Subversion Repositories gelsvn

Rev

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

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