X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FVariables.hh;h=1afc654c2fde2400cb088207ecd8acd7ae3668c8;hb=456ee576285b76aa46240f8001f426757810dcc1;hp=5b1b7280c356b78c5b901e065b8f69ff49a9eb67;hpb=80c6cb7ba9ad7776824c84809f422209adf27331;p=senf.git diff --git a/Console/Variables.hh b/Console/Variables.hh index 5b1b728..1afc654 100644 --- a/Console/Variables.hh +++ b/Console/Variables.hh @@ -42,6 +42,8 @@ namespace console { class ScopedDirectoryBase; template class VariableAttributor; +#ifndef DOXYGEN + template VariableAttributor senf_console_add_node( DirectoryNode & node, std::string const & name, Variable & var, int, @@ -52,6 +54,12 @@ namespace console { 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 { @@ -72,32 +80,92 @@ namespace console { friend class detail::VariableNodeCreator; }; - - template + + /** \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; typedef typename ConstVariableAttributor::Formatter Formatter; typedef typename ConstVariableAttributor::QueryOverload QueryOverload; - VariableAttributor parser(Parser parser); - VariableAttributor typeName(std::string const & name); - - VariableAttributor doc(std::string const & doc); - VariableAttributor formatter(Formatter formatter); + 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); + VariableAttributor(QueryOverload & queryOverload, SetOverload & setOverload, + Variable & var); SetOverload & setOverload_; + Variable & var_; friend class detail::VariableNodeCreator; };