--- /dev/null
+#ifndef MSP_GAME_SYSTEMSCHEDULER_H_
+#define MSP_GAME_SYSTEMSCHEDULER_H_
+
+#include <vector>
+#include "reflection.h"
+
+namespace Msp::Game {
+
+class System;
+
+class scheduling_error: public std::logic_error
+{
+public:
+ scheduling_error(const std::string &w): logic_error(w) { }
+};
+
+class SystemScheduler
+{
+public:
+ struct Group
+ {
+ std::vector<System *> systems;
+ };
+
+private:
+ struct GraphNode
+ {
+ System *system = nullptr;
+ Reflection::ClassBase *type = nullptr;
+ std::vector<GraphNode *> predecessors;
+ unsigned scheduled_order = 0;
+ };
+
+ Reflection::Reflector &reflector;
+ std::vector<GraphNode> nodes;
+ std::vector<Group> groups;
+
+public:
+ SystemScheduler(Reflection::Reflector &);
+
+ void add_system(System &);
+ void remove_system(System &);
+ void schedule();
+private:
+ static int get_order(const GraphNode &, const GraphNode &);
+ static int get_explicit_order(const GraphNode &, const GraphNode &);
+ static int get_data_order(const GraphNode &, const GraphNode &);
+public:
+ const std::vector<Group> &get_groups() const { return groups; }
+};
+
+} // namespace Msp::Game
+
+#endif