diff --git a/application/editormode.cpp b/application/editormode.cpp index c4cedb68..08f5103c 100644 --- a/application/editormode.cpp +++ b/application/editormode.cpp @@ -344,9 +344,14 @@ editor_mode::editor_mode() { m_orthophoto.ground_source([](glm::dvec2 const &Min, glm::dvec2 const &Max, std::vector &Out) { gather_ground_triangles(Min, Max, true, 50.0f, Out); }); - infra_hooks(); + editor_track::observe(this); } +editor_mode::~editor_mode() +{ + editor_track::observe(nullptr); +} + editor_ui *editor_mode::ui() const { return static_cast(m_userinterface.get()); diff --git a/application/editormode.h b/application/editormode.h index 32a6adaa..d8529da0 100644 --- a/application/editormode.h +++ b/application/editormode.h @@ -34,12 +34,13 @@ http://mozilla.org/MPL/2.0/. class TAnimModel; class TTrack; -class editor_mode : public application_mode +class editor_mode : public application_mode, private editor_track::observer { public: // constructors editor_mode(); + ~editor_mode() override; // methods // initializes internal data structures of the mode. returns: true on success, false otherwise bool init() override; @@ -576,7 +577,6 @@ class editor_mode : public application_mode bool m_bindings_loaded{false}; std::vector m_infra_buffer; // states of the objects before the change in progress bool m_infra_suspended{false}; - void infra_hooks(); void infra_load(); void infra_store(); std::vector infra_scope() const; @@ -587,9 +587,11 @@ class editor_mode : public application_mode infra::object_state infra_state_of(infra::binding const &Binding) const; void infra_restore_state(infra::object_state const &State); void infra_buffer(infra::binding const &Binding, bool const Refresh); - void infra_capture(TTrack const &Track); - void infra_follow(std::vector const &Tracks); - void infra_split(TTrack &Original, TTrack &Created, segment_data const &First); + // editor_track::observer + void track_captured(TTrack const &Track) override; + void tracks_committed(std::vector const &Tracks) override; + void track_retired(TTrack &Track) override; + void track_split(TTrack &Original, TTrack &Created, segment_data const &First) override; void infra_move(infra::binding &Binding); void infra_attach(EditorSnapshot &Snapshot); void render_infra_window(); diff --git a/application/editormodeinfra.cpp b/application/editormodeinfra.cpp index e950c5d7..090bc3ef 100644 --- a/application/editormodeinfra.cpp +++ b/application/editormodeinfra.cpp @@ -461,14 +461,6 @@ double turn_of(infra::binding const &Binding, double const Yaw) } // namespace -void editor_mode::infra_hooks() -{ - editor_track::on_capture = [this](TTrack const &Track) { infra_capture(Track); }; - editor_track::on_commit = [this](std::vector const &Tracks) { infra_follow(Tracks); }; - editor_track::on_retire = [this](TTrack &) { infra_follow({}); }; - editor_track::on_split = [this](TTrack &Original, TTrack &Created, segment_data const &First) { infra_split(Original, Created, First); }; -} - // format of the lines, coordinates in the space of the file: // { } // the object is the model, the include (position from its parameters), the traction piece (its first point), the memory @@ -908,7 +900,7 @@ void editor_mode::infra_buffer(infra::binding const &Binding, bool const Refresh m_infra_buffer.push_back(infra_state_of(Binding)); } -void editor_mode::infra_capture(TTrack const &Track) +void editor_mode::track_captured(TTrack const &Track) { if (m_infra_suspended || false == m_infra.follow) return; @@ -948,7 +940,7 @@ void editor_mode::infra_capture(TTrack const &Track) } } -void editor_mode::infra_follow(std::vector const &Tracks) +void editor_mode::tracks_committed(std::vector const &Tracks) { if (m_infra_suspended || false == m_infra.follow) return; @@ -1027,7 +1019,12 @@ void editor_mode::infra_follow(std::vector const &Tracks) } } -void editor_mode::infra_split(TTrack &Original, TTrack &Created, segment_data const &First) +void editor_mode::track_retired(TTrack &) +{ + tracks_committed({}); +} + +void editor_mode::track_split(TTrack &Original, TTrack &Created, segment_data const &First) { if (m_infra_suspended || Created.m_paths.empty()) return; diff --git a/editor/editorTrack.cpp b/editor/editorTrack.cpp index 7d815d66..e20fe976 100644 --- a/editor/editorTrack.cpp +++ b/editor/editorTrack.cpp @@ -122,15 +122,12 @@ bool adjoining_direction(TTrack const *Neighbour, glm::dvec3 const &Joint, bool } -std::function editor_track::on_capture; -std::function const &)> editor_track::on_commit; -std::function editor_track::on_retire; -std::function editor_track::on_split; +editor_track::observer *editor_track::s_observer{nullptr}; editor_track::state editor_track::capture(TTrack const &Track) { - if (on_capture) - on_capture(Track); + if (s_observer != nullptr) + s_observer->track_captured(Track); state result; result.paths = Track.m_paths; result.velocity = Track.fVelocity; @@ -240,8 +237,8 @@ void editor_track::commit(std::vector const &Tracks) for (auto *track : affected) for (auto *vehicle : track->Dynamics) vehicle->Move(0.000001); - if (on_commit) - on_commit(Tracks); + if (s_observer != nullptr) + s_observer->tracks_committed(Tracks); } void editor_track::commit_parameters(TTrack &Track) @@ -2219,8 +2216,8 @@ TTrack *editor_track::split_path(TTrack &Track, double const T) second.rolls[0] = roll; auto *created{create_path(Track, second)}; Track.m_paths.front() = first; - if (on_split) - on_split(Track, *created, first); + if (s_observer != nullptr) + s_observer->track_split(Track, *created, first); commit({&Track, created}); return created; } @@ -2257,8 +2254,8 @@ void editor_track::retire(TTrack &Track) update_transition(*neighbour); rebuild_geometry(*neighbour); } - if (on_retire) - on_retire(Track); + if (s_observer != nullptr) + s_observer->track_retired(Track); } void editor_track::rebuild_geometry(TTrack &Track) diff --git a/editor/editorTrack.hpp b/editor/editorTrack.hpp index 4a80dc95..742e393d 100644 --- a/editor/editorTrack.hpp +++ b/editor/editorTrack.hpp @@ -232,14 +232,21 @@ class editor_track static void velocity(TTrack &Track, double const Velocity); static void damage(TTrack &Track, int const Damage); - // let the objects which belong to the paths follow their changes - static std::function on_capture; - static std::function const &)> on_commit; - static std::function on_retire; - // called before the commit; the first argument keeps the beginning of the path, given in the last one - static std::function on_split; + // told about the changes of the paths, to let the objects which belong to them follow + class observer + { + public: + virtual ~observer() = default; + virtual void track_captured(TTrack const &Track) = 0; + virtual void tracks_committed(std::vector const &Tracks) = 0; + virtual void track_retired(TTrack &Track) = 0; + // called before the commit; Original keeps the beginning of the path, given in First + virtual void track_split(TTrack &Original, TTrack &Created, segment_data const &First) = 0; + }; + static void observe(observer *Observer) { s_observer = Observer; } private: + static observer *s_observer; static void disconnect(TTrack &Track); static void join(TTrack &Track); static void connect(TTrack &Track, bool const Prevside, TTrack *Other, int const Endpointid);