X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FVariables.hh;h=1afc654c2fde2400cb088207ecd8acd7ae3668c8;hb=fa5eaa97c8593e3587c87f25adb14f7f91f31f37;hp=58924b265865a08000570a01f20d332d6069a4a4;hpb=80c83d2565c50f8ad33af2be0f4cb3e5735cafcf;p=senf.git diff --git a/Console/Variables.hh b/Console/Variables.hh index 58924b2..1afc654 100644 --- a/Console/Variables.hh +++ b/Console/Variables.hh @@ -27,6 +27,9 @@ #define HH_Variables_ 1 // Custom includes +#include +#include +#include #include "ParsedCommand.hh" #include "Variables.ih" @@ -36,40 +39,136 @@ namespace senf { namespace console { + class ScopedDirectoryBase; + template class VariableAttributor; + +#ifndef DOXYGEN + template - class VariableAttributor + VariableAttributor senf_console_add_node( + DirectoryNode & node, std::string const & name, Variable & var, int, + typename boost::disable_if< boost::is_convertible >::type * = 0); + + template + typename detail::VariableNodeCreator::result_type + senf_console_add_node(DirectoryNode & node, std::string const & name, + boost::reference_wrapper var, int); + +#endif + + /** \brief Variable command attributes (const) + + \see VariableAttributor + */ + template + class ConstVariableAttributor { public: - typedef typename detail::SetVariable::Traits::Overload SetOverload; typedef typename detail::QueryVariable::Traits::Overload QueryOverload; - + typedef typename QueryOverload::Formatter Formatter; typedef OverloadedCommandNode node_type; - typedef VariableAttributor return_type; + typedef ConstVariableAttributor return_type; + + ConstVariableAttributor doc(std::string const & doc); + ConstVariableAttributor formatter(Formatter formatter); protected: + explicit ConstVariableAttributor(QueryOverload & queryOverload); private: - VariableAttributor(QueryOverload & queryOverload, SetOverload & setOverload); - QueryOverload & queryOverload_; - SetOverload & setOverload_; -#ifndef DOXYGEN - - template - friend VariableAttributor senf_console_add_node(DirectoryNode & node, - std::string const & name, - V * var, int); + friend class detail::VariableNodeCreator; + }; + + /** \brief Variable command attributes + + Variable commands allow to register any arbitrary variable as a command node. The variable + will be registered as two command overloads: One which takes a single argument of the + variables type to set the variable and another one taking no arguments and just querying the + current variable value. + \code + int var; + ScopedDirectory<> dir; + + dir.add("var", var); + \endcode + + Variables should be registered only with a ScopedDirectory declared in the same scope + (e.g. as a class member for member variables). This ensures, that the variable node is + removed from the tree when the scope is destroyed. + + Since a variable command is added as a combination of two ordinary overloads, it is possible + to register additional overloads with the same name before or after registering the + variable. + + It is also possible, to register a variable read-only. To achieve this, just wrap it with \c + boost::cref(). Such a variable cannot be changed only queried. Therefore, it does not have + the parser() and typeName() attributes. + \code + dir.add("const_var", boost::cref(var)) + \endcode + + \ingroup console_commands + */ + template + class VariableAttributor + : public ConstVariableAttributor + { + public: + typedef typename detail::SetVariable::Traits::Overload SetOverload; + typedef typename detail::ArgumentInfo::Parser Parser; + typedef typename detail::SetVariable::OnChangeHandler OnChangeHandler; + typedef OverloadedCommandNode node_type; + typedef VariableAttributor return_type; -#endif + typedef typename ConstVariableAttributor::Formatter Formatter; + typedef typename ConstVariableAttributor::QueryOverload QueryOverload; + + VariableAttributor doc(std::string const & doc); ///< Set documentation of the variable + VariableAttributor formatter(Formatter formatter); ///< Set formatter + /**< The \a formatter must be a callable with a signature + compatible with + \code + void formatter(Variable const & value, std::ostream & os); + \endcode + The \a formatter takes the return value of the call \a + value and writes it properly formated to \a os. */ + + VariableAttributor parser(Parser parser); ///< Set argument parser + /**< The parser is an arbitrary callable object with + the signature + \code + void parser(senf::console::ParseCommandInfo::TokensRange const & tokens, value_type & out); + \endcode + + where \c value_type is the type of the overload + parameter. The parser must read and parse the complete + \a tokens range and return the parsed value in \a + out. If the parser fails, it must raise a + senf::console::SyntaxErrorException. */ + VariableAttributor typeName(std::string const & name); ///< Set name of the variable type + VariableAttributor onChange(OnChangeHandler handler); ///< Set change callback + /**< The \a handler callback is called, whenever the value + of the variable is changed. The new value has already + been set, when the callback is called, the old value is + passed to the callback. The callback must have a + signature compatible to + \code + void handler(Variable const & oldValue); + \endcode */ + + protected: - }; + private: + VariableAttributor(QueryOverload & queryOverload, SetOverload & setOverload, + Variable & var); - template - VariableAttributor senf_console_add_node(DirectoryNode & node, - std::string const & name, - Variable * var, int); + SetOverload & setOverload_; + Variable & var_; + friend class detail::VariableNodeCreator; + }; }} ///////////////////////////////hh.e////////////////////////////////////////