Subversion Repositories gelsvn

Rev

Rev 626 | Rev 647 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 626 Rev 630
1
/* ----------------------------------------------------------------------- *
1
/* ----------------------------------------------------------------------- *
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
3
 * Copyright (C) the authors and DTU Informatics
3
 * Copyright (C) the authors and DTU Informatics
4
 * For license and list of authors, see ../../doc/intro.pdf
4
 * For license and list of authors, see ../../doc/intro.pdf
5
 * ----------------------------------------------------------------------- */
5
 * ----------------------------------------------------------------------- */
6
 
6
 
7
/**
7
/**
8
 * @file   Console.h
8
 * @file   Console.h
9
 * @author Anders Wang Kristensen <awk@imm.dtu.dk>
9
 * @author Anders Wang Kristensen <awk@imm.dtu.dk>
10
 * @date   Fri Oct 22 18:32:06 2011
10
 * @date   Fri Oct 22 18:32:06 2011
11
 *
11
 *
12
 * @brief  OpenGL 'Quake'-like console
12
 * @brief  OpenGL 'Quake'-like console
13
 */
13
 */
14
 
14
 
15
#ifndef __GEL_GLGRAPHICS_CONSOLE_H__
15
#ifndef __GEL_GLGRAPHICS_CONSOLE_H__
16
#define __GEL_GLGRAPHICS_CONSOLE_H__
16
#define __GEL_GLGRAPHICS_CONSOLE_H__
17
 
17
 
18
#include "gel_gl.h"
18
#include "gel_gl.h"
19
 
19
 
20
#include <functional> //make_shared, bind
20
#include <functional> //make_shared, bind
21
#include <map> //multimap
21
#include <map> //multimap
22
#include <sstream> //stringstream
22
#include <sstream> //stringstream
23
#include <memory> //unique_ptr
23
#include <memory> //unique_ptr
24
#include <vector>
24
#include <vector>
25
#include <cassert>
25
#include <cassert>
26
 
26
 
27
namespace GLGraphics {
27
namespace GLGraphics {
28
 
28
 
29
class Console
29
class Console
30
{
30
{
31
public:
31
public:
32
    Console();
32
    Console();
33
    ~Console() throw();
33
    ~Console() throw();
34
 
34
 
35
    //GLUT functions
35
    //GLUT functions
36
    void display();
36
    void display();
37
    void keyboard(unsigned char key);
37
    void keyboard(unsigned char key);
38
    void special(int key);
38
    void special(int key);
39
 
39
 
40
    //stdio-like io
40
    //stdio-like io
41
    void print(const char* buffer);
41
    void print(const char* buffer);
42
    void printf(const char* format, ...);
42
    void printf(const char* format, ...);
43
    void newline();
43
    void newline();
44
 
44
 
45
    //execute command
45
    //execute command
46
    void execute(const char* buffer);
46
    void execute(const char* buffer);
47
    void executef(const char* format, ...);
47
    void executef(const char* format, ...);
48
 
48
 
49
    typedef int cmd_token;
49
    typedef int cmd_token;
50
 
50
 
51
    //0-ary
51
    //0-ary
52
    inline cmd_token reg_cmd0(const std::string& name,
52
    inline cmd_token reg_cmd0(const std::string& name,
53
                              const std::function<void ()>& f,
53
                              const std::function<void ()>& f,
54
                              const std::string& help);
54
                              const std::string& help);
55
 
55
 
56
    //1-ary
56
    //1-ary
57
    template <typename A0>
57
    template <typename A0>
58
    cmd_token reg_cmd1(const std::string& name,
58
    cmd_token reg_cmd1(const std::string& name,
59
                       const std::function<void (const A0&)>& f,
59
                       const std::function<void (const A0&)>& f,
60
                       const std::string& help);
60
                       const std::string& help);
61
 
61
 
62
    //2-ary
62
    //2-ary
63
    template <typename A0, typename A1>
63
    template <typename A0, typename A1>
64
    cmd_token reg_cmd2(const std::string& name,
64
    cmd_token reg_cmd2(const std::string& name,
65
                       const std::function<void (const A0&,const A1&)>& f,
65
                       const std::function<void (const A0&,const A1&)>& f,
66
                       const std::string& help);
66
                       const std::string& help);
67
 
67
 
68
    //3-ary
68
    //3-ary
69
    template <typename A0, typename A1, typename A2>
69
    template <typename A0, typename A1, typename A2>
70
    cmd_token reg_cmd3(const std::string& name,
70
    cmd_token reg_cmd3(const std::string& name,
71
                       const std::function<void (const A0&,
71
                       const std::function<void (const A0&,
72
                                                 const A1&,const A2&)>& f,
72
                                                 const A1&,const A2&)>& f,
73
                       const std::string& help);
73
                       const std::string& help);
74
 
74
 
75
    //N-ary
75
    //N-ary
76
    inline cmd_token reg_cmdN(const std::string& name,
76
    inline cmd_token reg_cmdN(const std::string& name,
77
                              const std::function<
77
                              const std::function<
78
                                void (const std::vector<std::string>&)>& f,
78
                                void (const std::vector<std::string>&)>& f,
79
                              const std::string& help);
79
                              const std::string& help);
80
 
80
 
81
    //remove
81
    //remove
82
    inline void unreg_cmd(cmd_token);
82
    inline void unreg_cmd(cmd_token);
83
 
83
 
84
    //get name/help of registrered command
84
    //get name/help of registrered command
85
    const char* get_name(cmd_token) const;
85
    const char* get_name(cmd_token) const;
86
    const char* get_help(cmd_token) const;
86
    const char* get_help(cmd_token) const;
87
 
87
 
88
    //helper classes
88
    //helper classes
89
    class command;
89
    class command;
90
 
90
 
91
    template <typename T>
91
    template <typename T>
92
    class variable;
92
    class variable;
93
 
93
 
94
private:
94
private:
95
    //make noncopyable
95
    //make noncopyable
96
    Console(Console&);
96
    Console(Console&);
97
    const Console& operator=(const Console&);
97
    const Console& operator=(const Console&);
98
 
98
 
99
    static inline void from_string(const std::string& source,
99
    static inline void from_string(const std::string& source,
100
                                   std::string& target)
100
                                   std::string& target)
101
    {
101
    {
102
        target = source;
102
        target = source;
103
    }
103
    }
104
 
104
 
105
    template <typename T>
105
    template <typename T>
106
    static inline void from_string(const std::string& source, T& target)
106
    static inline void from_string(const std::string& source, T& target)
107
    {
107
    {
108
        std::stringstream ss(source);
108
        std::stringstream ss(source);
109
        if (!(ss >> target))
109
        if (!(ss >> target))
110
        {
110
        {
111
            std::stringstream ss;
111
            std::stringstream ss;
112
            ss << "Cannot convert "
112
            ss << "Cannot convert "
113
               << source << " to '" << typeid(T).name() << "'.";
113
               << source << " to '" << typeid(T).name() << "'.";
114
            throw std::invalid_argument(ss.str());
114
            throw std::invalid_argument(ss.str());
115
        }
115
        }
116
    }
116
    }
117
 
117
 
118
    //from string
118
    //from string
119
    template <typename T>
119
    template <typename T>
120
    static T lexical_cast(const std::string& source)
120
    static T lexical_cast(const std::string& source)
121
    {
121
    {
122
        T target;
122
        T target;
123
        from_string(source, target);
123
        from_string(source, target);
124
        return target;
124
        return target;
125
    }
125
    }
126
 
126
 
127
    //to string
127
    //to string
128
    template <typename S>
128
    template <typename S>
129
    static std::string to_string(const S& source)
129
    static std::string to_string(const S& source)
130
    {
130
    {
131
        std::stringstream ss;
131
        std::stringstream ss;
132
        if (!(ss << source))
132
        if (!(ss << source))
133
        {
133
        {
134
            //converting *to* string should never fail
134
            //converting *to* string should never fail
135
            throw std::invalid_argument("Cannot convert argument to string.");
135
            throw std::invalid_argument("Cannot convert argument to string.");
136
        }
136
        }
137
 
137
 
138
        return ss.str();
138
        return ss.str();
139
    }
139
    }
140
 
140
 
141
    class command_base
141
    class command_base
142
    {
142
    {
143
    public:
143
    public:
144
        inline command_base(Console& c, const std::string& help)
144
        inline command_base(Console& c, const std::string& help)
145
            : m_console(c), m_help(help) { m_id = c.m_id_counter++; }
145
            : m_console(c), m_help(help) { m_id = c.m_id_counter++; }
146
        virtual ~command_base() {}
146
        virtual ~command_base() {}
147
 
147
 
148
        virtual void execute(const std::vector<std::string>& args) const = 0;
148
        virtual void execute(const std::vector<std::string>& args) const = 0;
149
        virtual size_t arity() const = 0;
149
        virtual size_t arity() const = 0;
150
 
150
 
151
        inline cmd_token get_id() const { return m_id; }
151
        inline cmd_token get_id() const { return m_id; }
152
 
152
 
153
        inline const char* get_help() const { return m_help.c_str(); }
153
        inline const char* get_help() const { return m_help.c_str(); }
154
 
154
 
155
    protected:
155
    protected:
156
        Console& m_console;
156
        Console& m_console;
157
        cmd_token m_id;
157
        cmd_token m_id;
158
        std::string m_help;
158
        std::string m_help;
159
    };
159
    };
160
 
160
 
161
    //no need to be a template
161
    //no need to be a template
162
    class command0 : public command_base
162
    class command0 : public command_base
163
    {
163
    {
164
    public:
164
    public:
165
        typedef std::function<void ()> function_type;
165
        typedef std::function<void ()> function_type;
166
 
166
 
167
        inline command0(Console& c,
167
        inline command0(Console& c,
168
                        const std::string& h, const function_type& f)
168
                        const std::string& h, const function_type& f)
169
            : command_base(c,h), m_callback(f) {}
169
            : command_base(c,h), m_callback(f) {}
170
 
170
 
171
        inline void execute(const std::vector<std::string>& args) const;
171
        inline void execute(const std::vector<std::string>& args) const;
172
        inline size_t arity() const { return 0; }
172
        inline size_t arity() const { return 0; }
173
 
173
 
174
    private:
174
    private:
175
        function_type m_callback;
175
        function_type m_callback;
176
    };
176
    };
177
 
177
 
178
    template <typename A0>
178
    template <typename A0>
179
    class command1 : public command_base
179
    class command1 : public command_base
180
    {
180
    {
181
    public:
181
    public:
182
        typedef typename std::function<void (const A0&)> function_type;
182
        typedef typename std::function<void (const A0&)> function_type;
183
 
183
 
184
        command1(Console& c, const std::string& h, const function_type& f)
184
        command1(Console& c, const std::string& h, const function_type& f)
185
            : command_base(c,h), m_callback(f) {}
185
            : command_base(c,h), m_callback(f) {}
186
 
186
 
187
        void execute(const std::vector<std::string>& args) const;
187
        void execute(const std::vector<std::string>& args) const;
188
        size_t arity() const { return 1; }
188
        size_t arity() const { return 1; }
189
 
189
 
190
    private:
190
    private:
191
        function_type m_callback;
191
        function_type m_callback;
192
    };
192
    };
193
 
193
 
194
    template <typename A0, typename A1>
194
    template <typename A0, typename A1>
195
    class command2 : public command_base
195
    class command2 : public command_base
196
    {
196
    {
197
    public:
197
    public:
198
        typedef typename std::function<void (const A0&,
198
        typedef typename std::function<void (const A0&,
199
                                             const A1&)> function_type;
199
                                             const A1&)> function_type;
200
 
200
 
201
        command2(Console& c, const std::string& h, const function_type& f)
201
        command2(Console& c, const std::string& h, const function_type& f)
202
            : command_base(c,h), m_callback(f) {}
202
            : command_base(c,h), m_callback(f) {}
203
 
203
 
204
        void execute(const std::vector<std::string>& args) const;
204
        void execute(const std::vector<std::string>& args) const;
205
        size_t arity() const { return 2; }
205
        size_t arity() const { return 2; }
206
 
206
 
207
    private:
207
    private:
208
        function_type m_callback;
208
        function_type m_callback;
209
    };
209
    };
210
 
210
 
211
    template <typename A0, typename A1, typename A2>
211
    template <typename A0, typename A1, typename A2>
212
    class command3 : public command_base
212
    class command3 : public command_base
213
    {
213
    {
214
    public:
214
    public:
215
        typedef typename std::function<void (const A0&,
215
        typedef typename std::function<void (const A0&,
216
                                             const A1&,
216
                                             const A1&,
217
                                             const A2&)> function_type;
217
                                             const A2&)> function_type;
218
 
218
 
219
        command3(Console& c, const std::string& h, const function_type& f)
219
        command3(Console& c, const std::string& h, const function_type& f)
220
            : command_base(c,h), m_callback(f) {}
220
            : command_base(c,h), m_callback(f) {}
221
 
221
 
222
        void execute(const std::vector<std::string>& args) const;
222
        void execute(const std::vector<std::string>& args) const;
223
        size_t arity() const { return 3; }
223
        size_t arity() const { return 3; }
224
 
224
 
225
    private:
225
    private:
226
        function_type m_callback;
226
        function_type m_callback;
227
    };
227
    };
228
 
228
 
229
    //no need to be a template
229
    //no need to be a template
230
    class commandN : public command_base
230
    class commandN : public command_base
231
    {
231
    {
232
    public:
232
    public:
233
        typedef std::function<
233
        typedef std::function<
234
            void (const std::vector<std::string>&)> function_type;
234
            void (const std::vector<std::string>&)> function_type;
235
 
235
 
236
        inline commandN(Console& c,
236
        inline commandN(Console& c,
237
                        const std::string& h, const function_type& f)
237
                        const std::string& h, const function_type& f)
238
            : command_base(c,h), m_callback(f) {}
238
            : command_base(c,h), m_callback(f) {}
239
 
239
 
240
        inline void execute(const std::vector<std::string>& args) const;
240
        inline void execute(const std::vector<std::string>& args) const;
241
        inline size_t arity() const { return any_arity; }
241
        inline size_t arity() const { return any_arity; }
242
 
242
 
243
    private:
243
    private:
244
        function_type m_callback;
244
        function_type m_callback;
245
    };
245
    };
246
 
246
 
247
    //multi, so we can have multiple cmds with same name (but different arity)
247
    //multi, so we can have multiple cmds with same name (but different arity)
248
    typedef std::multimap<std::string,
248
    typedef std::multimap<std::string,
249
                          std::unique_ptr<command_base> > command_map_t;
249
                          std::unique_ptr<command_base> > command_map_t;
250
 
250
 
251
    cmd_token add_command(const std::string& name,
251
    cmd_token add_command(const std::string& name,
252
                           std::unique_ptr<command_base>&& ptr);
252
                           std::unique_ptr<command_base>&& ptr);
253
    void remove_command(cmd_token);
253
    void remove_command(cmd_token);
254
 
254
 
255
    void tab_completion();
255
    void tab_completion();
256
 
256
 
257
    std::vector<std::string> parse_cmdline(const char* buffer) const;
257
    std::vector<std::string> parse_cmdline(const char* buffer) const;
258
 
258
 
259
    //builtin commands
259
    //builtin commands
260
    void help();
260
    void help();
261
    void help(const std::string&);
261
    void help(const std::string&);
262
    void clear();
262
    void clear();
263
    void history();
263
    void history();
264
 
264
 
265
    void load_history();
265
    void load_history();
266
    void save_history() const;
266
    void save_history() const;
267
    void clear_history();
267
    void clear_history();
268
 
268
 
269
    enum { any_arity = 0xFFFF };
269
    enum { any_arity = 0xFFFF };
270
 
270
 
271
    //draw commands
271
    //draw commands
272
    void draw_text(int x, int y,
272
    void draw_text(int x, int y,
273
                   float r, float g, float b,
273
                   float r, float g, float b,
274
                   const char* buffer);
274
                   const char* buffer);
275
 
275
 
276
    void draw_textf(int x, int y,
276
    void draw_textf(int x, int y,
277
                    float r, float g, float b,
277
                    float r, float g, float b,
278
                    const char* fmt, ...);
278
                    const char* fmt, ...);
279
    //state
279
    //state
280
    command_map_t m_commands;
280
    command_map_t m_commands;
281
    std::vector<std::string> m_buffer;
281
    std::vector<std::string> m_buffer;
282
 
282
 
283
    size_t m_history_index;
283
    size_t m_history_index;
284
    std::vector<std::string> m_history;
284
    std::vector<std::string> m_history;
285
 
285
 
286
    std::string::size_type m_caret;
286
    std::string::size_type m_caret;
287
    std::string m_current_command;
287
    std::string m_current_command;
288
 
288
 
289
    int m_id_counter;
289
    int m_id_counter;
290
    bool m_is_executing;
290
    bool m_is_executing;
291
 
291
 
292
    GLuint m_font;
292
    GLuint m_font;
293
 
293
 
294
    static const unsigned char g_png_data[];
294
    static const unsigned char g_png_data[];
295
    static const size_t g_png_size;
295
    static const size_t g_png_size;
296
};
296
};
297
 
297
 
298
//0-ary
298
//0-ary
299
Console::cmd_token Console::reg_cmd0(const std::string& name,
299
Console::cmd_token Console::reg_cmd0(const std::string& name,
300
                                     const std::function<void ()>& f,
300
                                     const std::function<void ()>& f,
301
                                     const std::string& help)
301
                                     const std::string& help)
302
{
302
{
303
    typedef command0 command_type;
303
    typedef command0 command_type;
304
    return add_command(name,
304
    return add_command(name,
305
        std::unique_ptr<command_type>(
305
        std::unique_ptr<command_type>(
306
            new command_type(std::ref(*this), help, f)));
306
            new command_type(std::ref(*this), help, f)));
307
}
307
}
308
 
308
 
309
void Console::command0::execute(const std::vector<std::string>& args) const
309
void Console::command0::execute(const std::vector<std::string>& args) const
310
{
310
{
311
    assert(args.size() == arity());
311
    assert(args.size() == arity());
312
    m_callback();
312
    m_callback();
313
}
313
}
314
 
314
 
315
//1-ary
315
//1-ary
316
template <typename A0>
316
template <typename A0>
317
Console::cmd_token Console::reg_cmd1(const std::string& name,
317
Console::cmd_token Console::reg_cmd1(const std::string& name,
318
                                     const std::function<void (const A0&)>& f,
318
                                     const std::function<void (const A0&)>& f,
319
                                     const std::string& help)
319
                                     const std::string& help)
320
{
320
{
321
    typedef command1<A0> command_type;
321
    typedef command1<A0> command_type;
322
    return add_command(name,
322
    return add_command(name,
323
        std::unique_ptr<command_type>(
323
        std::unique_ptr<command_type>(
324
            new command_type(std::ref(*this), help, f)));
324
            new command_type(std::ref(*this), help, f)));
325
}
325
}
326
 
326
 
327
template <typename A0>
327
template <typename A0>
328
void Console::command1<A0>::execute(const std::vector<std::string>& args) const
328
void Console::command1<A0>::execute(const std::vector<std::string>& args) const
329
{
329
{
330
    assert(args.size() == arity());
330
    assert(args.size() == arity());
331
    m_callback(lexical_cast<A0>(args[0]));
331
    m_callback(lexical_cast<A0>(args[0]));
332
}
332
}
333
 
333
 
334
//2-ary
334
//2-ary
335
template <typename A0, typename A1>
335
template <typename A0, typename A1>
336
Console::cmd_token Console::reg_cmd2(const std::string& name,
336
Console::cmd_token Console::reg_cmd2(const std::string& name,
337
                                     const std::function<void (const A0&,
337
                                     const std::function<void (const A0&,
338
                                       const A1&)>& f,
338
                                       const A1&)>& f,
339
                                     const std::string& help)
339
                                     const std::string& help)
340
{
340
{
341
    typedef command2<A0,A1> command_type;
341
    typedef command2<A0,A1> command_type;
342
    return add_command(name,
342
    return add_command(name,
343
        std::unique_ptr<command_type>(
343
        std::unique_ptr<command_type>(
344
            new command_type(std::ref(*this), help, f)));
344
            new command_type(std::ref(*this), help, f)));
345
}
345
}
346
 
346
 
347
template <typename A0,typename A1>
347
template <typename A0,typename A1>
348
void Console::command2<A0,A1>::execute(
348
void Console::command2<A0,A1>::execute(
349
    const std::vector<std::string>& args) const
349
    const std::vector<std::string>& args) const
350
{
350
{
351
    assert(args.size() == arity());
351
    assert(args.size() == arity());
352
    m_callback(lexical_cast<A0>(args[0]),
352
    m_callback(lexical_cast<A0>(args[0]),
353
               lexical_cast<A1>(args[1]));
353
               lexical_cast<A1>(args[1]));
354
}
354
}
355
 
355
 
356
//3-ary
356
//3-ary
357
template <typename A0, typename A1, typename A2>
357
template <typename A0, typename A1, typename A2>
358
Console::cmd_token Console::reg_cmd3(const std::string& name,
358
Console::cmd_token Console::reg_cmd3(const std::string& name,
359
                                     const std::function<void (const A0&,
359
                                     const std::function<void (const A0&,
360
                                       const A1&,const A2&)>& f,
360
                                       const A1&,const A2&)>& f,
361
                                     const std::string& help)
361
                                     const std::string& help)
362
{
362
{
363
    typedef command3<A0,A1,A2> command_type;
363
    typedef command3<A0,A1,A2> command_type;
364
    return add_command(name,
364
    return add_command(name,
365
        std::unique_ptr<command_type>(
365
        std::unique_ptr<command_type>(
366
            new command_type(std::ref(*this), help, f)));
366
            new command_type(std::ref(*this), help, f)));
367
}
367
}
368
 
368
 
369
template <typename A0,typename A1, typename A2>
369
template <typename A0,typename A1, typename A2>
370
void Console::command3<A0,A1,A2>::execute(
370
void Console::command3<A0,A1,A2>::execute(
371
    const std::vector<std::string>& args) const
371
    const std::vector<std::string>& args) const
372
{
372
{
373
    assert(args.size() == arity());
373
    assert(args.size() == arity());
374
    m_callback(lexical_cast<A0>(args[0]),
374
    m_callback(lexical_cast<A0>(args[0]),
375
               lexical_cast<A1>(args[1]),
375
               lexical_cast<A1>(args[1]),
376
               lexical_cast<A2>(args[2]));
376
               lexical_cast<A2>(args[2]));
377
}
377
}
378
 
378
 
379
//N-ary
379
//N-ary
380
Console::cmd_token Console::reg_cmdN(const std::string& name,
380
Console::cmd_token Console::reg_cmdN(const std::string& name,
381
    const std::function<void (const std::vector<std::string>&)>& f,
381
    const std::function<void (const std::vector<std::string>&)>& f,
382
    const std::string& help)
382
    const std::string& help)
383
{
383
{
384
    typedef commandN command_type;
384
    typedef commandN command_type;
385
    return add_command(name,
385
    return add_command(name,
386
        std::unique_ptr<command_type>(
386
        std::unique_ptr<command_type>(
387
            new command_type(std::ref(*this), help, f)));
387
            new command_type(std::ref(*this), help, f)));
388
}
388
}
389
 
389
 
390
void Console::commandN::execute(const std::vector<std::string>& args) const
390
void Console::commandN::execute(const std::vector<std::string>& args) const
391
{
391
{
392
    m_callback(args);
392
    m_callback(args);
393
}
393
}
394
 
394
 
395
void Console::unreg_cmd(cmd_token id)
395
void Console::unreg_cmd(cmd_token id)
396
{
396
{
397
    remove_command(id);
397
    remove_command(id);
398
}
398
}
399
 
399
 
400
class Console::command
400
class Console::command
401
{
401
{
402
public:
402
public:
403
    inline command() : m_console(NULL) {}
403
    inline command() : m_console(NULL) {}
404
 
404
 
405
    inline void reg(Console& cs,
405
    inline void reg(Console& cs,
406
        const std::string& name,
406
        const std::string& name,
407
        const std::function<void ()>& function,
407
        const std::function<void ()>& function,
408
        const std::string& help)
408
        const std::string& help)
409
    {
409
    {
410
        assert(!m_console);
410
        assert(!m_console);
411
        m_console = &cs;
411
        m_console = &cs;
412
        m_id = m_console->reg_cmd0(name, function, help);
412
        m_id = m_console->reg_cmd0(name, function, help);
413
    }
413
    }
414
 
414
 
415
    template <typename A0>
415
    template <typename A0>
416
    void reg(Console& cs,
416
    void reg(Console& cs,
417
        const std::string& name,
417
        const std::string& name,
418
        const std::function<void (const A0&)>& function,
418
        const std::function<void (const A0&)>& function,
419
        const std::string& help)
419
        const std::string& help)
420
    {
420
    {
421
        assert(!m_console);
421
        assert(!m_console);
422
        m_console = &cs;
422
        m_console = &cs;
423
        m_id = m_console->reg_cmd1<A0>(name, function, help);
423
        m_id = m_console->reg_cmd1<A0>(name, function, help);
424
    }
424
    }
425
 
425
 
426
    template <typename A0, typename A1>
426
    template <typename A0, typename A1>
427
    void reg(Console& cs,
427
    void reg(Console& cs,
428
        const std::string& name,
428
        const std::string& name,
429
        const std::function<void (const A0&, const A1&)>& function,
429
        const std::function<void (const A0&, const A1&)>& function,
430
        const std::string& help)
430
        const std::string& help)
431
    {
431
    {
432
        assert(!m_console);
432
        assert(!m_console);
433
        m_console = &cs;
433
        m_console = &cs;
434
        m_id = m_console->reg_cmd2<A0,A1>(name, function, help);
434
        m_id = m_console->reg_cmd2<A0,A1>(name, function, help);
435
    }
435
    }
436
 
436
 
437
    template <typename A0, typename A1, typename A2>
437
    template <typename A0, typename A1, typename A2>
438
    void reg(Console& cs,
438
    void reg(Console& cs,
439
        const std::string& name,
439
        const std::string& name,
440
        const std::function<void (const A0&,
440
        const std::function<void (const A0&,
441
        const A1&, const A2&)>& function,
441
        const A1&, const A2&)>& function,
442
        const std::string& help)
442
        const std::string& help)
443
    {
443
    {
444
        assert(!m_console);
444
        assert(!m_console);
445
        m_console = &cs;
445
        m_console = &cs;
446
        m_id = m_console->reg_cmd3<A0,A1,A2>(name, function, help);
446
        m_id = m_console->reg_cmd3<A0,A1,A2>(name, function, help);
447
    }
447
    }
448
 
448
 
449
    inline ~command()
449
    inline ~command()
450
    {
450
    {
451
        if (m_console)
451
        if (m_console)
452
            m_console->unreg_cmd(m_id);
452
            m_console->unreg_cmd(m_id);
453
    }
453
    }
454
 
454
 
455
    inline const char* get_name() const
455
    inline const char* get_name() const
456
    {
456
    {
457
        assert(m_console);
457
        assert(m_console);
458
        return m_console->get_name(m_id);
458
        return m_console->get_name(m_id);
459
    }
459
    }
460
 
460
 
461
    inline const char* get_help() const
461
    inline const char* get_help() const
462
    {
462
    {
463
        assert(m_console);
463
        assert(m_console);
464
        return m_console->get_help(m_id);
464
        return m_console->get_help(m_id);
465
    }
465
    }
466
 
466
 
467
    inline Console* get_console() const { return m_console; }
467
    inline Console* get_console() const { return m_console; }
468
    inline cmd_token get_id() const { assert(m_console); return m_id; }
468
    inline cmd_token get_id() const { assert(m_console); return m_id; }
469
 
469
 
470
private:
470
private:
471
    command(command&);
471
    command(command&);
472
    const command& operator=(const command&);
472
    const command& operator=(const command&);
473
 
473
 
474
    Console* m_console;
474
    Console* m_console;
475
    cmd_token m_id;
475
    cmd_token m_id;
476
};
476
};
477
 
477
 
478
template <typename T>
478
template <typename T>
479
class Console::variable
479
class Console::variable
480
{
480
{
481
public:
481
public:
482
    variable(const T& initial_value = T())
482
    variable(const T& initial_value = T())
483
        : m_value(initial_value) {}
483
        : m_value(initial_value) {}
484
 
484
 
485
    void reg(Console& cs,
485
    void reg(Console& cs,
486
        const std::string& name,
486
        const std::string& name,
487
        const std::string& help)
487
        const std::string& help)
488
    {
488
    {
489
        if(m_set_cmd.get_console() == 0)
489
        if(m_set_cmd.get_console() == 0)
490
        {
490
        {
491
            m_print_cmd.reg(cs, name,
491
            m_print_cmd.reg(cs, name,
492
                            std::bind(&variable::print_value, this), help);
492
                            std::bind(&variable::print_value, this), help);
493
            
493
            
494
            m_set_cmd.reg<T>(cs, name,
494
            m_set_cmd.reg<T>(cs, name,
495
                             std::bind(&variable::set_value, this, std::placeholders::_1),
495
                             std::bind(&variable::set_value, this, std::placeholders::_1),
496
                             help);
496
                             help);
497
        }
497
        }
498
    }
498
    }
499
 
499
 
500
    const variable& operator=(const T& value) { m_value = value; return *this; }
500
    const variable& operator=(const T& value) { m_value = value; return *this; }
501
 
501
 
502
    operator const T&() const { return m_value; }
502
    operator const T&() const { return m_value; }
503
 
503
 
504
    const char* get_name() const { return m_print_cmd.get_name(); }
504
    const char* get_name() const { return m_print_cmd.get_name(); }
505
    const char* get_help() const { return m_print_cmd.get_help(); }
505
    const char* get_help() const { return m_print_cmd.get_help(); }
506
 
506
 
507
private:
507
private:
508
    variable(const variable&);
508
    variable(const variable&);
509
    const variable& operator=(const variable&);
509
    const variable& operator=(const variable&);
510
 
510
 
511
    void print_value()
511
    void print_value()
512
    {
512
    {
513
        m_print_cmd.get_console()->printf("%s = %s",
513
        m_print_cmd.get_console()->printf("%s = %s",
514
            m_print_cmd.get_name(),
514
            m_print_cmd.get_name(),
515
            Console::to_string(m_value).c_str());
515
            Console::to_string(m_value).c_str());
516
    }
516
    }
517
 
517
 
518
    void set_value(const T& value)
518
    void set_value(const T& value)
519
    {
519
    {
520
        m_value = value;
520
        m_value = value;
521
        m_print_cmd.get_console()->execute(m_print_cmd.get_name());
521
        m_print_cmd.get_console()->execute(m_print_cmd.get_name());
522
    }
522
    }
523
 
523
 
524
    T m_value;
524
    T m_value;
525
 
525
 
526
    command m_print_cmd;
526
    command m_print_cmd;
527
    command m_set_cmd;
527
    command m_set_cmd;
528
};
528
};
529
 
529
 
530
}
530
}
531
 
531
 
532
#endif //__GEL_GLGRAPHICS_CONSOLE_H__
532
#endif //__GEL_GLGRAPHICS_CONSOLE_H__
533
 
533