ScummVM API documentation
objectregistry.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 /*
23  * This code is based on Broken Sword 2.5 engine
24  *
25  * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
26  *
27  * Licensed under GNU GPL v2
28  *
29  */
30 
31 #ifndef SWORD25_OBJECTREGISTRY_H
32 #define SWORD25_OBJECTREGISTRY_H
33 
34 #include "common/func.h"
35 #include "common/hashmap.h"
36 #include "common/textconsole.h"
37 #include "sword25/kernel/common.h"
38 
39 namespace Sword25 {
40 
41 template<typename T>
43 public:
44  ObjectRegistry() : _nextHandle(1) {}
45  virtual ~ObjectRegistry() {}
46 
47  uint registerObject(T *objectPtr) {
48  // Null-Pointer können nicht registriert werden.
49  if (objectPtr == 0) {
50  error("Cannot register a null pointer.");
51  return 0;
52  }
53 
54  // Falls das Objekt bereits registriert wurde, wird eine Warnung ausgeben und das Handle zurückgeben.
55  uint handle = findHandleByPtr(objectPtr);
56  if (handle != 0) {
57  warning("Tried to register a object that was already registered.");
58  return handle;
59  }
60  // Ansonsten wird das Objekt in beide Maps eingetragen und das neue Handle zurückgeben.
61  else {
62  _handle2PtrMap[_nextHandle] = objectPtr;
63  _ptr2HandleMap[objectPtr] = _nextHandle;
64 
65  return _nextHandle++;
66  }
67  }
68 
69  uint registerObject(T *objectPtr, uint handle) {
70  // Null-Pointer und Null-Handle können nicht registriert werden.
71  if (objectPtr == 0 || handle == 0) {
72  error("Cannot register a null pointer or a null handle.");
73  return 0;
74  }
75 
76  // Falls das Objekt bereits registriert wurde, wird ein Fehler ausgegeben und 0 zurückgeben.
77  uint handleTest = findHandleByPtr(objectPtr);
78  if (handleTest != 0) {
79  error("Tried to register a object that was already registered.");
80  return 0;
81  }
82  // Falls das Handle bereits vergeben ist, wird ein Fehler ausgegeben und 0 zurückgegeben.
83  else if (findPtrByHandle(handle) != 0) {
84  error("Tried to register a handle that is already taken.");
85  return 0;
86  }
87  // Ansonsten wird das Objekt in beide Maps eingetragen und das gewünschte Handle zurückgeben.
88  else {
89  _handle2PtrMap[handle] = objectPtr;
90  _ptr2HandleMap[objectPtr] = handle;
91 
92  // Falls das vergebene Handle größer oder gleich dem nächsten automatische vergebenen Handle ist, wird das nächste automatisch
93  // vergebene Handle erhöht.
94  if (handle >= _nextHandle)
95  _nextHandle = handle + 1;
96 
97  return handle;
98  }
99  }
100 
101  void deregisterObject(T *objectPtr) {
102  uint handle = findHandleByPtr(objectPtr);
103 
104  if (handle != 0) {
105  // Registriertes Objekt aus beiden Maps entfernen.
106  _handle2PtrMap.erase(findHandleByPtr(objectPtr));
107  _ptr2HandleMap.erase(objectPtr);
108  } else {
109  warning("Tried to remove a object that was not registered.");
110  }
111  }
112 
113  T *resolveHandle(uint handle) {
114  // Zum Handle gehöriges Objekt in der Hash-Map finden.
115  T *objectPtr = findPtrByHandle(handle);
116 
117  // Pointer zurückgeben. Im Fehlerfall ist dieser 0.
118  return objectPtr;
119  }
120 
121  uint resolvePtr(T *objectPtr) {
122  // Zum Pointer gehöriges Handle in der Hash-Map finden.
123  uint handle = findHandleByPtr(objectPtr);
124 
125  // Handle zurückgeben. Im Fehlerfall ist dieses 0.
126  return handle;
127  }
128 
129 protected:
131  bool operator()(const T *x, const T *y) const {
132  return x == y;
133  }
134  };
136  uint operator()(const T *x) const {
137  return *(uint *)&x;
138  }
139  };
140 
143 
144  HANDLE2PTR_MAP _handle2PtrMap;
145  PTR2HANDLE_MAP _ptr2HandleMap;
146  uint32 _nextHandle;
147 
148  T *findPtrByHandle(uint handle) {
149  // Zum Handle gehörigen Pointer finden.
150  typename HANDLE2PTR_MAP::const_iterator it = _handle2PtrMap.find(handle);
151 
152  // Pointer zurückgeben, oder, falls keiner gefunden wurde, 0 zurückgeben.
153  return (it != _handle2PtrMap.end()) ? it->_value : 0;
154  }
155 
156  uint findHandleByPtr(T *objectPtr) {
157  // Zum Pointer gehöriges Handle finden.
158  typename PTR2HANDLE_MAP::const_iterator it = _ptr2HandleMap.find(objectPtr);
159 
160  // Handle zurückgeben, oder, falls keines gefunden wurde, 0 zurückgeben.
161  return (it != _ptr2HandleMap.end()) ? it->_value : 0;
162  }
163 };
164 
165 } // End of namespace Sword25
166 
167 #endif
void warning(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: console.h:27
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
void erase(iterator entry)
Definition: hashmap.h:708
Definition: objectregistry.h:130
Definition: objectregistry.h:135
Definition: objectregistry.h:42