src/Core/Command/CommandTable.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008 by Vegard Nossum                                   *
00003  *   vegard.nossum@gmail.com                                               *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 3 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
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         /* Make sure the table is sorted. If it isn't, binary search won't work. */
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 }

Generated for UnsignedByte by  doxygen 1.5.3
SourceForge.net Logo