X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FNode.hh;h=961a1b8bc38867a7a14fae0cf1bb14a6f5c030d9;hb=18ebf1e9edb34f1aa8a32173275421a5d54400f7;hp=cadc05763784eb252e89583d265b81e708b07a7d;hpb=9a782796586d1f6708e1baab64f2140c3c7972e8;p=senf.git diff --git a/Console/Node.hh b/Console/Node.hh index cadc057..961a1b8 100644 --- a/Console/Node.hh +++ b/Console/Node.hh @@ -33,6 +33,67 @@ \section console_tree The tree + We will start by giving a more complete example. This example contains most of the stuff needed + for using the console/config library. + + \code + // Define callback function. + void mycommand(std::ostream & os, senf::console::Arguments const & args) + { + // ... + os << "!! Important message ...\n"; + } + + class SomeClass + { + public: + // Declare a directory node (proxy) for use by this class. This must be public so we can add + // it to the node tree later. + senf::console::ScopedDirectory dir; + + SomeClass() : dir(this) + { + // 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"); + } + + void member(std::ostream & os, senf::console::Arguments const & args) + { + // ... + } + }; + + int main(int, char**) + { + // Provide global documentation + senf::console::root() + .doc("This is someServer server"); + + // 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 ( + .mkdir("myserver") + .doc("My server specific directory")); + + // Add a command to that directory + mydir.add("mycommand", &mycommand) + .doc("mycommand []\n\n" + "If is given, flurgle the , otherwise burgle it"); + + // Create a SomeClass instance and add it's directory. + SomeClass someClass; + mydir.add("someClass", someClass.dir); + + // Start the interactive console server + senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u)) + .name("someServer"); + } + \endcode + \subsection console_nodes Node types The console/config library tree consists of two basic node types: @@ -117,75 +178,12 @@ Most objects will register several commands. So it makes sense for these objects to manage their own directory. Since directories are however allocated on the heap, they cannot be directly - added to a class. To facilitate this usage, the senf::console::ObjectDirectory is used. This + added to a class. To facilitate this usage, the senf::console::ScopedDirectory is used. This class provides a senf::console::DirectoryNode facade. Internally, it automatically creates a senf::console::DirectoryNode to which all calls are forwarded. - The senf::console::ObjectDirectory member should be declared public. This allows the user of the + The senf::console::ScopedDirectory member should be declared public. This allows the user of the class to add the node to the tree. - - \section console_long_example Example - - The following is a more complete example. It uses most of the features you will be using from - the console library. - - \code - // Define callback function. - void mycommand(std::ostream & os, senf::console::Arguments const & args) - { - // ... - os << "!! Important message ...\n"; - } - - class SomeClass - { - public: - // Declare a directory node (proxy) for use by this class. This must be public so we can add - // it to the node tree later. - senf::console::ObjectDirectory dir; - - SomeClass() : dir(this) - { - // 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"); - } - - void member(std::ostream & os, senf::console::Arguments const & args) - { - // ... - } - }; - - int main(int, char**) - { - // Provide global documentation - senf::console::root() - .doc("This is someServer server"); - - // 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 ( - .mkdir("myserver") - .doc("My server specific directory")); - - // Add a command to that directory - mydir.add("mycommand", &mycommand) - .doc("mycommand []\n\n" - "If is given, flurgle the , otherwise burgle it"); - - // Create a SomeClass instance and add it's directory. - SomeClass someClass; - mydir.add("someClass", someClass.dir); - - // Start the interactive console server - senf::console::Server::start(senf::INet4SocketAddress(senf::INet4Address::None, 23232u)) - .name("someServer"); - } - \endcode */ #ifndef HH_Node_ @@ -326,8 +324,8 @@ namespace console { mkdir() or add(). Special add() members however allow externally allocated node objects. Nodes may be added to the tree only once, otherwise chaos will ensue. Since nodes are always - managed dynamically, there is a special ObjectDirectory proxy template which provides a - DirectoryNode facade. ObjectDirectory is used if a class wants to manage it's own directory + managed dynamically, there is a special ScopedDirectory proxy template which provides a + DirectoryNode facade. ScopedDirectory is used if a class wants to manage it's own directory as a data member. Every node is assigned a (new) name when it is added to a directory. If the directory @@ -359,7 +357,7 @@ namespace console { static ptr create(); ///< Create node object. /**< You should normally use either mkdir() or - ObjectDirectory instead of create() */ + ScopedDirectory instead of create() */ ///\} /////////////////////////////////////////////////////////////////////////// @@ -481,6 +479,13 @@ namespace console { {}; #endif + struct SyntaxErrorException : public senf::Exception + { + explicit SyntaxErrorException(std::string const & msg = ""); + + virtual char const * what() const throw(); + }; + /** \brief Config/console tree command node The CommandNode is the base-class for the tree leaf nodes. Concrete command node @@ -506,8 +511,8 @@ namespace console { /////////////////////////////////////////////////////////////////////////// - virtual void operator()(std::ostream & output, Arguments const & arguments) = 0; - ///< Called to execute the command + void operator()(std::ostream & output, Arguments const & arguments) const; + ///< Execute the command /**< \param[in] output stream where result messages may be written to \param[in] arguments command arguments. This is a @@ -519,6 +524,16 @@ namespace console { protected: CommandNode(); +#ifndef DOXYGEN + private: +#endif + virtual void v_execute(std::ostream & output, Arguments const & arguments) const = 0; + ///< Called to execute the command + /**< \param[in] output stream where result messages may be + written to + \param[in] arguments command arguments. This is a + range of ranges of ArgumentToken instances. */ + private: }; @@ -553,8 +568,6 @@ namespace console { ///\} /////////////////////////////////////////////////////////////////////////// - virtual void operator()(std::ostream & output, Arguments const & arguments); - ptr thisptr(); cptr thisptr() const; @@ -565,6 +578,8 @@ namespace console { private: virtual void v_help(std::ostream & output) const; + virtual void v_execute(std::ostream & output, Arguments const & arguments) const; + Function fn_; std::string doc_;