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