71ed3c160c706b9afb315c15283b65416ad8cc1f
[senf.git] / senf / Utils / Console / Variables.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Variables public header */
25
26 #ifndef HH_SENF_Scheduler_Console_Variables_
27 #define HH_SENF_Scheduler_Console_Variables_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31 #include <boost/type_traits/is_convertible.hpp>
32 #include <boost/ref.hpp>
33 #include "Node.hh"
34
35 #include "Variables.ih"
36 //#include "Variables.mpp"
37 ///////////////////////////////hh.p////////////////////////////////////////
38
39 namespace senf {
40 namespace console {
41
42     class ScopedDirectoryBase;
43     template <class Variable> class VariableAttributor;
44
45 namespace factory {
46
47     /** \brief Variable command attributes (const)
48         
49         \see VariableFactory
50      */
51     template <class Variable>
52     class ConstVariableFactory
53         : public detail::NodeFactory
54     {
55     public:
56         typedef typename detail::QueryVariable<Variable>::Traits::Overload QueryOverload;
57         typedef typename QueryOverload::Formatter Formatter;
58         typedef OverloadedCommandNode node_type;
59         typedef OverloadedCommandNode & result_type;
60
61         ConstVariableFactory doc(std::string const & doc);
62         ConstVariableFactory shortdoc(std::string const & doc);
63         ConstVariableFactory formatter(Formatter formatter);
64
65         OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
66         
67         explicit ConstVariableFactory(Variable const & var);
68
69     private:
70         typename QueryOverload::ptr queryOverload_;
71         boost::optional<std::string> doc_;
72         boost::optional<std::string> shortdoc_;
73     };
74  
75     /** \brief Variable command attributes
76
77         Variable commands allow to register any arbitrary variable as a command node. The variable
78         will be registered as two command overloads: One which takes a single argument of the
79         variables type to set the variable and another one taking no arguments and just querying the
80         current variable value.
81         \code
82             int var;
83             ScopedDirectory<> dir;
84
85         dir.add("var", var);
86         \endcode
87
88         Variables should be registered only with a ScopedDirectory declared in the same scope
89         (e.g. as a class member for member variables). This ensures, that the variable node is
90         removed from the tree when the scope is destroyed.
91
92         Since a variable command is added as a combination of two ordinary overloads, it is possible
93         to register additional overloads with the same name before or after registering the
94         variable. 
95
96         It is also possible, to register a variable read-only. To achieve this, just wrap it with \c
97         boost::cref(). Such a variable cannot be changed only queried. Therefore, it does not have
98         the parser() and typeName() attributes.
99         \code
100             dir.add("const_var", boost::cref(var))
101         \endcode
102
103         \ingroup console_commands
104      */
105     template <class Variable>
106     class VariableFactory
107         : public ConstVariableFactory<Variable>
108     {
109     public:
110         typedef typename detail::SetVariable<Variable>::Traits::Overload SetOverload;
111         typedef typename detail::ArgumentInfo<typename SetOverload::arg1_type>::Parser Parser;
112         typedef typename detail::SetVariable<Variable>::OnChangeHandler OnChangeHandler;
113
114         typedef typename ConstVariableFactory<Variable>::Formatter Formatter;
115         typedef typename ConstVariableFactory<Variable>::QueryOverload QueryOverload;
116
117         VariableFactory doc(std::string const & doc); ///< Set documentation of the variable
118         VariableFactory shortdoc(std::string const & doc); ///< Set short documentation
119         VariableFactory formatter(Formatter formatter); ///< Set formatter
120                                         /**< The \a formatter must be a callable with a signature
121                                              compatible with
122                                              \code
123                                                  void formatter(Variable const & value, std::ostream & os);
124                                              \endcode
125                                                  The \a formatter takes the return value of the call \a
126                                                  value and writes it properly formated to \a os. */
127         VariableFactory parser(Parser parser); ///< Set argument parser
128                                         /**< The parser is an arbitrary callable object with
129                                              the signature
130                                              \code
131                                                  void parser(senf::console::ParseCommandInfo::TokensRange const & tokens, value_type & out);
132                                              \endcode
133                                              
134                                              where \c value_type is the type of the overload
135                                              parameter. The parser must read and parse the complete
136                                              \a tokens range and return the parsed value in \a
137                                              out. If the parser fails, it must raise a
138                                              senf::console::SyntaxErrorException. */
139         VariableFactory typeName(std::string const & name); ///< Set name of the variable type
140         VariableFactory onChange(OnChangeHandler handler); ///< Set change callback
141                                         /**< The \a handler callback is called, whenever the value
142                                              of the variable is changed. The new value has already
143                                              been set, when the callback is called, the old value is
144                                              passed to the callback. The callback must have a
145                                              signature compatible to
146                                              \code
147                                                  void handler(Variable const & oldValue);
148                                              \endcode */
149
150         OverloadedCommandNode & create(DirectoryNode & dir, std::string const & name) const;
151
152         explicit VariableFactory(Variable & var);
153
154     protected:
155
156     private:
157         typename SetOverload::ptr setOverload_;
158         Variable & var_;
159     };
160
161     template <class Var>
162     VariableFactory<Var> Variable(Var & var);
163
164     template <class Var>
165     VariableFactory<Var> Variable(boost::reference_wrapper<Var> var);
166
167     template <class Var>
168     ConstVariableFactory<Var> Variable(Var const & var);
169
170     template <class Var>
171     ConstVariableFactory<Var> Variable(boost::reference_wrapper<Var const> var);
172
173 }}}
174
175 ///////////////////////////////hh.e////////////////////////////////////////
176 //#include "Variables.cci"
177 //#include "Variables.ct"
178 #include "Variables.cti"
179 #endif
180
181 \f
182 // Local Variables:
183 // mode: c++
184 // fill-column: 100
185 // comment-column: 40
186 // c-file-style: "senf"
187 // indent-tabs-mode: nil
188 // ispell-local-dictionary: "american"
189 // compile-command: "scons -u test"
190 // End: