Panda3D
|
00001 // Filename: buttonRegistry.cxx 00002 // Created by: drose (01Mar00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "buttonRegistry.h" 00016 #include "config_util.h" 00017 00018 #include <stdio.h> 00019 00020 // In general, we use the util_cat->info() syntax in this file 00021 // (instead of util_cat.info()), because much of this work is done at 00022 // static init time, and we must use the arrow syntax to force 00023 // initialization of the util_cat category. 00024 00025 ButtonRegistry *ButtonRegistry::_global_pointer = NULL; 00026 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: ButtonRegistry::register_button 00030 // Access: Public 00031 // Description: Registers a new ButtonHandle with the indicated name, 00032 // and if specified, the indicated ASCII equivalent. 00033 // Returns true if the button was registered, or false 00034 // it was already registered; in either case, the new 00035 // ButtonHandle is loaded into the first parameter. 00036 // 00037 // If the alias is not ButtonHandle::none(), it 00038 // indicates an alias (alternate name) for the same 00039 // button. Each button is allowed to have one alias, 00040 // and multiple different buttons can refer to the same 00041 // alias. The alias should be the more general name for 00042 // the button, for instance, shift is an alias for 00043 // lshift, but not vice-versa. 00044 // 00045 // This defines a new kind of button matching the 00046 // indicated name. The ButtonHandle can then be passed 00047 // around to devices as a button in its own right. 00048 //////////////////////////////////////////////////////////////////// 00049 bool ButtonRegistry:: 00050 register_button(ButtonHandle &button_handle, const string &name, 00051 ButtonHandle alias, char ascii_equivalent) { 00052 NameRegistry::iterator ri; 00053 ri = _name_registry.find(name); 00054 00055 if (ri == _name_registry.end()) { 00056 // The name was not already used; this is the first time this 00057 // button has been defined. 00058 00059 int index = -1; 00060 if (ascii_equivalent != '\0') { 00061 if (_handle_registry[ascii_equivalent] == (RegistryNode *)NULL) { 00062 index = ascii_equivalent; 00063 } else { 00064 util_cat->error() 00065 << "Attempt to register multiple buttons under ASCII equivalent " 00066 << ascii_equivalent << "\n"; 00067 } 00068 } 00069 00070 #ifdef NOTIFY_DEBUG 00071 // This code runs at static init time, so cannot use the 00072 // util_cat.is_spam() syntax. 00073 if (util_cat->is_spam()) { 00074 util_cat->spam() 00075 << "Registering button " << name << "\n"; 00076 } 00077 #endif 00078 00079 if (index == -1) { 00080 // It's not an ASCII equivalent; make up a new number. 00081 index = _handle_registry.size(); 00082 _handle_registry.push_back(NULL); 00083 } 00084 00085 ButtonHandle new_handle; 00086 new_handle._index = index; 00087 00088 RegistryNode *rnode = new RegistryNode(new_handle, alias, name); 00089 _handle_registry[index] = rnode; 00090 _name_registry[name] = rnode; 00091 00092 button_handle = new_handle; 00093 return true; 00094 } 00095 00096 RegistryNode *rnode = (*ri).second; 00097 nassertr(rnode->_name == (*ri).first, false); 00098 nassertr(rnode->_handle._index >= 0 && 00099 rnode->_handle._index < (int)_handle_registry.size(), false); 00100 nassertr(_handle_registry[rnode->_handle._index] == rnode, false); 00101 nassertr(rnode->_handle._index != 0, false); 00102 00103 if (button_handle != rnode->_handle) { 00104 // Hmm, we seem to have a contradictory button registration! 00105 util_cat->warning() 00106 << "Attempt to register button " << name << " more than once!\n"; 00107 00108 button_handle = rnode->_handle; 00109 } 00110 return false; 00111 } 00112 00113 //////////////////////////////////////////////////////////////////// 00114 // Function: ButtonRegistry::get_button 00115 // Access: Published 00116 // Description: Finds a ButtonHandle in the registry matching the 00117 // indicated name. If there is no such ButtonHandle, 00118 // registers a new one and returns it. 00119 //////////////////////////////////////////////////////////////////// 00120 ButtonHandle ButtonRegistry:: 00121 get_button(const string &name) { 00122 NameRegistry::const_iterator ri; 00123 ri = _name_registry.find(name); 00124 00125 if (ri != _name_registry.end()) { 00126 return (*ri).second->_handle; 00127 } 00128 00129 ButtonHandle button; 00130 register_button(button, name); 00131 return button; 00132 } 00133 00134 //////////////////////////////////////////////////////////////////// 00135 // Function: ButtonRegistry::find_ascii_button 00136 // Access: Published 00137 // Description: Finds a ButtonHandle in the registry matching the 00138 // indicated ASCII equivalent character. If there is no 00139 // such ButtonHandle, returns ButtonHandle::none(). 00140 //////////////////////////////////////////////////////////////////// 00141 ButtonHandle ButtonRegistry:: 00142 find_ascii_button(char ascii_equivalent) const { 00143 if (_handle_registry[ascii_equivalent] == (RegistryNode *)NULL) { 00144 return ButtonHandle::none(); 00145 } 00146 return _handle_registry[ascii_equivalent]->_handle; 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: ButtonRegistry::write 00151 // Access: Published 00152 // Description: 00153 //////////////////////////////////////////////////////////////////// 00154 void ButtonRegistry:: 00155 write(ostream &out) const { 00156 out << "ASCII equivalents:\n"; 00157 for (int i = 1; i < 128; i++) { 00158 if (_handle_registry[i] != (RegistryNode *)NULL) { 00159 char hex[12]; 00160 sprintf(hex, "%02x", (unsigned int)i); 00161 nassertv(strlen(hex) < 12); 00162 00163 out << " " << hex << " " << _handle_registry[i]->_name << "\n"; 00164 } 00165 } 00166 00167 out << "\nOther buttons:\n"; 00168 NameRegistry::const_iterator ri; 00169 for (ri = _name_registry.begin(); ri != _name_registry.end(); ++ri) { 00170 if (!(*ri).second->_handle.has_ascii_equivalent()) { 00171 out << " " << (*ri).second->_name; 00172 if ((*ri).second->_alias != ButtonHandle::none()) { 00173 out << " (alias " << (*ri).second->_alias << ")"; 00174 } 00175 out << "\n"; 00176 } 00177 } 00178 } 00179 00180 00181 //////////////////////////////////////////////////////////////////// 00182 // Function: ButtonRegistry::Constructor 00183 // Access: Private 00184 // Description: 00185 //////////////////////////////////////////////////////////////////// 00186 ButtonRegistry:: 00187 ButtonRegistry() { 00188 // We'll start by filling up the handle_registry with 128 entries 00189 // for ButtonHandle::none(), as well as for all the ASCII 00190 // equivalents. 00191 00192 _handle_registry.reserve(128); 00193 int i; 00194 for (i = 0; i < 128; i++) { 00195 _handle_registry.push_back(NULL); 00196 } 00197 } 00198 00199 //////////////////////////////////////////////////////////////////// 00200 // Function: ButtonRegistry::init_global_pointer 00201 // Access: Private, Static 00202 // Description: Constructs the ButtonRegistry object for the first 00203 // time. 00204 //////////////////////////////////////////////////////////////////// 00205 void ButtonRegistry:: 00206 init_global_pointer() { 00207 _global_pointer = new ButtonRegistry; 00208 } 00209 00210 00211 //////////////////////////////////////////////////////////////////// 00212 // Function: ButtonRegistry::look_up 00213 // Access: Private 00214 // Description: 00215 //////////////////////////////////////////////////////////////////// 00216 ButtonRegistry::RegistryNode *ButtonRegistry:: 00217 look_up(ButtonHandle handle) const { 00218 nassertr(handle._index != 0, NULL); 00219 00220 if (handle._index < 0 || 00221 handle._index >= (int)_handle_registry.size()) { 00222 util_cat->fatal() 00223 << "Invalid ButtonHandle index " << handle._index 00224 << "! Is memory corrupt?\n"; 00225 return (RegistryNode *)NULL; 00226 } 00227 00228 return _handle_registry[handle._index]; 00229 }