diff --git a/src/openlcb/DefaultNodeRegistry.hxx b/src/openlcb/DefaultNodeRegistry.hxx new file mode 100644 index 000000000..2b10b6b88 --- /dev/null +++ b/src/openlcb/DefaultNodeRegistry.hxx @@ -0,0 +1,78 @@ +/** \copyright + * Copyright (c) 2020, Balazs Racz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \file DefaultNodeRegistry.hxx + * + * Default implementations for data structures keyed by virtual nodes. + * + * @author Balazs Racz + * @date 12 Sep 2020 + */ + +#ifndef _OPENLCB_DEFAULTNODEREGISTRY_HXX_ +#define _OPENLCB_DEFAULTNODEREGISTRY_HXX_ + +#include + +#include "openlcb/NodeRegistry.hxx" + +namespace openlcb +{ + +class Node; + +class DefaultNodeRegistry : public NodeRegistry +{ +public: + /// Adds a node to the list of registered nodes. + /// @param node a virtual node. + void register_node(openlcb::Node *node) override + { + nodes_.insert(node); + } + + /// Removes a node from the list of registered nodes. + /// @param node a virtual node. + void unregister_node(openlcb::Node *node) override + { + nodes_.erase(node); + } + + /// Checks if a node is registered. + /// @param node a virtual node. + /// @return true if this node has been registered. + bool is_node_registered(openlcb::Node *node) override + { + return nodes_.find(node) != nodes_.end(); + } + +private: + std::set nodes_; +}; + +} // namespace openlcb + +#endif // _OPENLCB_DEFAULTNODEREGISTRY_HXX_ diff --git a/src/openlcb/NodeRegistry.hxx b/src/openlcb/NodeRegistry.hxx new file mode 100644 index 000000000..868bbf9ef --- /dev/null +++ b/src/openlcb/NodeRegistry.hxx @@ -0,0 +1,64 @@ +/** \copyright + * Copyright (c) 2020, Balazs Racz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \file NodeRegistry.hxx + * + * Abstract class for data structures keyed by virtual nodes. + * + * @author Balazs Racz + * @date 12 Sep 2020 + */ + +#ifndef _OPENLCB_NODEREGISTRY_HXX_ +#define _OPENLCB_NODEREGISTRY_HXX_ + +#include "utils/Destructable.hxx" + +namespace openlcb +{ + +class Node; + +class NodeRegistry : public Destructable +{ +public: + /// Adds a node to the list of registered nodes. + /// @param node a virtual node. + virtual void register_node(openlcb::Node *node) = 0; + + /// Removes a node from the list of registered nodes. + /// @param node a virtual node. + virtual void unregister_node(openlcb::Node *node) = 0; + + /// Checks if a node is registered. + /// @param node a virtual node. + /// @return true if this node has been registered. + virtual bool is_node_registered(openlcb::Node *node) = 0; +}; + +} // namespace openlcb + +#endif // _OPENLCB_NODEREGISTRY_HXX_ diff --git a/src/openlcb/TractionTrain.cxx b/src/openlcb/TractionTrain.cxx index 68c371bec..908b046de 100644 --- a/src/openlcb/TractionTrain.cxx +++ b/src/openlcb/TractionTrain.cxx @@ -174,8 +174,7 @@ struct TrainService::Impl return release_and_exit(); } // Checks if destination is a local traction-enabled node. - if (trainService_->nodes_.find(train_node()) == - trainService_->nodes_.end()) + if (!trainService_->nodes_->is_node_registered(train_node())) { LOG(VERBOSE, "Traction message for node %p that is not " "traction enabled.", @@ -629,9 +628,10 @@ struct TrainService::Impl TractionRequestFlow traction_; }; -TrainService::TrainService(If *iface) +TrainService::TrainService(If *iface, NodeRegistry *train_node_registry) : Service(iface->executor()) , iface_(iface) + , nodes_(train_node_registry) { impl_ = new Impl(this); } @@ -647,17 +647,16 @@ void TrainService::register_train(TrainNode *node) extern void StartInitializationFlow(Node * node); StartInitializationFlow(node); AtomicHolder h(this); - nodes_.insert(node); + nodes_->register_node(node); LOG(VERBOSE, "Registered node %p for traction.", node); - HASSERT(nodes_.find(node) != nodes_.end()); } void TrainService::unregister_train(TrainNode *node) { - HASSERT(nodes_.find(node) != nodes_.end()); + HASSERT(nodes_->is_node_registered(node)); iface_->delete_local_node(node); AtomicHolder h(this); - nodes_.erase(node); + nodes_->unregister_node(node); } } // namespace openlcb diff --git a/src/openlcb/TractionTrain.hxx b/src/openlcb/TractionTrain.hxx index c6729076b..8c1d08ac2 100644 --- a/src/openlcb/TractionTrain.hxx +++ b/src/openlcb/TractionTrain.hxx @@ -38,6 +38,7 @@ #include #include "executor/Service.hxx" +#include "openlcb/DefaultNodeRegistry.hxx" #include "openlcb/Node.hxx" #include "openlcb/TractionDefs.hxx" #include "openlcb/TrainInterface.hxx" @@ -322,7 +323,12 @@ private: class TrainService : public Service, private Atomic { public: - TrainService(If *iface); + /// Constructor. + /// @param iface the OpenLCB interface to which the train nodes are bound. + /// @param train_node_registry implementation of the + /// NodeRegistry. Ownership is transferred. + TrainService( + If *iface, NodeRegistry *train_node_registry = new DefaultNodeRegistry); ~TrainService(); If *iface() @@ -344,17 +350,17 @@ public: /// @return true if this is a known train node. bool is_known_train_node(Node *node) { - return nodes_.find((TrainNode*)node) != nodes_.end(); + return nodes_->is_node_registered(node); } private: struct Impl; /** Implementation flows. */ Impl *impl_; - + /** OpenLCB interface */ If *iface_; /** List of train nodes managed by this Service. */ - std::set nodes_; + std::unique_ptr nodes_; }; } // namespace openlcb