00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #pragma once
00022
00030 #include <cstring>
00031 #include <string>
00032 #include <vector>
00033
00034 #include "Assert.h"
00035 #include "CommandBinding.h"
00036
00043 template<typename T>
00044 class CommandTable
00045 {
00046 typedef CommandBinding<T> Binding;
00047 typedef CommandObject<T> Object;
00049 public:
00051 CommandTable(const Binding* bindings, const unsigned int n);
00052
00054 virtual ~CommandTable();
00055
00056
00058 const Binding* getBinding(const std::string& action);
00059
00061 const Object* getObject(const std::string& action);
00062
00063
00065 const std::vector<std::string>& getCommandsVector() const;
00066
00067 private:
00068 const Binding* m_bindings;
00069 const unsigned int m_n;
00070 std::vector<std::string> m_words;
00071 };
00072
00073 template<typename T>
00074 CommandTable<T>::CommandTable(const Binding* bindings, const unsigned int n):
00075 m_bindings(bindings),
00076 m_n(n),
00077 m_words(n)
00078 {
00079
00080 for(unsigned int i = 1; i < m_n; ++i)
00081 Assert(std::strcmp(m_bindings[i - 1].m_alias, m_bindings[i].m_alias) < 0);
00082
00083 for(unsigned int i = 0; i < m_n; ++i)
00084 m_words[i] = m_bindings[i].m_alias;
00085 }
00086
00087 template<typename T>
00088 CommandTable<T>::~CommandTable()
00089 {
00090 }
00091
00092 static bool
00093 string_lt_partial(const char* a, const char* b)
00094 {
00095 while(*a && *b && *a == *b) {
00096 ++a;
00097 ++b;
00098 }
00099
00100 if(*a < *b && *b)
00101 return true;
00102
00103 return false;
00104 }
00105
00106 static bool
00107 string_eq_partial(const char* a, const char* b)
00108 {
00109 while(*a && *b && *a == *b) {
00110 ++a;
00111 ++b;
00112 }
00113
00114 if(*a == *b || !*b)
00115 return true;
00116
00117 return false;
00118 }
00119
00120 template<typename T>
00121 const CommandBinding<T>*
00122 CommandTable<T>::getBinding(const std::string& action)
00123 {
00124 const char* word = action.c_str();
00125 unsigned int left = 0;
00126 unsigned int right = m_n;
00127
00128 while(left < right) {
00129 unsigned int modus = left + (right - left) / 2;
00130 if(string_lt_partial(m_bindings[modus].m_alias, word))
00131 left = modus + 1;
00132 else
00133 right = modus;
00134 }
00135
00136 if(left < m_n)
00137 {
00138 CommandBinding<T> command = m_bindings[left];
00139 if(command.fullName())
00140 {
00141 if(!strncmp(command.m_alias, word, action.size()))
00142 return &m_bindings[left];
00143 }
00144 else
00145 {
00146 if(string_eq_partial(command.m_alias, word))
00147 return &m_bindings[left];
00148 }
00149 }
00150
00151 return NULL;
00152 }
00153
00154 template<typename T>
00155 const CommandObject<T>*
00156 CommandTable<T>::getObject(const std::string& action)
00157 {
00158 const CommandBinding<T>* b = getBinding(action);
00159 if(!b)
00160 return NULL;
00161
00162 return &b->getCommand();
00163 }
00164
00165 template<typename T>
00166 const std::vector<std::string>&
00167 CommandTable<T>::getCommandsVector() const
00168 {
00169 return m_words;
00170 }