1 // -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi:tw=80:et:ts=2:sts=2
3 //
4 // -----------------------------------------------------------------------
5 //
6 // This file is part of RLVM, a RealLive virtual machine clone.
7 //
8 // -----------------------------------------------------------------------
9 //
10 // Copyright (C) 2010 Elliot Glaysher
11 //
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 3 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
25 // -----------------------------------------------------------------------
26
27 #ifndef SRC_MACHINE_GENERAL_OPERATIONS_IMPL_H_
28 #define SRC_MACHINE_GENERAL_OPERATIONS_IMPL_H_
29
30 // Implementation details of the GeneralOperations functions. This internal
31 // interface is hidden and should only be accessed through the functions
32 // exposed in general_operations.h.
33
34 // Contains details on how to get a certain object from an input
35 // RLMachine. Templates are specialized in the cc file.
36 namespace getSystemObjImpl {
37
38 template <typename RETTYPE>
39 RETTYPE& GetSystemObj(RLMachine& machine);
40
41 template <>
GetSystemObj(RLMachine & machine)42 inline RLMachine& GetSystemObj(RLMachine& machine) {
43 return machine;
44 }
45
46 // Equivalent to machine.system().
47 template <>
48 System& GetSystemObj(RLMachine& machine);
49
50 // Equivalent to machine.system().event().
51 template <>
52 EventSystem& GetSystemObj(RLMachine& machine);
53
54 // Equivalent to machine.system().graphics().
55 template <>
56 GraphicsSystem& GetSystemObj(RLMachine& machine);
57
58 // Equivalent to machine.system().text().
59 template <>
60 TextSystem& GetSystemObj(RLMachine& machine);
61
62 // Equivalent to machine.system().sound().
63 template <>
64 SoundSystem& GetSystemObj(RLMachine& machine);
65
66 // Equivalent to machine.system().graphics().cg_table().
67 template <>
68 CGMTable& GetSystemObj(RLMachine& machine);
69
70 // Equivalent to machine.system().text().GetCurrentPage().
71 template <>
72 TextPage& GetSystemObj(RLMachine& machine);
73
74 } // namespace getSystemObjImpl
75
76 namespace binderImpl {
77
78 // Binds setting an internal variable to a passed in value in from a
79 // running Reallive script.
80 template <typename OBJTYPE>
81 class Op_CallWithInt : public RLOpcode<IntConstant_T> {
82 public:
83 // The function signature for the setter function
84 typedef void (OBJTYPE::*Setter)(const int);
85
Op_CallWithInt(Setter s)86 explicit Op_CallWithInt(Setter s) : setter(s) {}
87
operator()88 virtual void operator()(RLMachine& machine, int in) override {
89 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*setter)(in);
90 }
91
92 private:
93 // The setter function to call on Op_SetToIncoming::reference when
94 // called.
95 Setter setter;
96 };
97
98 // Binds setting an internal variable to a passed in value in from a
99 // running Reallive script.
100 template <typename OBJTYPE>
101 class Op_CallWithMachineInt : public RLOpcode<IntConstant_T> {
102 public:
103 // The function signature for the setter function
104 typedef void (OBJTYPE::*Setter)(RLMachine&, const int);
105
Op_CallWithMachineInt(Setter s)106 explicit Op_CallWithMachineInt(Setter s) : setter(s) {}
107
operator()108 virtual void operator()(RLMachine& machine, int in) override {
109 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*setter)(machine, in);
110 }
111
112 private:
113 // The setter function to call on Op_SetToIncoming::reference when
114 // called.
115 Setter setter;
116 };
117
118 // Binds setting an internal variable to a passed in value in from a
119 // running Reallive script.
120 template <typename OBJTYPE>
121 class Op_CallWithMachineIntInt
122 : public RLOpcode<IntConstant_T, IntConstant_T> {
123 public:
124 // The function signature for the setter function
125 typedef void (OBJTYPE::*Setter)(RLMachine&, const int, const int);
126
Op_CallWithMachineIntInt(Setter s)127 explicit Op_CallWithMachineIntInt(Setter s) : setter(s) {}
128
operator()129 virtual void operator()(RLMachine& machine, int one, int two) override {
130 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*setter)(
131 machine, one, two);
132 }
133
134 private:
135 // The setter function to call on Op_SetToIncoming::reference when
136 // called.
137 Setter setter;
138 };
139
140 // Binds setting an internal variable to a passed in value in from a
141 // running Reallive script.
142 template <typename OBJTYPE>
143 class Op_CallWithIntInt : public RLOpcode<IntConstant_T, IntConstant_T> {
144 public:
145 // The function signature for the setter function
146 typedef void (OBJTYPE::*Setter)(const int, const int);
147
Op_CallWithIntInt(Setter s)148 explicit Op_CallWithIntInt(Setter s) : setter(s) {}
149
operator()150 virtual void operator()(RLMachine& machine, int in1, int in2) override {
151 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*setter)(in1, in2);
152 }
153
154 private:
155 // The setter function to call on Op_SetToIncoming::reference when
156 // called.
157 Setter setter;
158 };
159
160 // Binds setting an internal variable to a passed in value in from a
161 // running Reallive script.
162 template <typename OBJTYPE>
163 class Op_CallWithString : public RLOpcode<StrConstant_T> {
164 public:
165 // The function signature for the setter function
166 typedef void (OBJTYPE::*Setter)(const std::string&);
167
Op_CallWithString(Setter s)168 explicit Op_CallWithString(Setter s) : setter(s) {}
169
operator()170 virtual void operator()(RLMachine& machine, std::string incoming) override {
171 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*setter)(incoming);
172 }
173
174 private:
175 // The setter function to call on Op_CallWithString::reference
176 // when called.
177 Setter setter;
178 };
179
180 template <typename OBJTYPE>
181 class Op_CallMethod : public RLOpcode<> {
182 public:
183 // The string getter function to call
184 typedef void (OBJTYPE::*FUNCTYPE)();
185
Op_CallMethod(FUNCTYPE f)186 explicit Op_CallMethod(FUNCTYPE f) : func(f) {}
187
operator()188 virtual void operator()(RLMachine& machine) override {
189 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*func)();
190 }
191
192 private:
193 FUNCTYPE func;
194 };
195
196 // Sets an internal variable to a specific value set at compile time,
197 // and exposes this as an operation to Reallive scripts.
198 template <typename OBJTYPE, typename VALTYPE>
199 class Op_CallWithConstant : public RLOpcode<> {
200 public:
201 typedef void (OBJTYPE::*Setter)(VALTYPE);
202
Op_CallWithConstant(Setter s,VALTYPE in_val)203 Op_CallWithConstant(Setter s, VALTYPE in_val) : setter(s), value(in_val) {}
204
operator()205 virtual void operator()(RLMachine& machine) override {
206 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*setter)(value);
207 }
208
209 private:
210 Setter setter;
211 VALTYPE value;
212 };
213
214 template <typename OBJTYPE, typename VALONE, typename VALTWO>
215 class Op_CallWithConstantConstant : public RLOpcode<> {
216 public:
217 typedef void (OBJTYPE::*Setter)(VALONE, VALTWO);
218
Op_CallWithConstantConstant(Setter s,VALONE in_valone,VALTWO in_valtwo)219 Op_CallWithConstantConstant(Setter s, VALONE in_valone, VALTWO in_valtwo)
220 : setter(s), valone(in_valone), valtwo(in_valtwo) {}
221
operator()222 virtual void operator()(RLMachine& machine) override {
223 (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*setter)(valone, valtwo);
224 }
225
226 private:
227 Setter setter;
228 VALONE valone;
229 VALTWO valtwo;
230 };
231
232 template <typename RETTYPE>
233 class Op_ReturnFunctionIntValue : public RLStoreOpcode<> {
234 public:
235 typedef RETTYPE (*Getter)();
236
Op_ReturnFunctionIntValue(Getter g)237 explicit Op_ReturnFunctionIntValue(Getter g) : getter_(g) {}
238
operator()239 virtual int operator()(RLMachine& machine) override {
240 return (*getter_)();
241 }
242
243 private:
244 Getter getter_;
245 };
246
247 // Reads the value of an internal variable in a generic way using an
248 // arbitrary getter function and places it in the store register.
249 template <typename OBJTYPE, typename RETTYPE>
250 class Op_ReturnIntValue : public RLStoreOpcode<> {
251 public:
252 typedef RETTYPE (OBJTYPE::*Getter)() const;
253
Op_ReturnIntValue(Getter g)254 explicit Op_ReturnIntValue(Getter g) : getter_(g) {}
255
operator()256 virtual int operator()(RLMachine& machine) override {
257 return (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*getter_)();
258 }
259
260 private:
261 Getter getter_;
262 };
263
264 template <typename OBJTYPE, typename RETTYPE>
265 class Op_ReturnIntValueWithInt : public RLStoreOpcode<IntConstant_T> {
266 public:
267 typedef RETTYPE (OBJTYPE::*Getter)(const int) const;
268
Op_ReturnIntValueWithInt(Getter g)269 explicit Op_ReturnIntValueWithInt(Getter g) : getter_(g) {}
270
operator()271 virtual int operator()(RLMachine& machine, int one) override {
272 return (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*getter_)(one);
273 }
274
275 private:
276 Getter getter_;
277 };
278
279 template <typename OBJTYPE, typename RETTYPE>
280 class Op_ReturnIntValueWithString : public RLStoreOpcode<StrConstant_T> {
281 public:
282 typedef RETTYPE (OBJTYPE::*Getter)(const std::string&) const;
283
Op_ReturnIntValueWithString(Getter g)284 explicit Op_ReturnIntValueWithString(Getter g) : getter_(g) {}
285
operator()286 virtual int operator()(RLMachine& machine, string one) override {
287 return (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*getter_)(one);
288 }
289
290 private:
291 Getter getter_;
292 };
293
294 // Reads the value of an internal variable in a generic way using an
295 // arbitrary getter function and places it in a passed in reference.
296 template <typename OBJTYPE>
297 class Op_ReturnStringValue : public RLOpcode<StrReference_T> {
298 public:
299 // The signature of a string getter function
300 typedef const std::string& (OBJTYPE::*Getter)() const; // NOLINT
301
Op_ReturnStringValue(Getter g)302 explicit Op_ReturnStringValue(Getter g) : getter_(g) {}
303
operator()304 virtual void operator()(RLMachine& machine,
305 StringReferenceIterator dest) override {
306 *dest = (getSystemObjImpl::GetSystemObj<OBJTYPE>(machine).*getter_)();
307 }
308
309 private:
310 // The string getter function to call
311 Getter getter_;
312 };
313
314 } // namespace binderImpl
315
316 #endif // SRC_MACHINE_GENERAL_OPERATIONS_IMPL_H_
317