--- /dev/null
+#include "transformpropagator.h"
+#include "events.h"
+#include "root.h"
+#include "stage.h"
+#include "transform.h"
+
+using namespace std;
+
+namespace Msp::Game {
+
+TransformPropagator::TransformPropagator(Stage &s):
+ System(s),
+ observer(s.get_event_bus())
+{
+ observer.observe<Events::EntityCreated>([this](const Events::EntityCreated &){ transforms_dirty = true; });
+ observer.observe<Events::EntityDestroyed>([this](const Events::EntityDestroyed &){ transforms_dirty = true; });
+}
+
+void TransformPropagator::tick(Time::TimeDelta)
+{
+ if(transforms_dirty)
+ rebuild_transform_order();
+
+ for(const ParentedTransform &t: transforms)
+ t.transform->update_world_matrix(t.parent.get());
+}
+
+void TransformPropagator::rebuild_transform_order()
+{
+ transforms.clear();
+ for(Handle<Entity> c: stage.get_root()->get_children())
+ rebuild_transform_order(c, nullptr);
+}
+
+void TransformPropagator::rebuild_transform_order(Handle<Entity> entity, Handle<Transform> parent_trans)
+{
+ if(Handle<Transform> trans = entity->get_transform())
+ {
+ transforms.emplace_back(trans, parent_trans);
+ parent_trans = trans;
+ }
+
+ for(Handle<Entity> c: entity->get_children())
+ rebuild_transform_order(c, parent_trans);
+}
+
+} // namespace Msp::Game