forked from Source-Python-Dev-Team/Source.Python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemory_utilities.h
More file actions
244 lines (202 loc) · 7.78 KB
/
Copy pathmemory_utilities.h
File metadata and controls
244 lines (202 loc) · 7.78 KB
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/**
* =============================================================================
* Source Python
* Copyright (C) 2012-2015 Source Python Development Team. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* 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, see <http://www.gnu.org/licenses/>.
*
* As a special exception, the Source Python Team gives you permission
* to link the code of this program (as well as its derivative works) to
* "Half-Life 2," the "Source Engine," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, the Source.Python
* Development Team grants this exception to all derivative works.
*/
// ============================================================================
// >> MACROS
// ============================================================================
// The name of the attribute that is added to an exposed function.
#ifndef FUNC_INFO_NAME
#define FUNC_INFO_NAME "_func_info"
#endif
// The name of the method that is added to a class to return its pointer.
#ifndef GET_PTR_NAME
#define GET_PTR_NAME "_ptr"
#endif
// The name of the static method that is added to a class to wrap a pointer of this class.
#ifndef GET_OBJ_NAME
#define GET_OBJ_NAME "_obj"
#endif
// The name of the class attribute that contains the size of the class
#ifndef GET_SIZE_NAME
#define GET_SIZE_NAME "_size"
#endif
#ifndef _MEMORY_UTILITIES_H
#define _MEMORY_UTILITIES_H
// ============================================================================
// >> INCLUDES
// ============================================================================
// Memory
#include "memory_function_info.h"
#include "memory_pointer.h"
#include "memory_tools.h"
// ============================================================================
// >> FORWARD DECLARATIONS
// ============================================================================
object GetObjectPointer(object obj);
// ============================================================================
// >> ExtractPointer
// ============================================================================
inline CPointer* ExtractPointer(object oPtr)
{
try
{
oPtr = GetObjectPointer(oPtr);
}
catch (...)
{
PyErr_Clear();
}
CPointer* pPtr = extract<CPointer *>(oPtr);
return pPtr;
}
// ============================================================================
// >> ObjectToDataTypeVector
// ============================================================================
inline std::vector<DataType_t> ObjectToDataTypeVector(object oArgTypes)
{
std::vector<DataType_t> vecArgTypes;
for(int i=0; i < len(oArgTypes); i++)
{
vecArgTypes.push_back(extract<DataType_t>(oArgTypes[i]));
}
return vecArgTypes;
}
// ============================================================================
// >> ADD_PTR
// ============================================================================
template<class T>
CPointer* __ptr__(T* pThis)
{
return new CPointer((unsigned long) pThis);
}
// Use this macro to add this class to get_pointer_object()
#define ADD_PTR(classname) \
.def(GET_PTR_NAME, \
&__ptr__<classname>, \
manage_new_object_policy() \
)
// ============================================================================
// >> ADD_OBJ
// ============================================================================
template<class T>
T* __obj__(CPointer* pPtr)
{
return (T *) pPtr->m_ulAddr;
}
// Use this macro to add this class to make_object()
#define ADD_OBJ(classname) \
.def(GET_OBJ_NAME, \
&__obj__<classname>, \
reference_existing_object_policy() \
).staticmethod(GET_OBJ_NAME)
// ============================================================================
// >> ADD_SIZE
// ============================================================================
// Use this macro to add this class to get_size()
// Note: This must be at the end of the class definition!
#define ADD_SIZE(classname) \
.attr(GET_SIZE_NAME) = sizeof(classname);
// ============================================================================
// >> STORE_CLASS
// ============================================================================
// Use this macro to add the class to the ExposedClasses dict
#define STORE_CLASS(classname, pyname) \
extern dict g_oExposedClasses; \
g_oExposedClasses[XSTRINGIFY(classname)] = scope().attr(pyname);
// ============================================================================
// >> ADD_MEM_TOOLS_WRAPPER
// ============================================================================
#define ADD_MEM_TOOLS_WRAPPER(classname, realname) \
ADD_PTR(classname) \
ADD_OBJ(classname) \
ADD_SIZE(classname) \
STORE_CLASS(realname, converter::registry::query(typeid(classname))->m_class_object->tp_name)
// ============================================================================
// >> ADD_MEM_TOOLS
// ============================================================================
// Use this macro to add the class to the three functions
// Note: This must be at the end of the class definition!
#define ADD_MEM_TOOLS(classname) \
ADD_MEM_TOOLS_WRAPPER(classname, classname)
// ============================================================================
// >> FUNCTION INFO
// ============================================================================
/*
Macros to create class info dictionaries. The following example shows the usage:
class A
{
public:
virtual void f() = 0;
virtual void f() const = 0;
virtual void f(int x) = 0;
virtual void g() = 0;
};
BEGIN_CLASS_INFO(A)
// Start a new function info list, because "f" is overloaded
BEGIN_FUNCTION_INFO_LIST("f")
FUNCTION_INFO_OVERLOAD(void, f)
FUNCTION_INFO_CONST_OVERLOAD(void, f)
FUNCTION_INFO_OVERLOAD(void, f, int)
END_FUNCTION_INFO_LIST()
// Use this macro if there are no function overloads
FUNCTION_INFO(g)
END_CLASS_INFO()
*/
// Start a new class info dictionary
#define BEGIN_CLASS_INFO(classname) \
{ \
typedef classname functionInfoClass; \
extern dict g_oClassInfo; \
dict classInfoDict; \
if (g_oClassInfo.contains( #classname )) \
classInfoDict = extract<dict>(g_oClassInfo[ #classname ]); \
else \
g_oClassInfo[ #classname ] = classInfoDict;
// Finish a class info dictionary
#define END_CLASS_INFO() \
}
// Start a function info list
#define BEGIN_FUNCTION_INFO_LIST(name) \
{ \
list functionInfoList; \
classInfoDict[ name ] = functionInfoList;
// Finish a function info list
#define END_FUNCTION_INFO_LIST() \
}
// Requires a function address
#define ADD_FUNCTION_INFO(function) \
functionInfoList.append(ptr(GetFunctionInfo( function )));
// Use this macro if there are no function overloads
#define FUNCTION_INFO(function) \
BEGIN_FUNCTION_INFO_LIST( #function ) \
ADD_FUNCTION_INFO( &functionInfoClass::function ) \
END_FUNCTION_INFO_LIST()
// Use this macro to add a specific overloaded function
#define FUNCTION_INFO_OVERLOAD(return_type, method, ...) \
ADD_FUNCTION_INFO( GET_METHOD( return_type, functionInfoClass, method, __VA_ARGS__ ) )
// Use this macro to add a specific overloaded function which was decorated with the "const" modifier
#define FUNCTION_INFO_CONST_OVERLOAD(return_type, method, ...) \
ADD_FUNCTION_INFO( GET_CONST_METHOD( return_type, functionInfoClass, method, __VA_ARGS__ ) )
#endif // _MEMORY_UTILITIES_H