1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 /* 24 * This code is based on Broken Sword 2.5 engine 25 * 26 * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer 27 * 28 * Licensed under GNU GPL v2 29 * 30 */ 31 32 #ifndef SWORD25_OBJECTREGISTRY_H 33 #define SWORD25_OBJECTREGISTRY_H 34 35 #include "common/func.h" 36 #include "common/hashmap.h" 37 #include "common/textconsole.h" 38 #include "sword25/kernel/common.h" 39 40 namespace Sword25 { 41 42 template<typename T> 43 class ObjectRegistry { 44 public: ObjectRegistry()45 ObjectRegistry() : _nextHandle(1) {} ~ObjectRegistry()46 virtual ~ObjectRegistry() {} 47 registerObject(T * objectPtr)48 uint registerObject(T *objectPtr) { 49 // Null-Pointer k�nnen nicht registriert werden. 50 if (objectPtr == 0) { 51 error("Cannot register a null pointer."); 52 return 0; 53 } 54 55 // Falls das Objekt bereits registriert wurde, wird eine Warnung ausgeben und das Handle zur�ckgeben. 56 uint handle = findHandleByPtr(objectPtr); 57 if (handle != 0) { 58 warning("Tried to register a object that was already registered."); 59 return handle; 60 } 61 // Ansonsten wird das Objekt in beide Maps eingetragen und das neue Handle zur�ckgeben. 62 else { 63 _handle2PtrMap[_nextHandle] = objectPtr; 64 _ptr2HandleMap[objectPtr] = _nextHandle; 65 66 return _nextHandle++; 67 } 68 } 69 registerObject(T * objectPtr,uint handle)70 uint registerObject(T *objectPtr, uint handle) { 71 // Null-Pointer und Null-Handle k�nnen nicht registriert werden. 72 if (objectPtr == 0 || handle == 0) { 73 error("Cannot register a null pointer or a null handle."); 74 return 0; 75 } 76 77 // Falls das Objekt bereits registriert wurde, wird ein Fehler ausgegeben und 0 zur�ckgeben. 78 uint handleTest = findHandleByPtr(objectPtr); 79 if (handleTest != 0) { 80 error("Tried to register a object that was already registered."); 81 return 0; 82 } 83 // Falls das Handle bereits vergeben ist, wird ein Fehler ausgegeben und 0 zur�ckgegeben. 84 else if (findPtrByHandle(handle) != 0) { 85 error("Tried to register a handle that is already taken."); 86 return 0; 87 } 88 // Ansonsten wird das Objekt in beide Maps eingetragen und das gew�nschte Handle zur�ckgeben. 89 else { 90 _handle2PtrMap[handle] = objectPtr; 91 _ptr2HandleMap[objectPtr] = handle; 92 93 // Falls das vergebene Handle gr��er oder gleich dem n�chsten automatische vergebenen Handle ist, wird das n�chste automatisch 94 // vergebene Handle erh�ht. 95 if (handle >= _nextHandle) 96 _nextHandle = handle + 1; 97 98 return handle; 99 } 100 } 101 deregisterObject(T * objectPtr)102 void deregisterObject(T *objectPtr) { 103 uint handle = findHandleByPtr(objectPtr); 104 105 if (handle != 0) { 106 // Registriertes Objekt aus beiden Maps entfernen. 107 _handle2PtrMap.erase(findHandleByPtr(objectPtr)); 108 _ptr2HandleMap.erase(objectPtr); 109 } else { 110 warning("Tried to remove a object that was not registered."); 111 } 112 } 113 resolveHandle(uint handle)114 T *resolveHandle(uint handle) { 115 // Zum Handle geh�riges Objekt in der Hash-Map finden. 116 T *objectPtr = findPtrByHandle(handle); 117 118 // Pointer zur�ckgeben. Im Fehlerfall ist dieser 0. 119 return objectPtr; 120 } 121 resolvePtr(T * objectPtr)122 uint resolvePtr(T *objectPtr) { 123 // Zum Pointer geh�riges Handle in der Hash-Map finden. 124 uint handle = findHandleByPtr(objectPtr); 125 126 // Handle zur�ckgeben. Im Fehlerfall ist dieses 0. 127 return handle; 128 } 129 130 protected: 131 struct ClassPointer_EqualTo { operatorClassPointer_EqualTo132 bool operator()(const T *x, const T *y) const { 133 return x == y; 134 } 135 }; 136 struct ClassPointer_Hash { operatorClassPointer_Hash137 uint operator()(const T *x) const { 138 return (uint)(x - (const T *)0); 139 } 140 }; 141 142 typedef Common::HashMap<uint32, T *> HANDLE2PTR_MAP; 143 typedef Common::HashMap<T *, uint32, ClassPointer_Hash, ClassPointer_EqualTo> PTR2HANDLE_MAP; 144 145 HANDLE2PTR_MAP _handle2PtrMap; 146 PTR2HANDLE_MAP _ptr2HandleMap; 147 uint32 _nextHandle; 148 findPtrByHandle(uint handle)149 T *findPtrByHandle(uint handle) { 150 // Zum Handle geh�rigen Pointer finden. 151 typename HANDLE2PTR_MAP::const_iterator it = _handle2PtrMap.find(handle); 152 153 // Pointer zur�ckgeben, oder, falls keiner gefunden wurde, 0 zur�ckgeben. 154 return (it != _handle2PtrMap.end()) ? it->_value : 0; 155 } 156 findHandleByPtr(T * objectPtr)157 uint findHandleByPtr(T *objectPtr) { 158 // Zum Pointer geh�riges Handle finden. 159 typename PTR2HANDLE_MAP::const_iterator it = _ptr2HandleMap.find(objectPtr); 160 161 // Handle zur�ckgeben, oder, falls keines gefunden wurde, 0 zur�ckgeben. 162 return (it != _ptr2HandleMap.end()) ? it->_value : 0; 163 } 164 }; 165 166 } // End of namespace Sword25 167 168 #endif 169