Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/putil/buttonRegistry.cxx

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

Generated on Fri May 2 00:43:34 2003 for Panda by doxygen1.3