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