Subversion Repositories gelsvn

Rev

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

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