xoreos  0.0.5
avm.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos 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 xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <boost/bind.hpp>
26 
27 #include "src/common/error.h"
28 #include "src/common/util.h"
29 
37 
38 namespace Aurora {
39 
40 namespace ActionScript {
41 
43  _registers.resize(256);
44  _stopFlag = false;
45 
46  _variables["_global"] = ObjectPtr(new Object());
47  _variables["_root"] = ObjectPtr(new Object());
48  _variables["Object"] = ObjectPtr(new DummyFunction());
49  _variables["Object"].asObject()->setMember("registerClass", new NativeFunction(boost::bind(&AVM::registerClass, this, _1), false, false, false));
50  _variables["Object"].asObject()->setMember("prototype", ObjectPtr(new Object()));
51  _variables["Array"] = ObjectPtr(new DummyFunction());
52  _variables["Array"].asObject()->setMember("prototype", ObjectPtr(new Array()));
53  _variables["String"] = ObjectPtr(new DummyFunction());
54  _variables["String"].asObject()->setMember("prototype", ObjectPtr(new String()));
55  _variables["MovieClip"] = ObjectPtr(new DummyFunction());
56  _variables["MovieClip"].asObject()->setMember("prototype", ObjectPtr(new MovieClip()));
57  _variables["TextField"] = ObjectPtr(new DummyFunction());
58  _variables["TextField"].asObject()->setMember("prototype", ObjectPtr(new TextField()));
59 }
60 
63 }
64 
66  _fscommand = fscommand;
67 }
68 
69 void AVM::storeRegister(Variable value, byte index) {
70  _registers[index] = value;
71 }
72 
74  return _registers[index];
75 }
76 
77 void AVM::fsCommand(const Common::UString &name, const Common::UString &value) {
78  info("fsCommand(\"%s\", \"%s\")", name.c_str(), value.c_str());
79  if (_fscommand)
80  _fscommand(name, value);
81 }
82 
83 bool AVM::hasVariable(const Common::UString &name) {
84  if (_variables.find(name) != _variables.end())
85  return true;
86  if (_variables["_global"].asObject()->hasMember(name))
87  return true;
88 
89  return false;
90 }
91 
92 void AVM::setVariable(const Common::UString &name, Variable value) {
93  _variables[name] = value;
94 }
95 
97  if (_variables.find(name) != _variables.end()) {
98  return _variables[name];
99  } else if (_variables["_global"].asObject()->hasMember(name)) {
100  return _variables["_global"].asObject()->getMember(name);
101  } else {
102  _variables["_global"].asObject()->setMember(name, Variable());
103  return _variables["_global"].asObject()->getMember(name);
104  }
105 }
106 
107 Variable AVM::createNewObject(const Common::UString &name, std::vector<Variable> arguments) {
108  Variable variable = getVariable(name);
109 
110  if (!variable.isFunction())
111  throw Common::Exception("Object is not a function");
112 
113  if (!variable.asObject()->hasMember("prototype"))
114  throw Common::Exception("Object has no prototype");
115 
116  ObjectPtr newObject(new Object(variable.asObject()->getMember("prototype").asObject().get()));
117  Function *constructor = dynamic_cast<Function *>(variable.asObject().get());
118 
119  if (!constructor)
120  throw Common::Exception("Constructor is not a function");
121 
122  byte counter = 1;
123  if (constructor->getPreloadRootFlag()) {
124  storeRegister(_variables["_root"], counter);
125  counter += 1;
126  }
127  if (constructor->getPreloadThisFlag()) {
128  storeRegister(Variable(newObject), counter);
129  counter += 1;
130  }
131  if (constructor->getPreloadSuperFlag()) {
132  storeRegister(Variable(newObject->getMember("constructor")), counter);
133  counter += 1;
134  }
135 
136  for (size_t i = 0; i < arguments.size(); ++i) {
137  storeRegister(arguments[i], counter);
138  counter += 1;
139  }
140 
141  (*constructor)(*this);
142 
143  return Variable(newObject);
144 }
145 
147  _stopFlag = true;
148 }
149 
151  bool tmp = _stopFlag;
152  _stopFlag = false;
153  return tmp;
154 }
155 
156 void AVM::setReturnValue(Variable returnValue) {
157  _returnValue = returnValue;
158 }
159 
161  return _returnValue;
162 }
163 
165  Variable name = avm.getRegister(1);
166  Variable object = avm.getRegister(2);
167 
168  if (!name.isString())
169  throw Common::Exception("AVM::registerClass(): name is not a string");
170  if (!object.isObject())
171  throw Common::Exception("AVM::registerClass(): value is not an object");
172 
173  if (_registerClass)
174  _registerClass(name.asString(), object.asObject());
175 
176  return Variable();
177 }
178 
179 } // End of namespace ActionScript
180 
181 } // End of namespace Aurora
RegisterClassFunction _registerClass
Definition: avm.h:85
void setReturnValue(Variable returnValue=Variable())
Definition: avm.cpp:156
A class holding an UTF-8 string.
Definition: ustring.h:48
String implementation for actionscript.
void storeRegister(Variable value, byte index)
Definition: avm.cpp:69
boost::function< void(const Common::UString &, ObjectPtr)> RegisterClassFunction
Function for registering classes for widgets.
Definition: avm.h:43
Variable getVariable(const Common::UString &name)
Definition: avm.cpp:96
Variable registerClass(AVM &avm)
Definition: avm.cpp:164
void fsCommand(const Common::UString &name, const Common::UString &value)
fscommand is used for communicating with the host program.
Definition: avm.cpp:77
Variable createNewObject(const Common::UString &name, std::vector< Variable > arguments=std::vector< Variable >())
Definition: avm.cpp:107
Context for executing ActionScript.
Exception that provides a stack of explanations.
Definition: error.h:36
Implementation for an actionscript Array class.
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
const Common::UString & asString() const
Definition: variable.cpp:137
TextField implementation for actionscript.
Utility templates and functions.
std::map< Common::UString, Variable > _variables
Definition: avm.h:89
Function objects for ActionScript.
void info(const char *s,...)
Definition: util.cpp:69
void setFSCommandCallback(FSCommandFunction)
Set a callback for the fscommand() function.
Definition: avm.cpp:65
boost::function< Variable(const Common::UString &, const Common::UString &)> FSCommandFunction
Function for receiving fscommand().
Definition: avm.h:40
StackException Exception
Definition: error.h:59
Abstract object which is inherited by every other class.
FSCommandFunction _fscommand
Definition: avm.h:86
An action script variable.
Definition: variable.h:44
std::vector< Variable > _registers
Definition: avm.h:88
bool hasVariable(const Common::UString &name)
Check if a specific variable exists.
Definition: avm.cpp:83
Variable getReturnValue()
Definition: avm.cpp:160
boost::shared_ptr< Object > ObjectPtr
Definition: object.h:43
Variable getRegister(byte index)
Definition: avm.cpp:73
void setVariable(const Common::UString &name, Variable value)
Set a specific variable.
Definition: avm.cpp:92
Variable _returnValue
Definition: avm.h:92
MovieClip implementation for actionscript.
void setRegisterClassFunction(RegisterClassFunction)
Set a callback for the Object.registerClass() function.
Definition: avm.cpp:61
uint8 byte
Definition: types.h:209
The Action script virtual machine (AVM).
Definition: avm.h:46