Last active
November 3, 2016 03:25
-
-
Save wjwwood/ded26c4213f5046fef6b3e92e0af5d7c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <vector> | |
struct NodeBaseIface { | |
virtual std::string get_name() = 0; | |
}; | |
struct NodeBase : public NodeBaseIface { | |
explicit NodeBase(std::string name) : name_(name) {} | |
virtual std::string get_name() {return name_;} | |
private: | |
std::string name_; | |
}; | |
struct NodePubSubIface { | |
virtual void create_publisher(std::string topic) = 0; | |
virtual void create_subscription(std::string topic) = 0; | |
}; | |
struct NodePubSub : public NodePubSubIface { | |
explicit NodePubSub(NodeBase * node_base) : node_base_(node_base) {} | |
virtual void create_publisher(std::string topic) { | |
printf("in NodePubSub::create_publisher(%s) for node '%s'\n", topic.c_str(), node_base_->get_name().c_str()); | |
} | |
virtual void create_subscription(std::string topic) { | |
printf("in NodePubSub::create_subscription(%s) for node '%s'\n", topic.c_str(), node_base_->get_name().c_str()); | |
} | |
private: | |
NodeBase * node_base_; | |
}; | |
struct NodeServiceIface { | |
virtual void create_client(std::string service) = 0; | |
virtual void create_service(std::string service) = 0; | |
}; | |
struct NodeService : public NodeServiceIface { | |
explicit NodeService(NodeBase * node_base) : node_base_(node_base) {} | |
virtual void create_client(std::string service) { | |
printf("in NodeService::create_client(%s) for node '%s'\n", service.c_str(), node_base_->get_name().c_str()); | |
} | |
virtual void create_service(std::string service) { | |
printf("in NodeService::create_service(%s) for node '%s'\n", service.c_str(), node_base_->get_name().c_str()); | |
} | |
private: | |
NodeBase * node_base_; | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Graph part of the Node interface. | |
////////////////////////////////////////////////////////////////////////////////////// | |
struct NodeGraphIface { | |
virtual void wait_for_graph_change() = 0; | |
}; | |
struct NodeGraph : public NodeGraphIface { | |
explicit NodeGraph(NodeBase * node_base) : node_base_(node_base) {} | |
virtual void wait_for_graph_change() { | |
printf("in NodeGraph::wait_for_graph_change() for node '%s'\n", node_base_->get_name().c_str()); | |
} | |
private: | |
NodeBase * node_base_; | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Parameter part of the Node interface. | |
////////////////////////////////////////////////////////////////////////////////////// | |
struct NodeParamsIface { | |
virtual void get_parameter() = 0; | |
virtual void set_parameter() = 0; | |
}; | |
struct NodeParams : public NodeParamsIface { | |
explicit NodeParams( | |
NodeBaseIface * node_base, | |
NodePubSubIface * node_pub_sub, | |
NodeServiceIface * node_service) | |
: node_base_(node_base), node_pub_sub_(node_pub_sub), node_service_(node_service) | |
{ | |
printf("in NodeGraph::NodeGraph() for node '%s'\n", node_base_->get_name().c_str()); | |
printf(" "); | |
node_service_->create_service(node_base_->get_name() + "/set_parameter"); | |
printf(" "); | |
node_pub_sub_->create_publisher(node_base_->get_name() + "/parameter_events"); | |
} | |
virtual void get_parameter() { | |
printf("in NodeGraph::get_parameter() for node '%s'\n", node_base_->get_name().c_str()); | |
} | |
virtual void set_parameter() { | |
printf("in NodeGraph::set_parameter() for node '%s'\n", node_base_->get_name().c_str()); | |
} | |
private: | |
NodeBaseIface * node_base_; | |
NodePubSubIface * node_pub_sub_; | |
NodeServiceIface * node_service_; | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Action part of the Node interface. | |
////////////////////////////////////////////////////////////////////////////////////// | |
struct NodeActionIface { | |
virtual void create_action_server(std::string action) = 0; | |
virtual void create_action_client(std::string action) = 0; | |
}; | |
struct NodeActions : public NodeActionIface { | |
explicit NodeActions( | |
NodeBaseIface * node_base, | |
NodePubSubIface * node_pub_sub, | |
NodeServiceIface * node_service) | |
: node_base_(node_base), node_pub_sub_(node_pub_sub), node_service_(node_service) | |
{ | |
} | |
virtual void create_action_server(std::string action) { | |
printf("in NodeGraph::create_action_server(%s) for node '%s'\n", action.c_str(), node_base_->get_name().c_str()); | |
}; | |
virtual void create_action_client(std::string action) { | |
printf("in NodeGraph::create_action_client(%s) for node '%s'\n", action.c_str(), node_base_->get_name().c_str()); | |
}; | |
private: | |
NodeBaseIface * node_base_; | |
NodePubSubIface * node_pub_sub_; | |
NodeServiceIface * node_service_; | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Experimental "composite" or "subset" interface. | |
////////////////////////////////////////////////////////////////////////////////////// | |
// struct NodeCommsIface : public NodeBaseIface, public NodePubSubIface, public NodeServiceIface {}; | |
// struct NodeComms : public NodeCommsIface | |
struct NodeComms : public NodeBase, public NodePubSub, public NodeService | |
{ | |
explicit NodeComms(std::string name) : NodeBase(name), NodePubSub(this), NodeService(this) {} | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Basic Node class. | |
////////////////////////////////////////////////////////////////////////////////////// | |
struct Node | |
: | |
public NodeComms, | |
// public NodeBase, | |
// public NodePubSub, | |
// public NodeService, | |
public NodeGraph, | |
public NodeParams, | |
public NodeActions | |
{ | |
explicit Node(std::string name) | |
: | |
NodeComms(name), | |
// NodeBase(name), | |
// NodePubSub(this), | |
// NodeService(this), | |
NodeGraph(this), | |
NodeParams(this, this, this), | |
NodeActions(this, this, this) | |
{} | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Custom Node class which does not expose the normal PubSub interface. | |
////////////////////////////////////////////////////////////////////////////////////// | |
struct CustomNodeWithoutPubSub_NodePubSub_Wrapper | |
{ | |
explicit CustomNodeWithoutPubSub_NodePubSub_Wrapper(NodeBase * node_base) | |
: custom_helper_node_pub_sub_(new NodePubSub(node_base)) | |
{} | |
virtual ~CustomNodeWithoutPubSub_NodePubSub_Wrapper() {delete custom_helper_node_pub_sub_;} | |
protected: | |
CustomNodeWithoutPubSub_NodePubSub_Wrapper(const CustomNodeWithoutPubSub_NodePubSub_Wrapper &) = delete; | |
NodePubSub * custom_helper_node_pub_sub_; | |
}; | |
struct CustomNodeWithoutPubSub | |
: | |
public NodeBase, | |
public CustomNodeWithoutPubSub_NodePubSub_Wrapper, | |
// public NodePubSub, // explicitly left out to remove functions from API | |
public NodeService, | |
public NodeGraph, | |
public NodeParams, | |
public NodeActions | |
{ | |
explicit CustomNodeWithoutPubSub(std::string name) | |
: | |
NodeBase(name), | |
CustomNodeWithoutPubSub_NodePubSub_Wrapper(this), | |
NodeService(this), | |
NodeGraph(this), | |
NodeParams(this, custom_helper_node_pub_sub_, this), | |
NodeActions(this, custom_helper_node_pub_sub_, this) | |
{} | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Test functions that take different forms of the interface. | |
////////////////////////////////////////////////////////////////////////////////////// | |
void func_takes_pubsub(NodePubSubIface * i) { | |
printf("in func_takes_pubsub()\n"); | |
i->create_publisher("chatter"); | |
i->create_subscription("chatter"); | |
printf("\n"); | |
} | |
void func_takes_services(NodeServiceIface * i) { | |
printf("in func_takes_services()\n"); | |
i->create_service("add_two_ints"); | |
i->create_client("add_two_ints"); | |
printf("\n"); | |
} | |
void func_takes_comms(NodeComms * i) { | |
printf("in func_takes_comms(NodeCommsIface *)\n"); | |
i->create_publisher("chatter"); | |
i->create_subscription("chatter"); | |
i->create_service("add_two_ints"); | |
i->create_client("add_two_ints"); | |
printf("\n"); | |
} | |
void func_takes_comms(NodePubSubIface * pub_sub, NodeServiceIface * service) { | |
printf("in func_takes_comms(NodePubSubIface *, NodeServiceIface *)\n"); | |
pub_sub->create_publisher("chatter"); | |
pub_sub->create_subscription("chatter"); | |
service->create_service("add_two_ints"); | |
service->create_client("add_two_ints"); | |
printf("\n"); | |
} | |
void func_takes_params(NodeParamsIface * i) { | |
printf("in func_takes_params()\n"); | |
i->get_parameter(); | |
i->set_parameter(); | |
printf("\n"); | |
} | |
void func_takes_actions(NodeActionIface * i) { | |
printf("in func_takes_actions()\n"); | |
i->create_action_server("move_base/goal"); | |
i->create_action_client("move_base/goal"); | |
printf("\n"); | |
} | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Toy Executor that only needs part of the API. | |
////////////////////////////////////////////////////////////////////////////////////// | |
struct Executor | |
{ | |
void add_node(NodeBaseIface * node) {nodes_.push_back(node);} | |
private: | |
std::vector<NodeBaseIface *> nodes_; | |
}; | |
////////////////////////////////////////////////////////////////////////////////////// | |
// Demo main function. | |
////////////////////////////////////////////////////////////////////////////////////// | |
int main(int argc, char const *argv[]) | |
{ | |
Node * node = new Node("my_node"); | |
func_takes_pubsub(node); | |
func_takes_services(node); | |
func_takes_comms(node); | |
func_takes_comms(node, node); | |
func_takes_params(node); | |
func_takes_actions(node); | |
CustomNodeWithoutPubSub * custom_node = new CustomNodeWithoutPubSub("my_custom_node"); | |
// func_takes_pubsub(custom_node); // class has no pub sub in API | |
func_takes_services(custom_node); // class does have service API | |
// func_takes_comms(custom_node); // class does not inherit from NodeComms | |
// func_takes_comms(custom_node, custom_node); // class has no pub sub in API (first argument) | |
func_takes_params(custom_node); // still works for param API | |
func_takes_actions(custom_node); // also for actions | |
// Both can be added to the executor because it only needs the NodeBase API. | |
Executor exec; | |
exec.add_node(node); | |
exec.add_node(custom_node); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment