1
// -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
// vi:tw=80:et:ts=2:sts=2
4
// -----------------------------------------------------------------------
6
// This file is part of RLVM, a RealLive virtual machine clone.
8
// -----------------------------------------------------------------------
10
// Copyright (C) 2008 Elliot Glaysher
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.
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.
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
// -----------------------------------------------------------------------
27
#include "script_machine/script_world.h"
33
#include <boost/filesystem/operations.hpp>
34
#include <boost/filesystem/path.hpp>
36
#include "modules/module_sel.h"
37
#include "script_machine/luabind_event_system.h"
38
#include "script_machine/luabind_graphics_object.h"
39
#include "script_machine/luabind_graphics_system.h"
40
#include "script_machine/luabind_machine.h"
41
#include "script_machine/luabind_system.h"
42
#include "script_machine/luabind_utility.h"
43
#include "script_machine/script_machine.h"
44
#include "systems/base/system.h"
52
#include <luabind/luabind.hpp>
55
using namespace luabind;
56
namespace fs = boost::filesystem;
58
ScriptWorld::ScriptWorld() {
65
luabind::globals(L)["World"] = this;
68
ScriptWorld::~ScriptWorld() { lua_close(L); }
70
void ScriptWorld::LoadToplevelFile(const std::string& lua_file) {
71
script_dir_ = fs::path(lua_file).branch_path();
73
if (luaL_dofile(L, lua_file.c_str())) {
75
oss << "Error while running script: " << lua_file << " ("
76
<< lua_tostring(L, -1) << ")";
77
throw std::runtime_error(oss.str());
81
void ScriptWorld::Import(const std::string& file_name) {
82
fs::path script_path(script_dir_ / file_name);
84
if (!fs::exists(script_path)) {
86
oss << "Could not read script file: " << script_path;
87
throw std::runtime_error(oss.str());
90
if (luaL_dofile(L, script_path.string().c_str())) {
92
oss << "Error while running script: " << script_path << " ("
93
<< lua_tostring(L, -1) << ")";
94
throw std::runtime_error(oss.str());
98
std::string ScriptWorld::Regname() const {
99
ScriptMachine* machine =
100
luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
102
return machine->system().Regname();
104
throw std::logic_error("No machine!?");
108
void ScriptWorld::SetDecisionList(luabind::object table) {
110
for (luabind::iterator itr(table), end; itr != end; ++itr) {
111
boost::optional<std::string> v = object_cast_nothrow<std::string>(*itr);
114
decisions_.push_back(*v);
118
ScriptMachine* machine =
119
luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
121
machine->SetDecisionList(decisions_);
125
void ScriptWorld::Error(const std::string& error_message) {
126
ScriptMachine* machine =
127
luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
131
cerr << "ERROR: " << error_message << endl;
134
void ScriptWorld::AddHandler(int scene, int lineNo, luabind::object handler) {
135
ScriptMachine* machine =
136
luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
138
machine->AddLineAction(
139
scene, lineNo, boost::bind(&ScriptWorld::RunHandler, handler));
143
void ScriptWorld::SetDecisionHandler(luabind::object obj) {
144
luabind::globals(L)["DecisionHandler"] = obj;
147
std::string ScriptWorld::MakeDecision(
148
const std::vector<std::string>& decisions) {
149
luabind::object handler = luabind::globals(L)["DecisionHandler"];
151
if (type(handler) == LUA_TFUNCTION) {
152
object table = newtable(L);
153
for (int i = 0; i < decisions.size(); ++i) {
154
settable(table, i, decisions[i]);
157
luabind::object ret = handler(table);
158
if (type(ret) == LUA_TSTRING) {
159
return object_cast<std::string>(ret);
166
void ScriptWorld::InitializeMachine(ScriptMachine& machine) {
167
luabind::globals(L)["Machine"] = &machine;
168
luabind::globals(L)["System"] = &(machine.system());
172
void ScriptWorld::InitializeLuabind(lua_State* L) {
173
using namespace luabind;
177
// High level interface
178
class_<ScriptWorld>("World")
179
.def("import", &ScriptWorld::Import)
180
.def("regname", &ScriptWorld::Regname)
181
.def("setDecisionList", &ScriptWorld::SetDecisionList)
182
.def("error", &ScriptWorld::Error)
183
.def("addHandler", &ScriptWorld::AddHandler)
184
.def("setDecisionHandler", &ScriptWorld::SetDecisionHandler),
188
register_event_system(),
189
register_graphics_system(),
190
register_graphics_object()
195
void ScriptWorld::RunHandler(luabind::object handler) {
197
luabind::call_function<void>(handler);
199
catch (const luabind::error& e) {
200
lua_State* state = e.state();
201
std::cerr << lua_tostring(state, -1) << endl;