X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FUtils%2FConsole%2FNode.hh;h=f26ad9670ec39e3fb09936252c2a4c93edf3c272;hb=0003d55730b447329342161d12cf2ed23b63459e;hp=66ba18fb9193fc206c7d91acde2fa4c4977961f4;hpb=975639608e44e49058ccd52f05ffe6b21faeafef;p=senf.git diff --git a/senf/Utils/Console/Node.hh b/senf/Utils/Console/Node.hh index 66ba18f..f26ad96 100644 --- a/senf/Utils/Console/Node.hh +++ b/senf/Utils/Console/Node.hh @@ -2,23 +2,28 @@ // // Copyright (C) 2008 // Fraunhofer Institute for Open Communication Systems (FOKUS) -// Competence Center NETwork research (NET), St. Augustin, GERMANY -// Stefan Bund // -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. +// The contents of this file are subject to the Fraunhofer FOKUS Public License +// Version 1.0 (the "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// http://senf.berlios.de/license.html // -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. +// The Fraunhofer FOKUS Public License Version 1.0 is based on, +// but modifies the Mozilla Public License Version 1.1. +// See the full license text for the amendments. // -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., -// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// Software distributed under the License is distributed on an "AS IS" basis, +// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +// for the specific language governing rights and limitations under the License. +// +// The Original Code is Fraunhofer FOKUS code. +// +// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. +// (registered association), Hansastraße 27 c, 80686 Munich, Germany. +// All Rights Reserved. +// +// Contributor(s): +// Stefan Bund /** \file \brief Node public header */ @@ -58,7 +63,7 @@ dir.doc("Manager for something"); // Add a member function (the pointer-to-member is automatically bound to this instance) - dir.add("member", fty::Command(this, &SomeClass::member) + dir.add("member", fty::Command(&SomeClass::member, this) .doc("Do the member operation")); } @@ -132,7 +137,7 @@ \code void callback(std::ostream & os, senf::console::ParseCommandInfo const & command) { ... } // ... - myDirectory.add("foo",&callback); + myDirectory.add("foo",fty::Command(&callback)); \endcode Every node is identified among it's siblings by it's name. The name of the node is set when @@ -158,10 +163,10 @@ Depending on the node type added, additional node parameters may be set. For example, every node has a documentation parameter which is used by the online-help system. To assign these parameters, the node exposes corresponding member functions. Since - senf::console::DirectoryNode::add() returns the newly added node by reference, additional - parameters may just be added to the end of the add command: + senf::console::DirectoryNode::add() returns the newly added node by reference. Additional + parameters may be added after the factory call: \code - myDirectory.add("foo",&fooCallback).doc("The foo method"); + myDirectory.add("foo", fty::Command(&fooCallback).doc("The foo method") ); \endcode Since the parameter setters all return the node reference, additional parameters may just be added to the end of the command. @@ -212,7 +217,7 @@ #include //#include "Node.mpp" -///////////////////////////////hh.p//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// namespace senf { namespace console { @@ -230,7 +235,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. */ @@ -258,14 +263,14 @@ namespace console { { SENF_LOG_CLASS_AREA(); public: - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// // Types typedef boost::shared_ptr ptr; typedef boost::shared_ptr cptr; typedef boost::weak_ptr weak_ptr; - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// virtual ~GenericNode(); @@ -349,23 +354,23 @@ namespace console { : public GenericNode { public: - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// // Types typedef boost::shared_ptr ptr; typedef boost::shared_ptr cptr; typedef boost::weak_ptr weak_ptr; - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// ///\name Structors and default members - ///@{ + //\{ static ptr create(GenericNode & node); ///< Create new link node. /**< You should normally use DirectoryNode::link() to create a link node. */ - ///@} - /////////////////////////////////////////////////////////////////////////// + //\} + //-//////////////////////////////////////////////////////////////////////// GenericNode & follow() const; ///< Access the referenced node @@ -387,8 +392,8 @@ namespace console { This node type provides the internal and root nodes of the tree. It allows to add arbitrary children and supports directory traversal. - Nodes are normally not instantiated manually but are created by the DirectoryNode via - mkdir() or add(). Special add() members however allow externally allocated node objects. + Nodes are normally not instantiated manually but are created using factory calls. 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 ScopedDirectory proxy template which provides a @@ -408,7 +413,7 @@ namespace console { SENF_LOG_CLASS_AREA(); typedef std::map ChildMap; public: - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// // Types typedef boost::shared_ptr ptr; @@ -421,19 +426,19 @@ namespace console { typedef DirectoryNode node_type; typedef DirectoryNode & return_type; - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// ///\name Structors and default members - ///\{ + //\{ static ptr create(); ///< Create node object. /**< You should normally use either mkdir() or ScopedDirectory instead of create() */ ~DirectoryNode(); - ///\} - /////////////////////////////////////////////////////////////////////////// + //\} + //-//////////////////////////////////////////////////////////////////////// ///\name Children - ///\{ + //\{ template NodeType & add(std::string const & name, boost::shared_ptr node); @@ -514,8 +519,8 @@ namespace console { ///< Return iterator range of completions for \a s /**< The returned range is sorted by child name. */ - ///\} - /////////////////////////////////////////////////////////////////////////// + //\} + //-//////////////////////////////////////////////////////////////////////// DirectoryNode & doc(std::string const & doc); ///< Set node documentation DirectoryNode & shortdoc(std::string const & doc); ///< Set node short documentation @@ -558,14 +563,14 @@ namespace console { { SENF_LOG_CLASS_AREA(); public: - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// // Types typedef boost::shared_ptr ptr; typedef boost::shared_ptr cptr; typedef boost::weak_ptr weak_ptr; - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// void execute(std::ostream & output, ParseCommandInfo const & command) const; ///< Execute the command @@ -574,7 +579,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 @@ -630,7 +635,7 @@ namespace console { { SENF_LOG_CLASS_AREA(); public: - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// // Types typedef boost::shared_ptr ptr; @@ -642,14 +647,14 @@ namespace console { typedef SimpleCommandNode node_type; typedef SimpleCommandNode & return_type; - /////////////////////////////////////////////////////////////////////////// + //-//////////////////////////////////////////////////////////////////////// ///\name Structors and default members - ///\{ + //\{ static ptr create(Function const & fn); - ///\} - /////////////////////////////////////////////////////////////////////////// + //\} + //-//////////////////////////////////////////////////////////////////////// ptr thisptr(); cptr thisptr() const; @@ -674,10 +679,49 @@ namespace console { DirectoryNode & provideDirectory(DirectoryNode & dir, std::string const & name); -#ifndef DOXYGEN +/** \brief Console node factories + + The senf::console::factory namespace (customarily aliased to \c fty in user code) contains + factories used to create new node types: + \code + namespace fty = senf::console::factory; + + senf::console::DirectoryNode & dir (node.add("dirname", fty::Directory())); + + dir.add("name", fty::Command(&fn) + .arg("flag") + .doc("documentation")); + \endcode + + The node is added by passing the factory instance to senf::console::DirectoryNode::add(). + + To further customize the node, you may call attributor members on the temporary factory class + instance. Since the attributor members always return a self-reference to the factory class + instance, attributor calls may be chained arbitrarily. + + \see + \ref console_commands for details on the command nodes \n + \ref node_tree for details on the structural nodes (directory, link) + \note All factories are documented here as classes when in fact some are functions returning + internal classes. + + \implementation It is not true, that all attributor members return a self reference. Some + attributor members will return a new object of slightly different type. However, the + behavior is as documented above. + + \ingroup console_commands + */ namespace factory { - + + /** \brief SimpleCommandNode factory + + This factory will create a SimpleCommandNode calling the given callback. A SimpleCommandNode + does not support overloading or automatic argument parsing. + + \attention This class is of interest mostly for testing and as a simple CommandNode + example. Use senf::console::factory::Command instead. + */ class SimpleCommand : public detail::NodeFactory { @@ -687,15 +731,32 @@ namespace factory { explicit SimpleCommand(SimpleCommandNode::Function fn); - SimpleCommandNode & create(DirectoryNode & dir, std::string const & name) const; - SimpleCommand const & doc(std::string const & doc) const; + ///< Set simple command documentation SimpleCommand const & shortdoc(std::string const & doc) const; + ///< Set simple command short documentation private: + SimpleCommandNode & create(DirectoryNode & dir, std::string const & name) const; + SimpleCommandNode::ptr node_; + + friend class senf::console::DirectoryNode; }; + /** \brief DirectoryNode factory + + This factory will create new directory nodes. Use + + \code + namespace fty = senf::console::factory; + node.add("mydir", fty::Directory()) + \endcode + + To add a directory \a mydir to \a node. + + \see \ref node_tree + */ class Directory : public detail::NodeFactory { @@ -705,15 +766,32 @@ namespace factory { Directory(); - DirectoryNode & create(DirectoryNode & dir, std::string const & name) const; - Directory const & doc(std::string const & doc) const; + ///< Set directory documentation Directory const & shortdoc(std::string const & doc) const; + ///< Set directory short documentation private: + DirectoryNode & create(DirectoryNode & dir, std::string const & name) const; + DirectoryNode::ptr node_; + + friend class senf::console::DirectoryNode; }; + /** \brief LinkNode factory + + This factory will create new link nodes. Use + + \code + namespace fty = senf::console::factory; + node.add("mylink", fty::Link(targetNode)) + \endcode + + To add a link \a mylink to \a node pointing to \a targetNode + + \see \ref node_tree + */ class Link : public detail::NodeFactory { @@ -723,19 +801,19 @@ namespace factory { explicit Link(GenericNode & target); + private: LinkNode & create(DirectoryNode & dir, std::string const & name) const; - private: LinkNode::ptr node_; + + friend class senf::console::DirectoryNode; }; } -#endif - }} -///////////////////////////////hh.e//////////////////////////////////////// +//-///////////////////////////////////////////////////////////////////////////////////////////////// #include "Node.cci" //#include "Node.ct" #include "Node.cti"