Subversion Repositories gelsvn

Rev

Rev 647 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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