~ubuntu-branches/ubuntu/vivid/rlvm/vivid-proposed

« back to all changes in this revision

Viewing changes to test/script_machine/script_world.cc

  • Committer: Package Import Robot
  • Author(s): Ying-Chun Liu (PaulLiu)
  • Date: 2014-10-22 03:24:19 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20141022032419-yqxls9ky4n1w811n
Tags: 0.14-1
* New upstream release
* Bump Standards-Version to 3.9.6: nothing needs to be changed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 
2
// vi:tw=80:et:ts=2:sts=2
 
3
//
 
4
// -----------------------------------------------------------------------
 
5
//
 
6
// This file is part of RLVM, a RealLive virtual machine clone.
 
7
//
 
8
// -----------------------------------------------------------------------
 
9
//
 
10
// Copyright (C) 2008 Elliot Glaysher
 
11
//
 
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.
 
16
//
 
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.
 
21
//
 
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
// -----------------------------------------------------------------------
 
26
 
 
27
#include "script_machine/script_world.h"
 
28
 
 
29
#include <iostream>
 
30
#include <typeinfo>
 
31
#include <sstream>
 
32
#include <string>
 
33
#include <boost/filesystem/operations.hpp>
 
34
#include <boost/filesystem/path.hpp>
 
35
 
 
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"
 
45
 
 
46
extern "C" {
 
47
#include "lua.h"
 
48
#include "lualib.h"
 
49
#include "lauxlib.h"
 
50
}
 
51
 
 
52
#include <luabind/luabind.hpp>
 
53
 
 
54
using namespace std;
 
55
using namespace luabind;
 
56
namespace fs = boost::filesystem;
 
57
 
 
58
ScriptWorld::ScriptWorld() {
 
59
  L = lua_open();
 
60
  luaopen_base(L);
 
61
  luaopen_string(L);
 
62
  luaopen_table(L);
 
63
  InitializeLuabind(L);
 
64
 
 
65
  luabind::globals(L)["World"] = this;
 
66
}
 
67
 
 
68
ScriptWorld::~ScriptWorld() { lua_close(L); }
 
69
 
 
70
void ScriptWorld::LoadToplevelFile(const std::string& lua_file) {
 
71
  script_dir_ = fs::path(lua_file).branch_path();
 
72
 
 
73
  if (luaL_dofile(L, lua_file.c_str())) {
 
74
    ostringstream oss;
 
75
    oss << "Error while running script: " << lua_file << " ("
 
76
        << lua_tostring(L, -1) << ")";
 
77
    throw std::runtime_error(oss.str());
 
78
  }
 
79
}
 
80
 
 
81
void ScriptWorld::Import(const std::string& file_name) {
 
82
  fs::path script_path(script_dir_ / file_name);
 
83
 
 
84
  if (!fs::exists(script_path)) {
 
85
    ostringstream oss;
 
86
    oss << "Could not read script file: " << script_path;
 
87
    throw std::runtime_error(oss.str());
 
88
  }
 
89
 
 
90
  if (luaL_dofile(L, script_path.string().c_str())) {
 
91
    ostringstream oss;
 
92
    oss << "Error while running script: " << script_path << " ("
 
93
        << lua_tostring(L, -1) << ")";
 
94
    throw std::runtime_error(oss.str());
 
95
  }
 
96
}
 
97
 
 
98
std::string ScriptWorld::Regname() const {
 
99
  ScriptMachine* machine =
 
100
      luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
 
101
  if (machine) {
 
102
    return machine->system().Regname();
 
103
  } else {
 
104
    throw std::logic_error("No machine!?");
 
105
  }
 
106
}
 
107
 
 
108
void ScriptWorld::SetDecisionList(luabind::object table) {
 
109
  decisions_.clear();
 
110
  for (luabind::iterator itr(table), end; itr != end; ++itr) {
 
111
    boost::optional<std::string> v = object_cast_nothrow<std::string>(*itr);
 
112
 
 
113
    if (v) {
 
114
      decisions_.push_back(*v);
 
115
    }
 
116
  }
 
117
 
 
118
  ScriptMachine* machine =
 
119
      luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
 
120
  if (machine) {
 
121
    machine->SetDecisionList(decisions_);
 
122
  }
 
123
}
 
124
 
 
125
void ScriptWorld::Error(const std::string& error_message) {
 
126
  ScriptMachine* machine =
 
127
      luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
 
128
  if (machine)
 
129
    machine->Halt();
 
130
 
 
131
  cerr << "ERROR: " << error_message << endl;
 
132
}
 
133
 
 
134
void ScriptWorld::AddHandler(int scene, int lineNo, luabind::object handler) {
 
135
  ScriptMachine* machine =
 
136
      luabind::object_cast<ScriptMachine*>(luabind::globals(L)["Machine"]);
 
137
  if (machine) {
 
138
    machine->AddLineAction(
 
139
        scene, lineNo, boost::bind(&ScriptWorld::RunHandler, handler));
 
140
  }
 
141
}
 
142
 
 
143
void ScriptWorld::SetDecisionHandler(luabind::object obj) {
 
144
  luabind::globals(L)["DecisionHandler"] = obj;
 
145
}
 
146
 
 
147
std::string ScriptWorld::MakeDecision(
 
148
    const std::vector<std::string>& decisions) {
 
149
  luabind::object handler = luabind::globals(L)["DecisionHandler"];
 
150
 
 
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]);
 
155
    }
 
156
 
 
157
    luabind::object ret = handler(table);
 
158
    if (type(ret) == LUA_TSTRING) {
 
159
      return object_cast<std::string>(ret);
 
160
    }
 
161
  }
 
162
 
 
163
  return "";
 
164
}
 
165
 
 
166
void ScriptWorld::InitializeMachine(ScriptMachine& machine) {
 
167
  luabind::globals(L)["Machine"] = &machine;
 
168
  luabind::globals(L)["System"] = &(machine.system());
 
169
}
 
170
 
 
171
// static
 
172
void ScriptWorld::InitializeLuabind(lua_State* L) {
 
173
  using namespace luabind;
 
174
 
 
175
  open(L);
 
176
  module(L)[
 
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),
 
185
    register_utility(),
 
186
    register_machine(),
 
187
    register_system(),
 
188
    register_event_system(),
 
189
    register_graphics_system(),
 
190
    register_graphics_object()
 
191
  ];
 
192
}
 
193
 
 
194
// static
 
195
void ScriptWorld::RunHandler(luabind::object handler) {
 
196
  try {
 
197
    luabind::call_function<void>(handler);
 
198
  }
 
199
  catch (const luabind::error& e) {
 
200
    lua_State* state = e.state();
 
201
    std::cerr << lua_tostring(state, -1) << endl;
 
202
  }
 
203
}