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 
27 namespace Director {
28 
29 struct MethodProto {
30  const char *name;
31  void (*func)(int);
32  int minArgs; // -1 -- arglist
33  int maxArgs;
34  int version;
35 };
36 
37 struct XlibFileDesc {
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 
43 public:
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 bool 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 bool setField(int field, const Datum &value) = 0;
68 };
69 
70 template <typename Derived>
71 class Object : public AbstractObject {
72 public:
73  int *_refCount;
74 
75 protected:
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 
94 public:
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  bool setProp(const Common::String &propName, const Datum &value, bool force = false) override {
190  return false;
191  };
192  bool hasField(int field) override {
193  return false;
194  };
195  Datum getField(int field) override {
196  return Datum();
197  };
198  bool setField(int field, const Datum &value) override {
199  return false;
200  };
201 
202 protected:
203  static SymbolHash *_methods;
204  Common::String _name;
205  ObjectType _objType;
206  bool _disposed;
207  int _inheritanceLevel; // 1 for original object
208 };
209 
210 template<typename Derived>
212 
213 class ScriptContext : public Object<ScriptContext> {
214 public:
215  ScriptType _scriptType;
216  int _id;
217  Common::Array<Common::String> _functionNames; // used by cb_localcall
219  SymbolHash _functionHandlers;
220  Common::HashMap<uint32, Symbol> _eventHandlers;
221  Common::Array<Datum> _constants;
223  MethodHash _methodNames;
224  Common::SharedPtr<Node> _assemblyAST; // Optionally contains AST when we compile Lingo
225 
226 private:
227  DatumHash _properties;
228  Common::Array<Common::String> _propertyNames;
229  bool _onlyInLctxContexts = false;
230 
231 public:
232  ScriptContext(Common::String name, ScriptType type = kNoneScript, int id = 0);
233  ScriptContext(const ScriptContext &sc);
234  ~ScriptContext() override;
235 
236  bool isFactory() const { return _objType == kFactoryObj; };
237  void setFactory(bool flag) { _objType = flag ? kFactoryObj : kScriptObj; }
238 
239  void setOnlyInLctxContexts() { _onlyInLctxContexts = true; }
240  bool getOnlyInLctxContexts() { return _onlyInLctxContexts; }
241 
242  Common::String asString() override;
243  Symbol getMethod(const Common::String &methodName) override;
244  bool hasProp(const Common::String &propName) override;
245  Datum getProp(const Common::String &propName) override;
246  Common::String getPropAt(uint32 index) override;
247  uint32 getPropCount() override;
248  bool setProp(const Common::String &propName, const Datum &value, bool force = false) override;
249 
250  Symbol define(const Common::String &name, ScriptData *code, Common::Array<Common::String> *argNames, Common::Array<Common::String> *varNames);
251 
252  Common::String formatFunctionList(const char *prefix);
253 };
254 
255 namespace LM {
256 
257 // predefined methods
258 void m_describe(int nargs);
259 void m_dispose(int nargs);
260 void m_get(int nargs);
261 void m_instanceRespondsTo(int nargs);
262 void m_messageList(int nargs);
263 void m_name(int nargs);
264 void m_new(int nargs);
265 void m_perform(int nargs);
266 void m_put(int nargs);
267 void m_respondsTo(int nargs);
268 
269 // window
270 void m_close(int nargs);
271 void m_forget(int nargs);
272 void m_moveToBack(int nargs);
273 void m_moveToFront(int nargs);
274 void m_open(int nargs);
275 
276 } // End of namespace LM
277 
278 } // End of namespace Director
279 
280 #endif
Definition: lingo.h:81
Definition: str.h:59
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
void warning(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
Definition: lingo-object.h:37
Definition: archive.h:35
Definition: lingo-object.h:71
Definition: lingo-object.h:29
String substr(size_t pos=0, size_t len=npos) const
Definition: lingo.h:130
bool contains(const Key &key) const
Definition: hashmap.h:594
Definition: lingo-object.h:42
Definition: ptr.h:159
Definition: lingo-object.h:213