ScummVM API documentation
win_hand.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 #ifndef BAGEL_MFC_WIN_HAND_H
23 #define BAGEL_MFC_WIN_HAND_H
24 
25 #include "common/hashmap.h"
26 #include "bagel/mfc/afxwin.h"
27 
28 namespace Bagel {
29 namespace MFC {
30 
31 class CGdiObject;
32 class CDC;
33 
35  bool operator()(const void *x, const void *y) const {
36  return x == y;
37  }
38 };
39 
40 struct VoidPtr_Hash {
41  uint operator()(const void *x) const {
42  return (intptr)x;
43  }
44 };
45 
46 template<typename T>
47 struct HandleTraits;
48 
49 // Specialize for CGdiObject
50 template<>
52  static HANDLE &GetHandle(CGdiObject &obj) {
53  return *(HANDLE *)&obj.m_hObject;
54  }
55 };
56 
57 // Specialize for CDC
58 template<>
59 struct HandleTraits<CDC> {
60  static HANDLE &GetHandle(CDC &obj) {
61  return *(HANDLE *)&obj.m_hDC;
62  }
63 };
64 
65 template<class T>
66 class CHandleMap {
67 public:
68  typedef Common::HashMap<void *, T *,
69  VoidPtr_Hash, VoidPtr_EqualTo> CMapPtrToPtr;
70 
71 private:
72  CMapPtrToPtr _permanentMap;
73  CMapPtrToPtr _temporaryMap;
74 
75 public:
76  ~CHandleMap() {
77  DeleteTemp();
78  }
79 
80  T *FromHandle(HANDLE h) {
81  if (h == nullptr)
82  return nullptr;
83 
84  // Check for permanent object, and return if present
85  T *pObject = LookupPermanent(h);
86  if (pObject != nullptr)
87  return pObject;
88  else if ((pObject = LookupTemporary(h)) != nullptr) {
89  assert(HandleTraits<T>::GetHandle(*pObject) == h ||
90  HandleTraits<T>::GetHandle(*pObject) == nullptr);
91 
92  HandleTraits<T>::GetHandle(*pObject) = h;
93  return pObject;
94  }
95 
96  // This wasn't created by us, so create a temporary one.
97  T *pTemp = (T *)T::CreateObject();
98  assert(pTemp);
99 
100  _temporaryMap[h] = pTemp;
101 
102  // Now set the handle in the object and return it
103  HandleTraits<T>::GetHandle(*pTemp) = h;
104  return pTemp;
105  }
106 
107  void DeleteTemp() {
108  for (auto &entry : _temporaryMap) {
109  HANDLE h = entry._key;
110  T *pTemp = entry._value;
111 
112  // Zero out the handle
113  assert(HandleTraits<T>::GetHandle(*pTemp) == h ||
114  HandleTraits<T>::GetHandle(*pTemp) == nullptr);
115  HandleTraits<T>::GetHandle(*pTemp) = nullptr;
116 
117  delete pTemp;
118  }
119 
120  _temporaryMap.clear();
121  }
122 
123  void SetPermanent(HANDLE h, T *permOb) {
124  assert(!LookupPermanent(h));
125  _permanentMap[(void *)h] = permOb;
126  }
127 
128  void RemoveHandle(HANDLE h) {
129  _permanentMap.erase((void *)h);
130  }
131 
132  inline T *LookupPermanent(HANDLE h) const {
133  return _permanentMap.contains((void *)h) ?
134  _permanentMap[(void *)h] : nullptr;
135  }
136 
137  inline T *LookupTemporary(HANDLE h) const {
138  return _temporaryMap.contains((void *)h) ?
139  _temporaryMap[(void *)h] : nullptr;
140  }
141 };
142 
143 } // namespace MFC
144 } // namespace Bagel
145 
146 #endif
Definition: afxwin.h:1934
Definition: win_hand.h:34
Definition: afxwin.h:491
Definition: win_hand.h:40
Definition: hashmap.h:85
Definition: win_hand.h:47
Definition: afxwin.h:27
Definition: afxwin.h:708