Fix karmic build
[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 "ParsedCommand.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     
46
47 #ifndef DOXYGEN
48
49     template <class Variable>
50     typename detail::VariableNodeCreator<Variable>::result_type
51     senf_console_add_node(
52         DirectoryNode & node, std::string const & name, Variable & var, int,
53         typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type * = 0,
54         typename boost::disable_if< boost::is_convertible<Variable*, GenericNode*> >::type * = 0,
55         typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type * = 0);
56
57     template <class Variable>
58     typename detail::VariableNodeCreator<Variable const>::result_type
59     senf_console_add_node(
60         DirectoryNode & node, std::string const & name, Variable const & var, int,
61         typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type * = 0,
62         typename boost::disable_if< boost::is_convertible<Variable*, GenericNode*> >::type * = 0,
63         typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type * = 0);
64
65     template <class Variable>
66     typename detail::VariableNodeCreator<Variable>::result_type
67     senf_console_add_node(DirectoryNode & node, std::string const & name, 
68                           boost::reference_wrapper<Variable> var, int);
69
70     template <class Variable, class Owner>
71     typename detail::VariableNodeCreator<Variable>::result_type
72     senf_console_add_node(
73         DirectoryNode & node, Owner & owner, std::string const & name, Variable & var, int,
74         typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type * = 0,
75         typename boost::disable_if< boost::is_convertible<Variable*, GenericNode*> >::type * = 0,
76         typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type * = 0);
77
78     template <class Variable, class Owner>
79     typename detail::VariableNodeCreator<Variable const>::result_type
80     senf_console_add_node(
81         DirectoryNode & node, Owner & owner, std::string const & name, Variable const & var, int,
82         typename boost::disable_if< boost::is_convertible<Variable*, ScopedDirectoryBase*> >::type * = 0,
83         typename boost::disable_if< boost::is_convertible<Variable*, GenericNode*> >::type * = 0,
84         typename boost::disable_if_c<detail::ParsedCommandTraits<Variable>::is_callable>::type * = 0);
85
86     template <class Variable, class Owner>
87     typename detail::VariableNodeCreator<Variable>::result_type
88     senf_console_add_node(DirectoryNode & node, Owner & owner, std::string const & name, 
89                           boost::reference_wrapper<Variable> var, int);
90
91 #endif
92
93     /** \brief Variable command attributes (const)
94         
95         \see VariableAttributor
96      */
97     template <class Variable>
98     class ConstVariableAttributor
99     {
100     public:
101         typedef typename detail::QueryVariable<Variable>::Traits::Overload QueryOverload;
102         typedef typename QueryOverload::Formatter Formatter;
103         typedef OverloadedCommandNode node_type;
104         typedef ConstVariableAttributor return_type;
105
106         ConstVariableAttributor doc(std::string const & doc);
107         ConstVariableAttributor shortdoc(std::string const & doc);
108         ConstVariableAttributor formatter(Formatter formatter);
109
110         OverloadedCommandNode & node() const; ///< Return the node object
111         operator OverloadedCommandNode & () const; ///< Automatically convert to node object
112
113     protected:
114         explicit ConstVariableAttributor(QueryOverload & queryOverload);
115
116     private:
117         QueryOverload & queryOverload_;
118
119         friend class detail::VariableNodeCreator<Variable const>;
120     };
121  
122     /** \brief Variable command attributes
123
124         Variable commands allow to register any arbitrary variable as a command node. The variable
125         will be registered as two command overloads: One which takes a single argument of the
126         variables type to set the variable and another one taking no arguments and just querying the
127         current variable value.
128         \code
129             int var;
130             ScopedDirectory<> dir;
131
132         dir.add("var", var);
133         \endcode
134
135         Variables should be registered only with a ScopedDirectory declared in the same scope
136         (e.g. as a class member for member variables). This ensures, that the variable node is
137         removed from the tree when the scope is destroyed.
138
139         Since a variable command is added as a combination of two ordinary overloads, it is possible
140         to register additional overloads with the same name before or after registering the
141         variable. 
142
143         It is also possible, to register a variable read-only. To achieve this, just wrap it with \c
144         boost::cref(). Such a variable cannot be changed only queried. Therefore, it does not have
145         the parser() and typeName() attributes.
146         \code
147             dir.add("const_var", boost::cref(var))
148         \endcode
149
150         \ingroup console_commands
151      */
152     template <class Variable>
153     class VariableAttributor
154         : public ConstVariableAttributor<Variable>
155     {
156     public:
157         typedef typename detail::SetVariable<Variable>::Traits::Overload SetOverload;
158         typedef typename detail::ArgumentInfo<typename SetOverload::arg1_type>::Parser Parser;
159         typedef typename detail::SetVariable<Variable>::OnChangeHandler OnChangeHandler;
160         typedef OverloadedCommandNode node_type;
161         typedef VariableAttributor return_type;
162
163         typedef typename ConstVariableAttributor<Variable>::Formatter Formatter;
164         typedef typename ConstVariableAttributor<Variable>::QueryOverload QueryOverload;
165
166         VariableAttributor doc(std::string const & doc); ///< Set documentation of the variable
167         VariableAttributor shortdoc(std::string const & doc); ///< Set short documentation
168         VariableAttributor formatter(Formatter formatter); ///< Set formatter
169         /**< The \a formatter must be a callable with a signature
170              compatible with
171              \code
172                  void formatter(Variable const & value, std::ostream & os);
173              \endcode
174                  The \a formatter takes the return value of the call \a
175                  value and writes it properly formated to \a os. */
176        
177         VariableAttributor parser(Parser parser); ///< Set argument parser
178         /**< The parser is an arbitrary callable object with
179              the signature
180              \code
181                  void parser(senf::console::ParseCommandInfo::TokensRange const & tokens, value_type & out);
182              \endcode
183
184              where \c value_type is the type of the overload
185              parameter. The parser must read and parse the complete
186              \a tokens range and return the parsed value in \a
187              out. If the parser fails, it must raise a
188              senf::console::SyntaxErrorException. */
189         VariableAttributor typeName(std::string const & name); ///< Set name of the variable type
190         VariableAttributor onChange(OnChangeHandler handler); ///< Set change callback
191         /**< The \a handler callback is called, whenever the value
192              of the variable is changed. The new value has already
193              been set, when the callback is called, the old value is
194              passed to the callback. The callback must have a
195              signature compatible to
196              \code
197                  void handler(Variable const & oldValue);
198              \endcode */
199  
200     protected:
201
202     private:
203         VariableAttributor(QueryOverload & queryOverload, SetOverload & setOverload, 
204                            Variable & var);
205
206         SetOverload & setOverload_;
207         Variable & var_;
208
209         friend class detail::VariableNodeCreator<Variable>;
210     };
211 }}
212
213 ///////////////////////////////hh.e////////////////////////////////////////
214 //#include "Variables.cci"
215 //#include "Variables.ct"
216 #include "Variables.cti"
217 #endif
218
219 \f
220 // Local Variables:
221 // mode: c++
222 // fill-column: 100
223 // comment-column: 40
224 // c-file-style: "senf"
225 // indent-tabs-mode: nil
226 // ispell-local-dictionary: "american"
227 // compile-command: "scons -u test"
228 // End: