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) 2006 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 
28 #ifndef SRC_MODULES_MODULE_OBJ_H_
29 #define SRC_MODULES_MODULE_OBJ_H_
30 
31 // Reusable function objects for the GraphicsObject system.
32 
33 #include "machine/rloperation.h"
34 #include "utilities/lazy_array.h"
35 
36 class GraphicsObject;
37 
38 // -----------------------------------------------------------------------
39 
40 void EnsureIsParentObject(GraphicsObject& parent, int size);
41 
42 GraphicsObject& GetGraphicsObject(RLMachine& machine, RLOperation* op, int obj);
43 
44 LazyArray<GraphicsObject>& GetGraphicsObjects(RLMachine& machine,
45                                               RLOperation* op);
46 
47 void SetGraphicsObject(RLMachine& machine,
48                        RLOperation* op,
49                        int obj,
50                        GraphicsObject& gobj);
51 
52 // -----------------------------------------------------------------------
53 
54 // Special adapter to make any of obj* and objBg* operation structs
55 // into an objRange* or objRangeBg* struct.
56 //
57 // We extract the first two expression pieces from the incoming
58 // command and assume that they are integers and are the bounds on the
59 // object number. We then construct a set of parameters to pass to the
60 // real implementation.
61 //
62 // This is certainly not the most efficient way to do it, but it cuts
63 // down on a duplicated operation struct for each obj* and objBg*
64 // function, alowing us to just use this adapter with the already
65 // defined operations.
66 class ObjRangeAdapter : public RLOp_SpecialCase {
67  public:
68   explicit ObjRangeAdapter(RLOperation* in);
69   virtual ~ObjRangeAdapter();
70 
71   virtual void operator()(RLMachine& machine,
72                           const libreallive::CommandElement& ff) final;
73 
74  private:
75   std::unique_ptr<RLOperation> handler;
76 };
77 
78 // Mapping function for a MappedRLModule which turns operation op into
79 // a ranged operation.
80 //
81 // The wrapper takes ownership of the incoming op pointer, and the
82 // caller takes ownership of the resultant RLOperation.
83 RLOperation* RangeMappingFun(RLOperation* op);
84 
85 // -----------------------------------------------------------------------
86 
87 // An adapter that changes a normal object operation into one that operates on
88 // an object's child objects.
89 class ChildObjAdapter : public RLOp_SpecialCase {
90  public:
91   explicit ChildObjAdapter(RLOperation* in);
92   virtual ~ChildObjAdapter();
93 
94   virtual void operator()(RLMachine& machine,
95                           const libreallive::CommandElement& ff) final;
96 
97  private:
98   std::unique_ptr<RLOperation> handler;
99 };
100 
101 RLOperation* ChildObjMappingFun(RLOperation* op);
102 
103 // -----------------------------------------------------------------------
104 
105 // An adapter that ranges over children of a certain parent object.
106 class ChildObjRangeAdapter : public RLOp_SpecialCase {
107  public:
108   explicit ChildObjRangeAdapter(RLOperation* in);
109   virtual ~ChildObjRangeAdapter();
110 
111   virtual void operator()(RLMachine& machine,
112                           const libreallive::CommandElement& ff) final;
113 
114  private:
115   std::unique_ptr<RLOperation> handler;
116 };
117 
118 // The combo form of rangeMappingFun and childObjMappingFun. Used for
119 // operations that start with (parent object num, first child num, last child
120 // num).
121 RLOperation* ChildRangeMappingFun(RLOperation* op);
122 
123 // -----------------------------------------------------------------------
124 
125 // Calls a function on an object.
126 //
127 // NOTE: This does *not* call mark_object_state_as_dirty(), like the rest of
128 // these adapters.
129 class Obj_CallFunction : public RLOpcode<IntConstant_T> {
130  public:
131   typedef void (GraphicsObject::*Function)();
132 
133   explicit Obj_CallFunction(Function f);
134   virtual ~Obj_CallFunction();
135 
136   virtual void operator()(RLMachine& machine, int buf) final;
137 
138  private:
139   Function function_;
140 };
141 
142 // -----------------------------------------------------------------------
143 
144 // Specialized form of Op_SetToIncomingInt to deal with looking up
145 // object from the Obj* helper templates; since a lot of Object
146 // related functions simply call a setter.
147 //
148 // This template magic saves having to write out 25 - 30 operation
149 // structs.
150 class Obj_SetOneIntOnObj : public RLOpcode<IntConstant_T, IntConstant_T> {
151  public:
152   // The function signature for the setter function
153   typedef void (GraphicsObject::*Setter)(const int);
154 
155   explicit Obj_SetOneIntOnObj(Setter s);
156   virtual ~Obj_SetOneIntOnObj();
157 
158   virtual void operator()(RLMachine& machine, int buf, int incoming) final;
159 
160  private:
161   // The setter function to call on Op_SetToIncoming::reference when
162   // called.
163   Setter setter;
164 };
165 
166 // -----------------------------------------------------------------------
167 
168 // Specialized form of Op_SetToIncomingInt to deal with looking up object from
169 // the Obj* helper templates; since a lot of Object related functions simply
170 // call a setter.
171 class Obj_SetTwoIntOnObj
172     : public RLOpcode<IntConstant_T, IntConstant_T, IntConstant_T> {
173  public:
174   typedef void (GraphicsObject::*Setter)(const int);
175 
176   Obj_SetTwoIntOnObj(Setter one, Setter two);
177   virtual ~Obj_SetTwoIntOnObj();
178 
179   virtual void operator()(RLMachine& machine,
180                           int buf,
181                           int incoming_one,
182                           int incoming_two) final;
183 
184  private:
185   Setter setter_one_;
186   Setter setter_two_;
187 };
188 
189 // -----------------------------------------------------------------------
190 
191 class Obj_SetRepnoIntOnObj
192     : public RLOpcode<IntConstant_T, IntConstant_T, IntConstant_T> {
193  public:
194   typedef void (GraphicsObject::*Setter)(const int, const int);
195 
196   Obj_SetRepnoIntOnObj(Setter setter);
197   virtual ~Obj_SetRepnoIntOnObj();
198 
199   virtual void operator()(RLMachine& machine,
200                           int buf,
201                           int idx,
202                           int val) final;
203 
204  private:
205   Setter setter;
206 };
207 
208 #endif  // SRC_MODULES_MODULE_OBJ_H_
209