Subversion Repositories gelsvn

Rev

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

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