ScummVM API documentation
lingo-object.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef DIRECTOR_LINGO_OBJECT_H
23#define DIRECTOR_LINGO_OBJECT_H
24
25#include "director/lingo/lingo.h"
26
27namespace Director {
28
30 const char *name;
31 void (*func)(int);
32 int minArgs; // -1 -- arglist
33 int maxArgs;
34 int version;
35};
36
38 const char *name; // Base file name for the Xlib file in the original
39 const char *gameId; // GameId or nullptr if applicable to all
40};
41
43public:
44 virtual ~AbstractObject() {};
45
46 virtual Common::String getName() const = 0;
47 virtual ObjectType getObjType() const = 0;
48 virtual bool isDisposed() const = 0;
49 virtual int *getRefCount() const = 0;
50 virtual void incRefCount() = 0;
51 virtual void decRefCount() = 0;
52 virtual int getInheritanceLevel() const = 0;
53
54 virtual void setName(const Common::String &name) = 0;
55 virtual void dispose() = 0;
56
57 virtual Common::String asString() = 0;
58 virtual AbstractObject *clone() = 0;
59 virtual Symbol getMethod(const Common::String &methodName) = 0;
60 virtual bool hasProp(const Common::String &propName) = 0;
61 virtual Datum getProp(const Common::String &propName) = 0;
62 virtual Common::String getPropAt(uint32 index) = 0;
63 virtual uint32 getPropCount() = 0;
64 virtual void setProp(const Common::String &propName, const Datum &value, bool force = false) = 0;
65 virtual bool hasField(int field) = 0;
66 virtual Datum getField(int field) = 0;
67 virtual void setField(int field, const Datum &value) = 0;
68};
69
70template <typename Derived>
71class Object : public AbstractObject {
72public:
73 int *_refCount;
74
75protected:
76 Object(Common::String objName) {
77 _name = objName;
78 _objType = kNoneObj;
79 _disposed = false;
80 _inheritanceLevel = 1;
81 _refCount = new int;
82 *_refCount = 0;
83 };
84
85 Object(const Object &obj) {
86 _name = obj._name;
87 _objType = obj._objType;
88 _disposed = obj._disposed;
89 _inheritanceLevel = obj._inheritanceLevel + 1;
90 _refCount = new int;
91 *_refCount = 0;
92 };
93
94public:
95 static void initMethods(const MethodProto protos[]) {
96 if (_methods) {
97 warning("Object::initMethods: Methods already initialized");
98 return;
99 }
100
101 _methods = new SymbolHash;
102 for (const MethodProto *mtd = protos; mtd->name; mtd++) {
103 if (mtd->version > g_lingo->_vm->getVersion())
104 continue;
105
106 Symbol sym;
107 sym.name = new Common::String(mtd->name);
108 sym.type = HBLTIN;
109 sym.nargs = mtd->minArgs;
110 sym.maxArgs = mtd->maxArgs;
111 sym.u.bltin = mtd->func;
112 (*_methods)[mtd->name] = sym;
113 }
114 }
115
116 static void cleanupMethods() {
117 delete _methods;
118 _methods = nullptr;
119 }
120
121 virtual ~Object() {
122 delete _refCount;
123 };
124
125 Common::String getName() const override { return _name; };
126 ObjectType getObjType() const override { return _objType; };
127 bool isDisposed() const override { return _disposed; };
128 int *getRefCount() const override { return _refCount; };
129 void incRefCount() override { *_refCount += 1; };
130 virtual void decRefCount() override {
131 *_refCount -= 1;
132 if (*_refCount <= 0)
133 delete this;
134 };
135 int getInheritanceLevel() const override { return _inheritanceLevel; };
136
137 void setName(const Common::String &name) override { _name = name; };
138 void dispose() override { _disposed = true; };
139
140 Common::String asString() override {
141 return Common::String::format("object: #%s %d %p", _name.c_str(), _inheritanceLevel, (void *)this);
142 };
143
144 AbstractObject *clone() override {
145 return new Derived(static_cast<Derived const &>(*this));
146 };
147
148 Symbol getMethod(const Common::String &methodName) override {
149 Symbol sym;
150
151 if (_disposed) {
152 warning("Method '%s' called on disposed object <%s>, returning VOID", methodName.c_str(), asString().c_str());
153 return sym;
154 }
155
156 Common::String methodId;
157 if ((_objType & (kFactoryObj | kXObj)) && methodName.hasPrefixIgnoreCase("m")) {
158 methodId = methodName.substr(1);
159 } else {
160 methodId = methodName;
161 }
162
163 if (_methods && _methods->contains(methodId)) {
164 sym = (*_methods)[methodId];
165 sym.target = this;
166 return sym;
167 }
168 if (g_lingo->_methods.contains(methodId) && (g_lingo->_methods[methodId].targetType & _objType)) {
169 sym = g_lingo->_methods[methodId];
170 sym.target = this;
171 return sym;
172 }
173
174 return sym;
175 };
176
177 bool hasProp(const Common::String &propName) override {
178 return false;
179 };
180 Datum getProp(const Common::String &propName) override {
181 return Datum();
182 };
183 Common::String getPropAt(uint32 index) override {
184 return Common::String();
185 };
186 uint32 getPropCount() override {
187 return 0;
188 };
189 void setProp(const Common::String &propName, const Datum &value, bool force = false) override {
190 return;
191 };
192 bool hasField(int field) override {
193 return false;
194 };
195 Datum getField(int field) override {
196 return Datum();
197 };
198 void setField(int field, const Datum &value) override {
199 return;
200 };
201
202protected:
203 static SymbolHash *_methods;
204 Common::String _name;
205 ObjectType _objType;
206 bool _disposed;
207 int _inheritanceLevel; // 1 for original object
208};
209
210template<typename Derived>
212
213class ScriptContext : public Object<ScriptContext> {
214public:
215 ScriptType _scriptType;
216 int _id;
217 int _scriptId;
218 uint16 _parentNumber;
219 uint16 _castLibHint;
220 Common::Array<Common::String> _functionNames; // used by cb_localcall
222 SymbolHash _functionHandlers;
223 Common::HashMap<uint32, Symbol> _eventHandlers;
224 Common::Array<Datum> _constants;
226 MethodHash _methodNames;
227 Common::SharedPtr<Node> _assemblyAST; // Optionally contains AST when we compile Lingo
228
229private:
230 friend class Cast; // clears _cast directly in ~Cast
231
232 DatumHash _properties;
233 Common::Array<Common::String> _propertyNames;
234 bool _onlyInLctxContexts = false;
235 Cast *_cast = nullptr;
236
237public:
238 ScriptContext(Common::String name, ScriptType type = kNoneScript, int id = 0, uint16 castLibHint = 0, uint16 parentNumber = 0, int scriptId = 0);
239 ScriptContext(const ScriptContext &sc);
240 ~ScriptContext() override;
241
242 Cast *getCast() const { return _cast; }
243 void setCast(Cast *cast);
244
245 bool isFactory() const { return _objType == kFactoryObj; };
246 void setFactory(bool flag) { _objType = flag ? kFactoryObj : kScriptObj; }
247
248 const Common::Array<Common::String> &getPropertyNames() const { return _propertyNames; }
249
250 void setOnlyInLctxContexts() { _onlyInLctxContexts = true; }
251 bool getOnlyInLctxContexts() { return _onlyInLctxContexts; }
252
253 Common::String asString() override;
254 Symbol getMethod(const Common::String &methodName) override;
255 bool hasProp(const Common::String &propName) override;
256 Datum getProp(const Common::String &propName) override;
257 Common::String getPropAt(uint32 index) override;
258 uint32 getPropCount() override;
259 void setProp(const Common::String &propName, const Datum &value, bool force = false) override;
260
261 Symbol define(const Common::String &name, ScriptData *code, Common::Array<Common::String> *argNames, Common::Array<Common::String> *varNames);
262
263 Common::String formatFunctionList(const char *prefix);
264};
265
266namespace LM {
267
268// predefined methods
269void m_describe(int nargs);
270void m_dispose(int nargs);
271void m_get(int nargs);
272void m_instanceRespondsTo(int nargs);
273void m_messageList(int nargs);
274void m_name(int nargs);
275void m_new(int nargs);
276void m_perform(int nargs);
277void m_put(int nargs);
278void m_respondsTo(int nargs);
279
280// window
281void m_close(int nargs);
282void m_forget(int nargs);
283void m_moveToBack(int nargs);
284void m_moveToFront(int nargs);
285void m_open(int nargs);
286
287} // End of namespace LM
288
289} // End of namespace Director
290
291#endif
Definition: ptr.h:159
Definition: str.h:59
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
String substr(size_t pos=0, size_t len=npos) const
Definition: lingo-object.h:42
Definition: cast.h:88
Definition: lingo-object.h:71
Definition: lingo-object.h:213
bool contains(const Key &key) const
Definition: hashmap.h:598
void warning(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: lingo.h:131
Definition: lingo-object.h:29
Definition: lingo.h:82
Definition: lingo-object.h:37