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