Autor Wątek: Data-driven programming - źródła  (Przeczytany 6633 razy)

Offline lmmilewski

  • Użytkownik
    • Łukasz Milewski - devblog

# Grudzień 14, 2011, 15:16:28
Jaka lista komponentów? :-)

//EDIT: dla uściślenia - obiekt nie jest rodzicem kontenerem komponentów jak w OOP
« Ostatnia zmiana: Grudzień 14, 2011, 15:19:38 wysłana przez lmmilewski »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline skowronkow

  • Użytkownik
    • skowronkow devsite

# Grudzień 14, 2011, 16:00:12
Z takim komponentowym podejsciem próbowałem (faktycznie dużo latwiej zrobic wtedy zarządzanie obiektami poprzez sterowane danymi - http://skowronkow.ovh.org/Armedge%20documentation.pdf).

O ile idea wydaje mi się zachowana to nie do końca przekonuje mnie obrany sposób uniezaleznienia obiektow od siebie (wspolne wlasciwisci) jaki wybrałem. Faktycznie zaden komponent nie musi wiedziec nic o innym (działać będzie, nie będzie funkcjonalności). Wszystko opiera się na zdarzeniach. W językach dynamicznych jest to o wiele wygodniejsze (w js wrecz naturalne i czasem nie wiadomo nawet w którym momencie calkowicie stosuje się całe to data oriented podejscie, choć z optymalizacją nie ma to często wiele wspólnego).

Dla mnie data driven to możliwośc latwego zarządzania (oraz komponowania) obiektów za pomocą danych - czyli system komponentowy raczej go spełnia. Co do data oriented to nie jest tak, że to podejscie jest własnie naturalną konsekwencją data driven (pozniejsze zarządzanie danymi w sposób niezalezny od tego do kogo te dane należą i nie ważne czy z powodów optymalizacyjnych czy innych)? Jeśli nie to również nie rozumiem.

Offline Paweł

  • Użytkownik

# Grudzień 28, 2011, 21:37:03
No dobra zdarzenia. W przykładzie jest CollisionComponent, który aby stwierdzić czy zaszła kolizja musi znać położenie obiektu i np. jego wymary. Czyli można zrobić tak: CollisionComponent::update(){
  Rect boundingRect = {};
  for( Iterator it = daneDlaObiektow.begin(); it !=  daneDlaObiektow.end(); ++it ){
    sendMessage( GET_BOUNDING_RECT, it->first, &boundingRect  );
    //operacje na bounding rect
  }
}

Tylko jak to się ma do liniowego przetwarzania danych? Wydaje mi się że ta liniowość jest trochę zaburzona, bo niby iterujemy tylko po mapie w CollisionComponent a tak naprawdę to wysyłając komunikat bedzie trzeba odczytać dane z innych komponentów ( w najlepszym przypadku będzie to odczyt na przemian ) . Dodatkowo nie wiemy kto odpowie na komunikat, za każdym razem może to być inny komponent.
Jak w takim razie zorganizować wymianę danych między komponentami?
« Ostatnia zmiana: Grudzień 28, 2011, 21:42:22 wysłana przez Paweł »

Offline Liosan

  • Moderator

# Grudzień 28, 2011, 22:54:54
Ideally, components should not know about each other. However, in a practical world, there are always going to be dependencies between specific components (...) we allowed the components to store pointers to one another, and call member functions in other components directly.
Shared state is useful for the really basic stuff that you can take for granted that every object has— things like position and size.

Some domains are distinct but still closely related. Things like animation and rendering, user input and AI, physics and collision. If you have separate components for each half of those pairs, you may find it easiest to just let them know directly about their other half.

Messaging is useful for “less important” communication. Its fire-and-forget nature is a good fit for things like having an audio component play a sound when a physics component sends a message that the object has collided with something.

Twój przykładowy kod wydaje się mało ciekawym modelem pracy. Używasz niby-eventów, żeby synchronicznie dostać potrzebne Ci dane. W optymistycznym przypadku, to jest tylko poplątany sposób wywołania funkcji, który wiąże się z dziwacznym interfejsem, narzutem performance'owym ze względu na 'pytanie' komponentów które nie obsługują GET_BOUNDING_RECT oraz trudnością rozszerzania tego mechanizmu. W pesymistycznym przypadku, dostajesz kompletny chaos, kiedy nie wiesz od jakiego komponentu przyszła odpowiedź - bo przecież kilka może odpowiedzieć na ten event - ale który był ostatni? i który jest ten dobry? i w jakiej kolejności powinny być przetwarzane?

Decoupling decouplingiem, ale jak chcesz dostać bounding rect to byłoby fajnie móc wywołać getBoundingRect(), nie?

Liosan