From 8b4ace6fb8889b1ed7ec8f2493c59d2e3e3bd606 Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 25 Apr 2018 22:20:12 +0100 Subject: [PATCH] Subsystems: stub code for smart add+remove Groups track their state, which will enable them to correctly transition added and removed children in the future. Only stubbed for now, to avoid breakage on the FG side. --- simgear/structure/subsystem_mgr.cxx | 30 ++++++++++++++++++++++++++++ simgear/structure/subsystem_mgr.hxx | 6 +++++- simgear/structure/subsystem_test.cxx | 9 +++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx index 52ca6fda..033bb244 100644 --- a/simgear/structure/subsystem_mgr.cxx +++ b/simgear/structure/subsystem_mgr.cxx @@ -157,6 +157,7 @@ SGSubsystemMgr* SGSubsystem::get_manager() const std::string SGSubsystem::nameForState(State s) { switch (s) { + case State::INVALID: return "invalid"; case State::INIT: return "init"; case State::REINIT: return "reinit"; case State::POSTINIT: return "post-init"; @@ -216,11 +217,13 @@ SGSubsystemGroup::~SGSubsystemGroup () void SGSubsystemGroup::init () { + assert(_state == State::BIND); forEach([this](SGSubsystem* s){ this->notifyWillChange(s, State::INIT); s->init(); this->notifyDidChange(s, State::INIT); }); + _state = State::INIT; } SGSubsystem::InitStatus @@ -233,11 +236,13 @@ SGSubsystemGroup::incrementalInit() // termination test if (_initPosition >= static_cast(_members.size())) { + _state = State::INIT; return INIT_DONE; } if (_initPosition < 0) { // first call + assert(_state == State::BIND); _initPosition = 0; notifyWillChange(_members.front()->subsystem, State::INIT); } @@ -279,11 +284,13 @@ void SGSubsystemGroup::reverseForEach(std::function f) void SGSubsystemGroup::postinit () { + assert(_state == State::INIT); forEach([this](SGSubsystem* s){ this->notifyWillChange(s, State::POSTINIT); s->postinit(); this->notifyDidChange(s, State::POSTINIT); }); + _state = State::POSTINIT; } void @@ -304,6 +311,7 @@ SGSubsystemGroup::shutdown () s->shutdown(); this->notifyDidChange(s, State::SHUTDOWN); }); + _state = State::SHUTDOWN; _initPosition = -1; } @@ -315,6 +323,7 @@ SGSubsystemGroup::bind () s->bind(); this->notifyDidChange(s, State::BIND); }); + _state = State::BIND; } void @@ -325,6 +334,7 @@ SGSubsystemGroup::unbind () s->unbind(); this->notifyDidChange(s, State::UNBIND); }); + _state = State::UNBIND; } void @@ -420,6 +430,16 @@ SGSubsystemGroup::set_subsystem (const string &name, SGSubsystem * subsystem, member->min_step_sec = min_step_sec; subsystem->set_group(this); notifyDidChange(subsystem, State::ADD); + + if (_state != State::INVALID) { + SG_LOG(SG_GENERAL, SG_DEV_WARN, "TODO: implement SGSubsystemGroup transition when adding after init"); + // transition to the correct state + // bind + + // init + + // post-init + } } void @@ -457,6 +477,16 @@ SGSubsystemGroup::remove_subsystem(const string &name) if (it != _members.end()) { // found it, great const auto sub = (*it)->subsystem; + + if (_state != State::INVALID) { + // transition out correctly + SG_LOG(SG_GENERAL, SG_DEV_WARN, "TODO: implement SGSubsystemGroup transition when removing before shutdown"); + + // shutdown + + // unbind + } + notifyWillChange(sub, State::REMOVE); delete *it; _members.erase(it); diff --git a/simgear/structure/subsystem_mgr.hxx b/simgear/structure/subsystem_mgr.hxx index 63257dc9..6ce18dfc 100644 --- a/simgear/structure/subsystem_mgr.hxx +++ b/simgear/structure/subsystem_mgr.hxx @@ -288,7 +288,8 @@ public: SGSubsystemGroup* get_group() const; enum class State { - ADD, + INVALID = -1, + ADD = 0, BIND, INIT, POSTINIT, @@ -401,6 +402,9 @@ private: using MemberVec = std::vector; MemberVec _members; + // track the state of this group, so we can transition added/removed + // members correctly + SGSubsystem::State _state = SGSubsystem::State::INVALID; double _fixedUpdateTime; double _updateTimeRemainder; diff --git a/simgear/structure/subsystem_test.cxx b/simgear/structure/subsystem_test.cxx index 90bcab5f..cd604272 100644 --- a/simgear/structure/subsystem_test.cxx +++ b/simgear/structure/subsystem_test.cxx @@ -30,7 +30,8 @@ public: void bind() override { auto node = get_manager()->root_node(); - node->setIntValue("mysub/foo", 42); + if (node) + node->setIntValue("mysub/foo", 42); } void update(double dt) override @@ -54,7 +55,8 @@ public: void bind() override { auto node = get_manager()->root_node(); - node->setIntValue("anothersub/bar", 172); + if (node) + node->setIntValue("anothersub/bar", 172); } void update(double dt) override @@ -246,6 +248,7 @@ void testSubGrouping() // lookup of the group should also work SG_CHECK_EQUAL(manager->get_subsystem(), instruments); + manager->bind(); manager->init(); SG_VERIFY(instruments->wasInited); @@ -304,6 +307,7 @@ void testIncrementalInit() instruments->set_subsystem(radio1); instruments->set_subsystem(radio2); + manager->bind(); for ( ; ; ) { auto status = manager->incrementalInit(); if (status == SGSubsystemMgr::INIT_DONE) @@ -347,6 +351,7 @@ void testSuspendResume() instruments->set_subsystem(radio1); instruments->set_subsystem(radio2); + manager->bind(); manager->init(); manager->update(1.0);