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)
int main(int, char**)
{
+ namespace fty = senf::console::factory;
+
// 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 ( 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 <foo> [<bar>]\n\n"
- "If <bar> is given, flurgle the <foo>, otherwise burgle it");
+ "If <bar> is given, flurgle the <foo>, otherwise burgle it"));
// Create a SomeClass instance and add it's directory.
SomeClass someClass;
#include <boost/enable_shared_from_this.hpp>
#include <boost/utility.hpp>
#include <boost/range/iterator_range.hpp>
-#include <boost/typeof/typeof.hpp>
-#include <boost/type_traits/remove_reference.hpp>
#include <boost/any.hpp>
-#include "../../Utils/Exception.hh"
-#include "../../Utils/mpl.hh"
-#include "../../Utils/Logger/SenfLog.hh"
-#include "../../Utils/type_traits.hh"
-#include "Parse.hh"
+#include <senf/Utils/Exception.hh>
+#include <senf/Utils/Logger/SenfLog.hh>
//#include "Node.mpp"
///////////////////////////////hh.p////////////////////////////////////////
class DirectoryNode;
class CommandNode;
+ namespace detail { struct NodeFactory {}; }
+
/** \brief Get console root node */
DirectoryNode & root();
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 <class Object>
- struct NodeCreateTraits
- {
- typedef BOOST_TYPEOF_TPL( senf_console_add_node(
- * static_cast<DirectoryNode *>(0),
- * static_cast<std::string const *>(0),
- * static_cast<Object *>(0),
- 0) ) base_type;
- typedef typename senf::remove_cvref<base_type>::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
'-n' is added to the name until the name is unique. If
\a name is empty, it is set to 'unnamed'. */
- template <class Object>
- typename NodeCreateTraits<Object>::result_type add(std::string const & name,
- Object const & ob);
+ template <class NodeType>
+ NodeType & add(std::string const & name, NodeType & node,
+ typename boost::enable_if< boost::is_convertible<NodeType &, GenericNode &> >::type * = 0);
+
+ template <class Factory>
+ typename Factory::result_type add(std::string const & name, Factory const & factory,
+ typename boost::enable_if< boost::is_convertible<Factory const &, detail::NodeFactory const &> >::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
- <tt>senf_console_add_node</tt> 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 <class Object>
- typename NodeCreateTraits<Object>::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
\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. */
///< 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. */
-
///\}
///////////////////////////////////////////////////////////////////////////
struct UnknownNodeNameException : public senf::Exception
{ UnknownNodeNameException() : senf::Exception("Unknown node name") {}};
-#ifndef DOXYGEN
- template <class Type>
- struct NodeCreateTraits< boost::shared_ptr<Type> >
- {};
-#endif
-
/** \brief Config/console tree command node
The CommandNode is the base-class for the tree leaf nodes. Concrete command node
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 {
+
+ class SimpleCommand
+ : public detail::NodeFactory
+ {
+ public:
+ typedef SimpleCommandNode node_type;
+ typedef SimpleCommandNode & result_type;
- DirectoryNode & senf_console_add_node(DirectoryNode & node, std::string const & name,
- DirectoryNode & dir, int);
+ explicit SimpleCommand(SimpleCommandNode::Function fn);
-#endif
+ 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_;
+ };
-BOOST_TYPEOF_REGISTER_TYPE(senf::console::DirectoryNode)
-BOOST_TYPEOF_REGISTER_TYPE(senf::console::SimpleCommandNode)
+ class Directory
+ : public detail::NodeFactory
+ {
+ public:
+ typedef DirectoryNode node_type;
+ typedef DirectoryNode & result_type;
+
+ 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"
#include "Node.cti"
#endif
-
+\f
// Local Variables:
// mode: c++
// fill-column: 100