Leviathan  0.8.0.0
Leviathan game engine
BindHelpers.h
Go to the documentation of this file.
1 // Leviathan Game Engine
2 // Copyright (c) 2012-2017 Henri Hyyryläinen
3 #pragma once
4 // ------------------------------------ //
5 #include "Logger.h"
6 
7 #include "angelscript.h"
8 
9 #include <map>
10 #include <string>
11 
12 #define ANGELSCRIPT_REGISTERFAIL \
13  Leviathan::Logger::Get()->Error("AngelScript: Binding failed: " \
14  "file " __FILE__ " on line " + \
15  std::to_string(__LINE__)); \
16  return false;
17 
18 // Maybe this could be avoided by typedefing the right thing to size_t in angelscript
19 // initialization based on size of size_t
21 #define ANGELSCRIPT_ASSUMED_SIZE_T \
22  static_assert(sizeof(size_t) == sizeof(uint64_t), \
23  "Script register for size_t assumes it is " \
24  "equivalent to uint64_t in angelscript");
25 
26 
27 namespace Leviathan {
28 
29 // ------------------ Dynamic cast proxies ------------------ //
30 template<class From, class To>
31 To* DoReferenceCastDynamic(From* ptr)
32 {
33  // If already invalid just return it //
34  if(!ptr)
35  return nullptr;
36 
37  To* newptr = dynamic_cast<To*>(ptr);
38  if(newptr) {
39  // Add reference so script doesn't screw up with the handles //
40  newptr->AddRef();
41  }
42 
43  // Return the ptr (which might be invalid) //
44  return newptr;
45 }
46 
47 template<class From, class To>
48 To* DoReferenceCastStatic(From* ptr)
49 {
50  // If already invalid just return it //
51  if(!ptr)
52  return nullptr;
53 
54  To* newptr = static_cast<To*>(ptr);
55  if(newptr) {
56  // Add reference so script doesn't screw up with the handles //
57  newptr->AddRef();
58  }
59 
60  // Return the ptr (which might be invalid) //
61  return newptr;
62 }
63 
64 template<class From, class To>
66 {
67  // If already invalid just return it //
68  if(!ptr)
69  return nullptr;
70 
71  To* newptr = dynamic_cast<To*>(ptr);
72 
73  // Return the ptr (which might be invalid) //
74  return newptr;
75 }
76 
77 template<class From, class To>
79 {
80  // If already invalid just return it //
81  if(!ptr)
82  return nullptr;
83 
84  To* newptr = static_cast<To*>(ptr);
85 
86  // Return the ptr (which might be invalid) //
87  return newptr;
88 }
89 
90 // ------------------------------------ //
91 // Register helpers
92 #define ANGELSCRIPT_REGISTER_REF_TYPE(RegisterName, ClassName) \
93  if(engine->RegisterObjectType(RegisterName, 0, asOBJ_REF) < 0) { \
94  ANGELSCRIPT_REGISTERFAIL; \
95  } \
96  \
97  if(engine->RegisterObjectBehaviour(RegisterName, asBEHAVE_ADDREF, "void f()", \
98  asMETHOD(ClassName, AddRef), asCALL_THISCALL) < 0) { \
99  ANGELSCRIPT_REGISTERFAIL; \
100  } \
101  \
102  if(engine->RegisterObjectBehaviour(RegisterName, asBEHAVE_RELEASE, "void f()", \
103  asMETHOD(ClassName, Release), asCALL_THISCALL) < 0) { \
104  ANGELSCRIPT_REGISTERFAIL; \
105  }
106 
107 #define ANGELSCRIPT_REGISTER_ENUM_VALUE(enum, x) \
108  { \
109  if(engine->RegisterEnumValue(#enum, #x, static_cast<int>(enum ::x)) < 0) { \
110  ANGELSCRIPT_REGISTERFAIL; \
111  } \
112  }
113 
114 #define ANGELSCRIPT_REGISTER_ENUM_VALUE_WITH_NAME(enum, valuename, x) \
115  { \
116  if(engine->RegisterEnumValue(enum, valuename, static_cast<int>(x)) < 0) { \
117  ANGELSCRIPT_REGISTERFAIL; \
118  } \
119  }
120 } // namespace Leviathan
121 
122 #define ANGLESCRIPT_BASE_CLASS_CASTS(base, base_as, derived, derived_as) \
123  if(engine->RegisterObjectMethod(base_as, derived_as "@ opCast()", \
124  asFUNCTION((Leviathan::DoReferenceCastDynamic<base, derived>)), \
125  asCALL_CDECL_OBJFIRST) < 1) { \
126  ANGELSCRIPT_REGISTERFAIL; \
127  } \
128  if(engine->RegisterObjectMethod(derived_as, base_as "@ opImplCast()", \
129  asFUNCTION((Leviathan::DoReferenceCastStatic<derived, base>)), \
130  asCALL_CDECL_OBJFIRST) < 1) { \
131  ANGELSCRIPT_REGISTERFAIL; \
132  } \
133  if(engine->RegisterObjectMethod(base_as, "const " derived_as "@ opCast() const", \
134  asFUNCTION((Leviathan::DoReferenceCastDynamic<base, derived>)), \
135  asCALL_CDECL_OBJFIRST) < 1) { \
136  ANGELSCRIPT_REGISTERFAIL; \
137  } \
138  if(engine->RegisterObjectMethod(derived_as, "const " base_as "@ opImplCast() const", \
139  asFUNCTION((Leviathan::DoReferenceCastStatic<derived, base>)), \
140  asCALL_CDECL_OBJFIRST) < 1) { \
141  ANGELSCRIPT_REGISTERFAIL; \
142  }
143 
144 
145 #define ANGLESCRIPT_BASE_CLASS_CASTS_NO_REF(base, base_as, derived, derived_as) \
146  if(engine->RegisterObjectMethod(base_as, derived_as "@ opCast()", \
147  asFUNCTION((Leviathan::DoReferenceCastDynamicNoRef<base, derived>)), \
148  asCALL_CDECL_OBJFIRST) < 1) { \
149  ANGELSCRIPT_REGISTERFAIL; \
150  } \
151  if(engine->RegisterObjectMethod(derived_as, base_as "@ opImplCast()", \
152  asFUNCTION((Leviathan::DoReferenceCastStaticNoRef<derived, base>)), \
153  asCALL_CDECL_OBJFIRST) < 1) { \
154  ANGELSCRIPT_REGISTERFAIL; \
155  } \
156  if(engine->RegisterObjectMethod(base_as, "const " derived_as "@ opCast() const", \
157  asFUNCTION((Leviathan::DoReferenceCastDynamicNoRef<base, derived>)), \
158  asCALL_CDECL_OBJFIRST) < 1) { \
159  ANGELSCRIPT_REGISTERFAIL; \
160  } \
161  if(engine->RegisterObjectMethod(derived_as, "const " base_as "@ opImplCast() const", \
162  asFUNCTION((Leviathan::DoReferenceCastStaticNoRef<derived, base>)), \
163  asCALL_CDECL_OBJFIRST) < 1) { \
164  ANGELSCRIPT_REGISTERFAIL; \
165  }
166 
167 
168 #define ANGLESCRIPT_BASE_CLASS_CASTS_NO_REF_STRING(base, base_as, derived, derived_as) \
169  if(engine->RegisterObjectMethod(base_as.c_str(), (derived_as + "@ opCast()").c_str(), \
170  asFUNCTION((Leviathan::DoReferenceCastDynamicNoRef<base, derived>)), \
171  asCALL_CDECL_OBJFIRST) < 1) { \
172  ANGELSCRIPT_REGISTERFAIL; \
173  } \
174  if(engine->RegisterObjectMethod(derived_as.c_str(), (base_as + "@ opImplCast()").c_str(), \
175  asFUNCTION((Leviathan::DoReferenceCastStaticNoRef<derived, base>)), \
176  asCALL_CDECL_OBJFIRST) < 1) { \
177  ANGELSCRIPT_REGISTERFAIL; \
178  } \
179  if(engine->RegisterObjectMethod(base_as.c_str(), \
180  ("const " + derived_as + "@ opCast() const").c_str(), \
181  asFUNCTION((Leviathan::DoReferenceCastDynamicNoRef<base, derived>)), \
182  asCALL_CDECL_OBJFIRST) < 1) { \
183  ANGELSCRIPT_REGISTERFAIL; \
184  } \
185  if(engine->RegisterObjectMethod(derived_as.c_str(), \
186  ("const " + base_as + "@ opImplCast() const").c_str(), \
187  asFUNCTION((Leviathan::DoReferenceCastStaticNoRef<derived, base>)), \
188  asCALL_CDECL_OBJFIRST) < 1) { \
189  ANGELSCRIPT_REGISTERFAIL; \
190  }
To * DoReferenceCastStatic(From *ptr)
Definition: BindHelpers.h:48
To * DoReferenceCastDynamicNoRef(From *ptr)
Definition: BindHelpers.h:65
To * DoReferenceCastStaticNoRef(From *ptr)
Definition: BindHelpers.h:78
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
To * DoReferenceCastDynamic(From *ptr)
Definition: BindHelpers.h:31