Skip to content

Upgrador

Kigs-framework edited this page Feb 26, 2023 · 5 revisions

Table of contents

Introduction

The Upgrador class purpose is to be able to add a specific behaviour to several classes without implementing it in the base class. An example of Upgrador is done in UIPopUp (UIPopUp.h , UIPopUp.cpp ) so you can add a "PopUp" behaviour to all type of object inheriting UIItem.

Creating a new Upgrador

Declare the Upgrador

The new Upgrador class must inherit Uprador<baseClass>, where baseClass is the base class that will be upgraded. The pure virtual Upgrador methods Init and Destroy must be overloaded. The helper macro START_UPGRADOR(yourUpgradorClass) must be used as well as UPGRADOR_METHODS(method1,method2,method3...) to declare CoreModifiable methods that will be available on this Upgrador. Upgrador itself is not a CoreModifiable, so it can only have classic member variables or methods.

class PopUpUpgrador : public Upgrador<UIItem>
{
public:
   // create and init Upgrador if needed and add dynamic attributes
   virtual void	Init(CoreModifiable* toUpgrade) override;

   // destroy UpgradorData and remove dynamic attributes 
   virtual void	Destroy(CoreModifiable* toDowngrade) override;

   START_UPGRADOR(PopUpUpgrador);
   UPGRADOR_METHODS(HidePopUp, ShowPopUp);

protected:	

   // internal show/hide mechanism
   void Show(UIItem* localthis,CoreModifiable* aActivator);
   void Hide(UIItem* localthis);

   // upgrador member variable
   double myTimeOpen = 0;
   bool myOpenPopup = false;
   CoreModifiable* myActivator = nullptr;
};

Define the Upgrador

Then in the class definition (.cpp), the Init / Destroy body have to written. Init will connect to signals or annotation, and add dynamic attributes if needed, and Destroy will do the opposite ( disconnect, remove dynamic attributes ).

// connect pop up to events and create attributes
void	PopUpUpgrador::Init(CoreModifiable* toUpgrade)
{
   KigsCore::GetNotificationCenter()->addObserver(toUpgrade, "HidePopUp", "HidePopUp");
   KigsCore::GetNotificationCenter()->addObserver(toUpgrade, "ShowPopUp", "ShowPopUp");

   toUpgrade->AddDynamicAttribute(CoreModifiable::ATTRIBUTE_TYPE::INT, "NumSignal", 0);
   toUpgrade->AddDynamicAttribute(CoreModifiable::ATTRIBUTE_TYPE::BOOL, "CloseAll", true);
   toUpgrade->AddDynamicAttribute(CoreModifiable::ATTRIBUTE_TYPE::INT, "StayOpen", 0);
   toUpgrade->AddDynamicVectorAttribute("ActiveColor",(float*) &Point3D( 0.2f, 1.0f, 0.2f ),3);
   toUpgrade->AddDynamicVectorAttribute("UsedColor", (float*)&Point3D(0.4f, 0.4f, 0.4f), 3);
}

//  remove dynamic attributes and disconnect events
void	PopUpUpgrador::Destroy(CoreModifiable* toDowngrade)
{
   Hide((UIItem*)toDowngrade);

   KigsCore::GetNotificationCenter()->removeObserver(toDowngrade, "HidePopUp");
   KigsCore::GetNotificationCenter()->removeObserver(toDowngrade, "ShowPopUp");

   toDowngrade->RemoveDynamicAttribute("NumSignal");
   toDowngrade->RemoveDynamicAttribute("CloseAll");
   toDowngrade->RemoveDynamicAttribute("StayOpen");
   toDowngrade->RemoveDynamicAttribute("ActiveColor");
   toDowngrade->RemoveDynamicAttribute("UsedColor");
}

The CoreModifiable methods declared with UPGRADOR_METHODS macro have to be defined with macro DEFINE_UPGRADOR_METHOD :

// ShowPopUp slot
// the prototype is the same as CoreModifiable methods : 
// bool methodName(CoreModifiable* sender,std::vector<CoreModifiableAttribute*>& params,void* privateParams)
DEFINE_UPGRADOR_METHOD(PopUpUpgrador, ShowPopUp)
{
   if (!params.empty())
   {
	// here is the ShowPopUp behaviour code
        // ...
   }
   return false;
}

Then a mandatory Upgrador Update method must be defined using DEFINE_UPGRADOR_UPDATE helper macro

// prototype is : void UpgradorUpdate(const Timer& timer, void* addParam)
DEFINE_UPGRADOR_UPDATE(PopUpUpgrador)
{
   double t = timer.GetTime();
   // update code
   // ...
}

Inside Upgrador Update or DEFINE_UPGRADOR_METHOD code, this point to the upgraded class. To access current Upgrador, use GetUpgrador() method :

// access current Upgrador members with GetUpgrador()
// getValue is called on this ( the upgraded UIItem )
if (t - GetUpgrador()->myTimeOpen >= getValue<int>("StayOpen"))
{
   GetUpgrador()->Hide(this);
   GetUpgrador()->myTimeOpen = -1.0;
}

Register Upgrador

The Upgrador is then registered, preferably in the Init method of the concerned module, with REGISTER_UPGRADOR helper macro :

REGISTER_UPGRADOR(PopUpUpgrador);

#Upgrade or Downgrade an Instance

Once it is done, the process is simple :

// create a UIButton Instance
SP<UIButton>	b = KigsCore::GetInstanceOf("button", "UIButton");
// says that it know behave as a PopUp ( hide / show when event HidePopUp / ShowPopUp is sent with the good signal number )
b->Upgrade("PopUpUpgrador");
// set activation number for this popup : 
b->setValue("NumSignal",1);

If the upgrade is no more needed, downgrade the instance using Downgrade method :

// b is no more a popup
b->Downgrade("PopUpUpgrador");

Alias

For the sake of simplicity, it's possible to define aliases using DECLARE_CLASS_ALIAS_AND_UPGRADE macro, so that the instance factory upgrade automatically the instance you ask :

// when instance factory is asked for a UIPopUp instance, return UIItem upgrade with PopUpUpgrador
// you can add several Upgradors as macro parameters 
DECLARE_CLASS_ALIAS_AND_UPGRADE(core, UIPopUp, UIItem, PopUpUpgrador);

The alias only work for instance factory, in the previous example, the type of the UIPopUp instance remains UIItem.

It's also possible to create a simple alias with no Upgrador with DECLARE_CLASS_ALIAS macro :

DECLARE_CLASS_ALIAS(core, UIPanel, UIDrawableItem);

Serialization

An upgraded instance is exported with Upgrd XML item(s) :

<Upgrd N="PopUpUpgrador"/>

When imported, the Upgrador are initialized first, so concerned attributes are always initialized after them.

  1. Getting Started

  2. Overall features

  3. Advances features

    3.1. CoreModifiable

    3.1.1. Upgrador

    3.2. Attributes

    3.3. Methods

    3.4. CoreItem

    3.5. Signal/Slot/Notification

    3.6. Lua Binding

    3.7. Data Driven Application

  4. Other Modules

    4.1. FileManager

    4.2. Timer

    4.3. 2DLayers

    4.4. Collision

    4.5. GUI

    4.6. Input

    4.7. SceneGraph

    4.8. Renderer

Clone this wiki locally