Skip to content

Commit

Permalink
ACTIONSCRIPT: Add variable and object class
Browse files Browse the repository at this point in the history
  • Loading branch information
Nostritius authored and DrMcCoy committed Jun 13, 2018
1 parent 308b8fe commit 8970296
Show file tree
Hide file tree
Showing 5 changed files with 488 additions and 0 deletions.
86 changes: 86 additions & 0 deletions src/aurora/actionscript/object.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/* xoreos - A reimplementation of BioWare's Aurora engine
*
* xoreos is the legal property of its developers, whose names
* can be found in the AUTHORS file distributed with this source
* distribution.
*
* xoreos is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* xoreos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xoreos. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file
* Abstract object which is inherited by every other class.
*/

#include <boost/weak_ptr.hpp>

#include "src/common/error.h"

#include "src/aurora/actionscript/object.h"
#include "src/aurora/actionscript/avm.h"
#include "src/aurora/actionscript/function.h"

namespace Aurora {

namespace ActionScript {

Object::Object() {
}

Object::Object(Object *object) {
_members = object->_members;
}

Object::~Object() {
}

bool Object::hasMember(Common::UString id) {
return _members.find(id) != _members.end();
}

Variable Object::getMember(Common::UString id) {
if (_members.find(id) != _members.end())
return _members[id];
else {
_members.insert(std::make_pair(id, ObjectPtr(new Object)));
return _members[id];
}
}

void Object::setMember(Common::UString id, Variable member) {
_members[id] = member;
}

Variable Object::call(Common::UString function, AVM &avm) {
if (!hasMember(function))
throw Common::Exception("object has no member %s", function.c_str());

if (!getMember(function).isFunction())
throw Common::Exception("%s is no method", function.c_str());

Function *f = reinterpret_cast<Function *>(getMember(function).asObject().get());

byte counter = 1;
if (f->preloadThisFlag()) {
avm.storeRegister(shared_from_this(), counter);
counter += 1;
}

avm.setReturnValue();
(*f)(avm);
return avm.getReturnValue();
}

} // End of namespace ActionScript

} // End of namespace Aurora
68 changes: 68 additions & 0 deletions src/aurora/actionscript/object.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* xoreos - A reimplementation of BioWare's Aurora engine
*
* xoreos is the legal property of its developers, whose names
* can be found in the AUTHORS file distributed with this source
* distribution.
*
* xoreos is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* xoreos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xoreos. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file
* Abstract object which is inherited by every other class.
*/

#ifndef AURORA_ACTIONSCRIPT_OBJECT_H
#define AURORA_ACTIONSCRIPT_OBJECT_H

#include <map>

#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

#include "src/common/ustring.h"

#include "src/aurora/actionscript/variable.h"
#include "src/aurora/actionscript/avm.h"

namespace Aurora {

namespace ActionScript {

class AVM;
class Object;

typedef boost::shared_ptr<Object> ObjectPtr;

class Object : public boost::enable_shared_from_this<Object> {
public:
Object();
Object(Object *object);
virtual ~Object();

bool hasMember(Common::UString);

Variable getMember(Common::UString);
void setMember(Common::UString, Variable);

Variable call(Common::UString, AVM &avm);

private:
std::map<Common::UString, Variable> _members;
};

} // End of namespace ActionScript

} // End of namespace Aurora

#endif // AURORA_ACTIONSCRIPT_OBJECT_H
4 changes: 4 additions & 0 deletions src/aurora/actionscript/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ noinst_LTLIBRARIES += src/aurora/actionscript/libactionscript.la
src_aurora_actionscript_libactionscript_la_SOURCES =

src_aurora_actionscript_libactionscript_la_SOURCES += \
src/aurora/actionscript/object.h \
src/aurora/actionscript/variable.h \
src/aurora/actionscript/types.h \
$(EMPTY)

src_aurora_actionscript_libactionscript_la_SOURCES += \
src/aurora/actionscript/object.cpp \
src/aurora/actionscript/variable.cpp \
$(EMPTY)
226 changes: 226 additions & 0 deletions src/aurora/actionscript/variable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
/* xoreos - A reimplementation of BioWare's Aurora engine
*
* xoreos is the legal property of its developers, whose names
* can be found in the AUTHORS file distributed with this source
* distribution.
*
* xoreos is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* xoreos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xoreos. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file
* A variable used in the execution context.
*/

#include "src/aurora/actionscript/variable.h"
#include "src/aurora/actionscript/object.h"
#include "src/aurora/actionscript/function.h"

namespace Aurora {

namespace ActionScript {

Variable::Variable() : _type(kTypeUndefined) {
}

Variable::Variable(const Common::UString &value) : _type(kTypeString) {
_value.string = value;
}

Variable::Variable(double value) : _type(kTypeNumber) {
_value.number = value;
}

Variable::Variable(unsigned int value) : _type(kTypeNumber) {
_value.number = value;
}

Variable::Variable(bool value) : _type(kTypeBoolean) {
_value.boolean = value;
}

Variable::Variable(ObjectPtr value) : _type(kTypeObject) {
_value.object = value;
}

Variable::Variable(const Variable &variable) {
_type = variable._type;

switch (variable._type) {
case kTypeObject:
_value.object = variable._value.object;
break;
case kTypeString:
_value.string = variable._value.string;
break;
case kTypeBoolean:
_value.boolean = variable._value.boolean;
break;
case kTypeNumber:
_value.number = variable._value.number;
break;
default:
_type = variable._type;
}
}

Variable::~Variable() {
}

bool Variable::isUndefined() {
return _type == kTypeUndefined;
}

bool Variable::isObject() {
return _type == kTypeObject;
}

bool Variable::isString() {
return _type == kTypeString;
}

bool Variable::isNumber() {
return _type == kTypeNumber;
}

bool Variable::isFunction() {
return _type == kTypeObject && dynamic_cast<ScriptedFunction *>(_value.object.get());
}

double Variable::asNumber() {
switch (_type) {
case kTypeNumber:
return _value.number;
case kTypeBoolean:
return _value.boolean ? 1 : 0;
default:
return 0;
}
}

ObjectPtr Variable::asObject() {
if (_type == kTypeUndefined) {
_type = kTypeObject;
_value.object = ObjectPtr(new Object());
}
return _value.object;
}

const Common::UString &Variable::asString() {
return _value.string;
}

bool Variable::asBoolean() {
if (_type == kTypeNumber)
return _value.number != 0;
else if (_type == kTypeBoolean)
return _value.boolean;
else if (_type == kTypeObject)
return static_cast<bool>(_value.object.get());
else
return false;
}

void Variable::operator=(Variable v) {
_type = v._type;
switch (_type) {
case kTypeString:
_value.string = v._value.string;
break;
case kTypeObject:
_value.object = v._value.object;
break;
case kTypeNumber:
_value.number = v._value.number;
break;
case kTypeBoolean:
_value.boolean = v._value.boolean;
break;
default:
_type = v._type;
}
}

bool Variable::operator!() {
switch (_type) {
case kTypeNumber:
return !_value.number;
case kTypeBoolean:
return !_value.boolean;
default:
return true;
}
}

Variable Variable::operator&&(Variable v) {
if (v._type == kTypeNumber && _type == kTypeNumber)
return v.asNumber() && asNumber();
else
return false;
}

Variable Variable::operator||(Variable v) {
if (v._type == kTypeNumber && _type == kTypeNumber)
return v.asNumber() || asNumber();
else
return false;
}

Variable Variable::operator==(Variable v) {
if (_type != v._type)
return false;

switch (_type) {
case kTypeNumber:
return v._value.number == _value.number;
default:
return false;
}
}

Variable Variable::operator<(Aurora::ActionScript::Variable v) {
if (v._type == kTypeNumber && _type == kTypeNumber)
return asNumber() < v.asNumber();
else
return false;
}

Variable Variable::operator-(Variable v) {
if (v._type == kTypeNumber && _type == kTypeNumber)
return asNumber() - v.asNumber();
else
return 0.0;
}

Variable Variable::operator+(Variable v) {
if (v._type == kTypeNumber && _type == kTypeNumber)
return asNumber() + v.asNumber();
else
return 0.0;
}

Variable Variable::operator*(Variable v) {
return asNumber() * v.asNumber();
}

Variable Variable::operator/(Variable v) {
return asNumber() / v.asNumber();
}

Variable Variable::operator++() {
return asNumber() + 1;
}

} // End of namespace ActionScript

} // End of namespace Aurora

0 comments on commit 8970296

Please sign in to comment.