Event Manager

À̺¥Æ®¸Å´ÏÁ®ÀÇ °ø°³ ÇÔ¼ö´Â ´ÙÀ½°ú °°´Ù.

struct EventHandler;
class MyPropertySystem;

using EntryName = std::string;  //to remove event
using EventId = std::string;
using EventFunc = std::function<bool(MyPropertySystem)>;
using EventList = std::list<EventHandler>;
using EventMap = std::unordered_map<EventId, EventList>;
using EnteryMap = std::unordered_map<EntryName, EventId>;

class EventManager
{
private:
    EventMap m_eventMap;
    EnteryMap m_entryMap;
public:
    EventManager();
    bool AddEvent(EventId eventId, EventFunc eventFunc);
    bool AddEvent(EventId eventId, EventFunc eventFunc, EntryName entryName);
    bool RemoveEvent(EntryName entryName);
    void Update(EventId eventId, const MyPropertySystem& param);

AddEvent

À̺¥Æ®¸¦ µî·ÏÇÑ´Ù.
eventId Áߺ¹µÉ¼ö ÀÖÀ¸¸ç, entryNameÀº °íÀ¯ Å°ÀÌ´Ù.
entryNameÀÌ »ý·« µÇ¸é eventId¿Í µ¿ÀÏÇÑ °ªÀÌ ÀúÀåµÈ´Ù. À̶§, eventId´Â Áߺ¹ µÉ¼ö ¾ø´Ù.

RemoveEvent

entryNameÀ¸·Î À̺¥Æ®¸¦ Á¦°ÅÇÑ´Ù.

Update

À̺¥Æ® ¸®½ºÆ®¿¡ µî·ÏµÈ ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.

ÄÚµå ¼³¸í

EventMap m_eventMap
EventId¸¦ Å°·Î EventList¸¦ µ¥ÀÌÅÍ·Î ÀúÀåÇÑ´Ù.

EnteryMap m_entryMap
EntryNameÀ» Å°·Î EventId¸¦ µ¥ÀÌÅÍ·Î ÀúÀåÇÑ´Ù.
m_entryMapÀº RemoveEvent½Ã m_eventMap¿¡¼­ Á¦°ÅÇϱâ À§Çؼ­ ÇÊ¿äÇÏ´Ù.

MyPropertySystem

¼Ó¼º Ãß°¡
    MyPropertySystem prop;
    prop.GetValue<int>("Damage") = 100;
    prop.GetValue<float>("hp") = 1000;
    prop.GetValue<std::string>("class") = "worrior";
    prop.GetValue<bool>("alive") = true;

»ç¿ë °¡´ÉÇÑ Å¸ÀÔÀº int, float, std::string, boolÀÌ´Ù.

¼Ó¼º »ç¿ë
PropertyList list = prop.GetList();
for (auto p : list)
{
    std::cout << " : " <<  p->GetName() << " : " << p->GetTypeName() << " : " << ToString(p) << std::endl;
}
return 0;


EventManager¿Í MyPropertySystemÀ» °°ÀÌ »ç¿ëÇÑ ÄÚµå

struct Car
{
    std::string name;
    int ShowPrice(MyPropertySystem propertySystem)
    {
        PropertyList list = propertySystem.GetList();
        for (auto p : list)
        {
            std::cout << name << " : " <<  p->GetName() << " : " << p->GetTypeName() << " : " << ToString(p) << std::endl;
        }
        return 0;
    }

    int ShowLowPrice(MyPropertySystem propertySystem)
    {
        PropertyList list = propertySystem.GetList();
        for (auto p : list)
        {
            std::cout << name << " : "  << p->GetName() << " : " << p->GetTypeName() << " : " << ToString(p) << std::endl;
        }
        return 0;
    }
}

void DoTest()
{
    std::cout << "============ Test AddEvent: add NormalPrice, LowPrice ============" << std::endl;
    EventManager manager;
    Car car1;
    car1.name = "an electric car";
    Car car2;
    car2.name= "a gasoline car";

    manager.AddEvent("Update_Price", std::bind(&Car::ShowPrice, &car1, _1), "NormalPrice");
    manager.AddEvent("Update_Price", std::bind(&Car::ShowLowPrice, &car2, _1), "LowPrice");
    MyPropertySystem param;
    param.GetValue<int>("price") = 1000;
    param.GetValue<bool>("isAll") = true;
    manager.Update("Update_Price", param);

    std::cout << "============ Test RemoveEvent : remove NormalPrice ============" << std::endl;
    manager.RemoveEvent("NormalPrice");

    MyPropertySystem param1;
    param1.GetValue<int>("price") = 100;
    param1.GetValue<float>("percent") = 50.5f;

    manager.Update("Update_Price", param1);
}

°á°ú)
============ Test AddEvent: add NormalPrice, LowPrice ============
an electric car : price : int : 1000
an electric car : isAll : bool : 1
a gasoline car : price : int : 1000
a gasoline car : isAll : bool : 1
============ Test RemoveEvent : remove NormalPrice ============
a gasoline car : price : int : 100
a gasoline car : percent : float : 50.500000

¼Ò½º ÆÄÀÏ ´Ù¿î·Îµå
EventManager.h
EventManager.cpp
EventTest.cpp

property/PropertyType.h
property/MyProperty.h
property/MyPropertySystem.h
property/MyPropertySystem.cpp

ÇÁ·ÎÁ§Æ® ´Ù¿î·Î
EventTest.zip

Âü°í)
¼Ó¼º ÄÚµå ¼öÁ¤
http://dolphin.ivyro.net/file/cplusplus/entity01.html

Ư¼öÈ­ ÅÛÇø´ Á¤Àû ¸â¹ö ÃʱâÈ­
https://stackoverflow.com/questions/42743048/c-template-the-static-member-in-a-global-object-is-not-initialized

template <class T>
class PropertyType
{
public :
    // Returns type ID associated with the templatized type.
    static  ePropertyType GetTypeID()
    {
        return ms_typeID;
    }
    static  const char* GetTypeName()
    {
         return ms_typeName;
    }

private:
    static  ePropertyType ms_typeID;
    static  const char* ms_typeName;
};

template<> ePropertyType PropertyType<bool>::ms_typeID = ept_bool;
ºôµå´Â µÇÁö¸¸ ´ÙÀ½ÀÇ ¿À·ù°¡ ¶á´Ù.

E1449    ¸â¹ö "PropertyType<T>::ms_typeID [´ë»ó T=bool]"ÀÇ ¸í½ÃÀû Ư¼öÈ­´Â óÀ½ »ç¿ëÇϱâ Àü¿¡ ³ªÅ¸³ª¾ß ÇÕ´Ï´Ù().

´ÙÀ½°ú °°ÀÌ Á¤Àû ¸â¹ö ÃʱâÈ­ ´ë½Å Á¤Àû¸â¹ö¸¦ »ç¿ëÇÏ´Â ÇÔ¼ö¸¦ ÃʱâÈ­ ÇØÁÖ¸é µÈ´Ù.

template<> ePropertyType PropertyType<bool>::GetTypeID() { return ept_bool; }
template<> const char* PropertyType<bool>::GetTypeName() { return static_cast<const char*>("bool"); }

template<> ePropertyType PropertyType<int>::GetTypeID() { return ept_int; }
template<> const char* PropertyType<int>::GetTypeName() { return static_cast<const char*>("int"); }

template<> ePropertyType PropertyType<float>::GetTypeID() { return ept_float; }
template<> const char* PropertyType<float>::GetTypeName() { return static_cast<const char*>("float"); }

template<> ePropertyType PropertyType<std::string>::GetTypeID() { return ept_string; }
template<> const char* PropertyType<std::string>::GetTypeName() { return static_cast<const char*>("string"); }