1 /***************************************************************************
2 * Copyright (C) 2008 by Vegard Nossum *
3 * vegard.nossum@gmail.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 * @file CommandTable.h
25 * This file contains the CommandTable template.
35 #include "CommandBinding.h"
38 * This class performs lookup of input to commands.
40 * The lookup performs a binary search on the bindings table.
41 * It also checks for partial matches.
46 typedef CommandBinding
<T
> Binding
; /**< The type of a binding to a specific clsas. */
47 typedef CommandObject
<T
> Object
; /**< The type of a CommandObject of a specific class. */
50 /** Constructs a CommandTable using the specified bindings table that is of the specified size.*/
51 CommandTable(const Binding
* bindings
, const unsigned int n
);
53 /** Destructor, a noop. */
54 virtual ~CommandTable();
57 /** Performs a lookup on the specified word and returns the associated binding. */
58 const Binding
* getBinding(const std::string
& action
);
60 /** Performs a lookup on the specified word and returns the associated object. */
61 const Object
* getObject(const std::string
& action
);
64 /** Returns a list of known commands. */
65 const std::vector
<std::string
>& getCommandsVector() const;
68 const Binding
* m_bindings
; /**< The bindings we search on. */
69 const unsigned int m_n
; /**< The size of the bindings. */
70 std::vector
<std::string
> m_words
; /**< The list of known commands. */
74 CommandTable
<T
>::CommandTable(const Binding
* bindings
, const unsigned int n
):
79 /* Make sure the table is sorted. If it isn't, binary search won't work. */
80 for(unsigned int i
= 1; i
< m_n
; ++i
)
81 Assert(std::strcmp(m_bindings
[i
- 1].m_alias
, m_bindings
[i
].m_alias
) < 0);
83 for(unsigned int i
= 0; i
< m_n
; ++i
)
84 m_words
[i
] = m_bindings
[i
].m_alias
;
88 CommandTable
<T
>::~CommandTable()
93 string_lt_partial(const char* a
, const char* b
)
95 while(*a
&& *b
&& *a
== *b
) {
107 string_eq_partial(const char* a
, const char* b
)
109 while(*a
&& *b
&& *a
== *b
) {
121 const CommandBinding
<T
>*
122 CommandTable
<T
>::getBinding(const std::string
& action
)
124 const char* word
= action
.c_str();
125 unsigned int left
= 0;
126 unsigned int right
= m_n
;
128 while(left
< right
) {
129 unsigned int modus
= left
+ (right
- left
) / 2;
130 if(string_lt_partial(m_bindings
[modus
].m_alias
, word
))
138 CommandBinding
<T
> command
= m_bindings
[left
];
139 if(command
.fullName())
141 if(!strncmp(command
.m_alias
, word
, action
.size()))
142 return &m_bindings
[left
];
146 if(string_eq_partial(command
.m_alias
, word
))
147 return &m_bindings
[left
];
155 const CommandObject
<T
>*
156 CommandTable
<T
>::getObject(const std::string
& action
)
158 const CommandBinding
<T
>* b
= getBinding(action
);
162 return &b
->getCommand();
166 const std::vector
<std::string
>&
167 CommandTable
<T
>::getCommandsVector() const