From c8f1117a8dd75475e5beddc9e00c819de8ec8fdb Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 23 Mar 2025 13:16:12 +0200 Subject: [PATCH] Refactor dependency iteration in SystemScheduler to be more reusable --- source/game/systemscheduler.cpp | 74 ++++++++++++++++++--------------- source/game/systemscheduler.h | 2 + 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/source/game/systemscheduler.cpp b/source/game/systemscheduler.cpp index 1cc78a4..0a15a30 100644 --- a/source/game/systemscheduler.cpp +++ b/source/game/systemscheduler.cpp @@ -70,6 +70,46 @@ int SystemScheduler::get_data_order(const GraphNode &node1, const GraphNode &nod int data_order = 0; const Reflection::ClassBase *ordered_data = nullptr; const Reflection::ClassBase *unordered_data = nullptr; + for_common_deps(node1, node2, [&](const Reflection::ClassBase *type, int flags1, int flags2){ + bool unbuffered = (flags1|flags2)&System::UNBUFFERED; + flags1 &= ~System::UNBUFFERED; + flags2 &= ~System::UNBUFFERED; + + int order = 0; + // Read-only access to fresh data comes after any writes + if(flags1==System::READ_FRESH && (flags2&System::WRITE)) + order = 1; + else if(flags2==System::READ_FRESH && (flags1&System::WRITE)) + order = -1; + // Reads can happen concurrently to other access with buffering + else if(!(flags1&flags2&System::WRITE) && !unbuffered) + order = 0; + // Chained updates always come after non-chained writes + else if(flags1==System::CHAINED_UPDATE && (flags2==System::WRITE || flags2==System::UPDATE)) + order = 1; + else if(flags2==System::CHAINED_UPDATE && (flags1==System::WRITE || flags1==System::UPDATE)) + order = -1; + else + unordered_data = type; + + if(order && data_order && order!=data_order) + throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s and %s", + node1.type->get_name(), node2.type->get_name(), ordered_data->get_name(), type->get_name())); + + data_order = order; + ordered_data = type; + }); + + if(!data_order && unordered_data) + throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s", + node1.type->get_name(), node2.type->get_name(), unordered_data->get_name())); + + return data_order; +} + +template +void SystemScheduler::for_common_deps(const GraphNode &node1, const GraphNode &node2, const F &func) +{ for(const System::Dependency &d1: node1.system->get_dependencies()) { int flags1 = d1.get_flags()&System::DATA_MASK; @@ -90,41 +130,9 @@ int SystemScheduler::get_data_order(const GraphNode &node1, const GraphNode &nod else continue; - bool unbuffered = (flags1|flags2)&System::UNBUFFERED; - flags1 &= ~System::UNBUFFERED; - flags2 &= ~System::UNBUFFERED; - - int order = 0; - // Read-only access to fresh data comes after any writes - if(flags1==System::READ_FRESH && (flags2&System::WRITE)) - order = 1; - else if(flags2==System::READ_FRESH && (flags1&System::WRITE)) - order = -1; - // Reads can happen concurrently to other access with buffering - else if(!(flags1&flags2&System::WRITE) && !unbuffered) - order = 0; - // Chained updates always come after non-chained writes - else if(flags1==System::CHAINED_UPDATE && (flags2==System::WRITE || flags2==System::UPDATE)) - order = 1; - else if(flags2==System::CHAINED_UPDATE && (flags1==System::WRITE || flags1==System::UPDATE)) - order = -1; - else - unordered_data = common_type; - - if(order && data_order && order!=data_order) - throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s and %s", - node1.type->get_name(), node2.type->get_name(), ordered_data->get_name(), common_type->get_name())); - - data_order = order; - ordered_data = common_type; + func(common_type, flags1, flags2); } } - - if(!data_order && unordered_data) - throw scheduling_error(format("Ambiguous data ordering between %s and %s, accessing %s", - node1.type->get_name(), node2.type->get_name(), unordered_data->get_name())); - - return data_order; } void SystemScheduler::run(Time::TimeDelta dt) diff --git a/source/game/systemscheduler.h b/source/game/systemscheduler.h index 9101f81..f7c1ebd 100644 --- a/source/game/systemscheduler.h +++ b/source/game/systemscheduler.h @@ -44,6 +44,8 @@ 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 &); + template + static void for_common_deps(const GraphNode &, const GraphNode &, const F &); public: const std::vector &get_graph() const { return nodes; } -- 2.45.2