X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FUtils%2FConsole%2FNode.hh;h=5765dd644fab62c9fb6c5d7032ea5971738fb831;hb=463db052ea9d1c292bfd40301d0dc4963411485e;hp=3158023e5e90eb545ff6e7908a317c89e7bc04d0;hpb=3fe2ed38b800bcb57afff676698462e763724245;p=senf.git diff --git a/senf/Utils/Console/Node.hh b/senf/Utils/Console/Node.hh index 3158023..5765dd6 100644 --- a/senf/Utils/Console/Node.hh +++ b/senf/Utils/Console/Node.hh @@ -53,12 +53,13 @@ SomeClass() : dir(this) { + namespace fty = senf::console::factory; // You may document the directory here or later when adding it to the tree dir.doc("Manager for something"); // Add a member function (the pointer-to-member is automatically bound to this instance) - dir.add("member", &SomeClass::member) - .doc("Do the member operation"); + dir.add("member", fty::Command(this, &SomeClass::member) + .doc("Do the member operation")); } void member(std::ostream & os, senf::console::ParseCommandInfo const & command) @@ -69,6 +70,8 @@ int main(int, char**) { + namespace fty = senf::console::factory; + // Provide global documentation senf::console::root() .doc("This is someServer server"); @@ -76,13 +79,13 @@ // Add a new directory to the root and document it. All the mutators return the node object // itself so operations can be chained. senf::console::DirectoryNode & mydir ( senf::console::root() - .mkdir("myserver") - .doc("My server specific directory")); + .add("myserver", fty::Directory() + .doc("My server specific directory"))); // Add a command to that directory - mydir.add("mycommand", &mycommand) + mydir.add("mycommand", fty::Command(&mycommand) .doc("mycommand []\n\n" - "If is given, flurgle the , otherwise burgle it"); + "If is given, flurgle the , otherwise burgle it")); // Create a SomeClass instance and add it's directory. SomeClass someClass; @@ -204,14 +207,9 @@ #include #include #include -#include -#include #include #include -#include #include -#include -#include "Parse.hh" //#include "Node.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -223,6 +221,8 @@ namespace console { class DirectoryNode; class CommandNode; + namespace detail { struct NodeFactory {}; } + /** \brief Get console root node */ DirectoryNode & root(); @@ -230,7 +230,7 @@ namespace console { Recursively dumps the console directory structure starting at \a dir. By default, dumps the complete tree beginning at the root node. - + In contrast to the console 'lr' command, links are dumped by showing the \e absolute path to the target node. */ @@ -382,31 +382,6 @@ namespace console { class SimpleCommandNode; - /** \brief Internal: Node creation helper traits - - This class is used internally to find out the type of node to create for a specific argument - type. - */ - template - struct NodeCreateTraits - { - typedef BOOST_TYPEOF_TPL( senf_console_add_node( - * static_cast(0), - * static_cast(0), - * static_cast(0), - 0) ) base_type; - typedef typename senf::remove_cvref::type value_type; - - typedef typename value_type::node_type NodeType; - typedef typename value_type::return_type result_type; - - /// Internal - struct Creator { - static result_type create(DirectoryNode & node, std::string const & name, - Object & ob); - }; - }; - /** \brief Config/console tree directory node This node type provides the internal and root nodes of the tree. It allows to add arbitrary @@ -469,38 +444,17 @@ namespace console { '-n' is added to the name until the name is unique. If \a name is empty, it is set to 'unnamed'. */ - template - typename NodeCreateTraits::result_type add(std::string const & name, - Object const & ob); + template + NodeType & add(std::string const & name, NodeType & node, + typename boost::enable_if< boost::is_convertible >::type * = 0); + + template + typename Factory::result_type add(std::string const & name, Factory const & factory, + typename boost::enable_if< boost::is_convertible >::type * = 0); ///< Generic child node factory /**< This member is used to create a new child node of the current directory. The type of node created depends on - the type of argument passed. - - The node type is selected by the NodeCreateTraits - class. To allow adding a specific node type, you need - to provide an overload for - senf_console_add_node which must be visible at - when you register the new node. - \code - MyNodeType & senf_console_add_node( - DirectoryNode & dir, - std::string const & name, - MySpecialObject const & ob, - int) - { - return dir.add(name, MyNodeType::create(ob)); - } - \endcode - (Do not forget the last unnamed 'int' parameter which - is not used but serves to disambiguate the - overloads). */ - - template - typename NodeCreateTraits::result_type add(std::string const & name, - Object & ob); - ///< Generic child node factory - /**< \see add() */ + the type of argument passed. */ GenericNode::ptr remove(std::string const & name); ///< Remove node \a name from the tree @@ -553,11 +507,6 @@ namespace console { \throws std::bad_cast if the child \a name is not a command node. */ - DirectoryNode & mkdir(std::string const & name); - ///< Create sub-directory node - DirectoryNode & provideDirectory(std::string const & name); - ///< Return subdirectory, possibly creating it - ChildrenRange children() const; ///< Return iterator range over all children. /**< The returned range is sorted by child name. */ @@ -565,10 +514,6 @@ namespace console { ///< Return iterator range of completions for \a s /**< The returned range is sorted by child name. */ - void link(std::string const & name, GenericNode & target); - ///< Create a child node which is a link to target. \a s - /**< The new link node will be a child of the node for which this member function is called. */ - ///\} /////////////////////////////////////////////////////////////////////////// @@ -597,12 +542,6 @@ namespace console { struct UnknownNodeNameException : public senf::Exception { UnknownNodeNameException() : senf::Exception("Unknown node name") {}}; -#ifndef DOXYGEN - template - struct NodeCreateTraits< boost::shared_ptr > - {}; -#endif - /** \brief Config/console tree command node The CommandNode is the base-class for the tree leaf nodes. Concrete command node @@ -635,7 +574,7 @@ namespace console { \param[in] command command arguments. This is a range of ranges of Token instances. */ - void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command) + void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command) const; ///< Execute the command /**< \param[out] rv command return value @@ -733,23 +672,68 @@ namespace console { std::string shortdoc_; }; + DirectoryNode & provideDirectory(DirectoryNode & dir, std::string const & name); + #ifndef DOXYGEN - SimpleCommandNode & senf_console_add_node(DirectoryNode & node, std::string const & name, - SimpleCommandNode::Function fn, int); +namespace factory { - DirectoryNode & senf_console_add_node(DirectoryNode & node, std::string const & name, - DirectoryNode & dir, int); + class SimpleCommand + : public detail::NodeFactory + { + public: + typedef SimpleCommandNode node_type; + typedef SimpleCommandNode & result_type; -#endif + explicit SimpleCommand(SimpleCommandNode::Function fn); -}} + SimpleCommandNode & create(DirectoryNode & dir, std::string const & name) const; + + SimpleCommand const & doc(std::string const & doc) const; + SimpleCommand const & shortdoc(std::string const & doc) const; -#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() + private: + SimpleCommandNode::ptr node_; + }; + + class Directory + : public detail::NodeFactory + { + public: + typedef DirectoryNode node_type; + typedef DirectoryNode & result_type; -BOOST_TYPEOF_REGISTER_TYPE(senf::console::DirectoryNode) -BOOST_TYPEOF_REGISTER_TYPE(senf::console::SimpleCommandNode) + Directory(); + DirectoryNode & create(DirectoryNode & dir, std::string const & name) const; + + Directory const & doc(std::string const & doc) const; + Directory const & shortdoc(std::string const & doc) const; + + private: + DirectoryNode::ptr node_; + }; + + class Link + : public detail::NodeFactory + { + public: + typedef LinkNode node_type; + typedef LinkNode & result_type; + + explicit Link(GenericNode & target); + + LinkNode & create(DirectoryNode & dir, std::string const & name) const; + + private: + LinkNode::ptr node_; + }; + +} + +#endif + +}} ///////////////////////////////hh.e//////////////////////////////////////// #include "Node.cci"