Prikaz jedne poruke
Stara 11.7.2014, 1:44   #3
Geomaster
V.I.P. Programiranje
 
Član od: 28.6.2007.
Lokacija: Beograd
Poruke: 2.342
Zahvalnice: 2.836
Zahvaljeno 1.047 puta na 507 poruka
Slanje poruke preko MSN-a korisniku Geomaster Slanje poruke preko Skypea korisniku Geomaster
Određen forumom Re: [C++] Unity sistem komponenti

Ovde je dat interesantan (doduše kratak) pregled kako se sistem baziran na komponentama može integrisati u data-oriented dizajn endžina (za više o data-oriented dizajnu, evo ga jedan moj tekst koji bi (kao) trebalo da bude dobar uvod). Evo i nešto malo duže na sličnu temu. Nisam siguran koliko je relevantno, samo dodajem ono što sam ja čitao o tome

Što se kôda tiče, @Belphegor, sintaksa mi deluje baš fino, posebno sa AddComponent<T> i bratijom. I sviđa mi se korišćenje C++11, baš kôd postaje primetno lepši i lakše se rade neke stvari. Ne znam jesi li razmišljao da implementiraš neki event dispatch sistem između ovih različitih komponenti, ali bilo bi zanimljivo da mogu da šalju poruke međusobno. Npr. entitet koji predstavlja NPC može da ima AI komponentu koja može da odgovara na eventove tipa "collision" iz physics komponente. U svakom slučaju, ako hoćeš, možeš da pogledaš neko rešenje za delegate (kao u C#-u), mogu da budu brži od virtuelnih funkcija, boilerplate je mnogo manji i kôd na kraju ispadne lepši (bar meni). Ovde sam nešto piskarao o tome (ignorisati nesmešne opaske i klinačke komentare), evo ga i kôd za te Delegate klase. Nije gotov, i verujem da s nekom metaprogramming mađijom može da se sredi da sintaksa bude još lepša, ali kapiram da je fina referenca.

delegate.h
Kod:
template<typename R, typename... Args>
class Delegate<R(Args...)> {
public:
  Delegate() : mObject(nullptr), mStub(nullptr)
  {

  }
  Delegate(const Delegate& Other) = default;

  Delegate& operator=(const Delegate& Other) = default;

  R operator()(Args... Arguments)
  {
    return (*mStub)(mObject, Arguments...);
  }

  template<class T, R (T::*Method)(Args...)>
  static Delegate fromMethod(T* Object)
  {
    Delegate d;
    d.mObject = Object;
    d.mStub = &methodStub<T, Method>;

    return d;
  }

protected:
  typedef R (*Stub)(void* Object, Args...);

  void* mObject;
  Stub mStub;

  template<class T, R (T::*Method)(Args...)>
  static R methodStub(void* Object, Args... Arguments)
  {
    return (static_cast<T*>(Object)->*Method)(Arguments...);
  }
};
eventsource.h
Kod:
template<typename T> std::vector<T> Vector;
template<typename K, typename V, blablabla> std::map<K, V, blablabla> Map;

template<typename... Args>
class EventSource {
public:
  typedef uint Handle;

  Handle addHandler(const Delegate<void(Args...)>& Handler)
  {
    Handle nh = mNextHandle++;
    mHandlers.push_back(Handler);
    mHandleMap[nh] = mHandlers.size() - 1;

    return nh;
  }

  void removeHandler(Handle H)
  {
    typename HandleMap::iterator it = mHandleMap.find(H);
    if (it == mHandleMap.end())
      throw exceptions::NoSuchEventHandler(H);

    typename HandlerList::size_type i = it->second, last = mHandlers.size() - 1;
    std::swap(mHandlers.at(i), mHandlers.back());
    mHandlers.pop_back();

    for (auto& p : mHandleMap)
      if (p.second == last) {
        p.second = i;
        break;
      }
  }

  void clearHandlers()
  {
    mHandlers.clear();
  }

  void fire(Args... Arguments)
  {
    for (auto& d : mHandlers)
      d(Arguments...);
  }

protected:
  typedef Vector<Delegate<void (Args...)>> HandlerList;
  typedef Map<Handle, typename HandlerList::size_type> HandleMap;

  HandlerList mHandlers;
  HandleMap mHandleMap;
  Handle mNextHandle;
};
Dakle fora je da jednostavno emiteri ponude EventSource klasu i ti njoj samo zakačiš svoj delegat kad hoćeš da se subscribe-uješ na evente (i posle ga otkačiš kad ti ne treba više, razume se). Onda emiteri pozivaju fire(...) i svi registrovani delegati bivaju pozvani. Zato što nema nikakav setup overhead u kôdu, možeš da nudiš EventSource za svaki tip eventa, ili da napraviš neku klasu koja sadrži grupu takvih emitera, pa da nju ponudiš iz komponente... Ne znam kako bi se to uklopilo u tvoj komponentski sistem, ali eto, neka ga tu, nek bleji. Izvinjavam se za off, ovo su samo neke ideje koje sam ja nekad imao i koje bih voleo da zažive u nekom obliku, pa ih poturam ljudima
Geomaster je offline   Odgovor sa citatom ove poruke
Sledeći korisnik se zahvaljuje korisniku Geomaster na korisnoj poruci:
Belphegor (11.7.2014)