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