summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-05-20 14:11:40 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2011-05-20 14:11:40 +0200
commit3bb33734a92e86024488adf88dc2a368c8c952b2 (patch)
treeaee8ab7832b7fef021668d94cbaf7d21d6c9c839
parent7b22d822f9871222fbbe401c9c79d6a624d21331 (diff)
Basic lua implementation.
-rw-r--r--.gitignore2
-rw-r--r--SConstruct6
-rw-r--r--gui.cpp20
-rw-r--r--gui.h9
-rw-r--r--scene.cpp9
-rw-r--r--scene.h4
-rw-r--r--scripting.cpp61
-rw-r--r--scripting.h30
-rw-r--r--scripting/SConscript22
-rw-r--r--scripting/test.cpp11
-rw-r--r--scripting/test.h8
11 files changed, 174 insertions, 8 deletions
diff --git a/.gitignore b/.gitignore
index 088042e..0097867 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,5 @@
/map
*.dll
*.exe
+/scripting/tolua_*
+/scripting/*.pkg
diff --git a/SConstruct b/SConstruct
index c4e9247..962ac29 100644
--- a/SConstruct
+++ b/SConstruct
@@ -8,7 +8,7 @@ AddOption('--release', action = 'store_true')
AddOption('--profiling', action = 'store_true')
env.Append(CPPPATH = ['.'])
-env.Append(LIBS = ['GL', 'GLU', 'noise', 'boost_filesystem'])
+env.Append(LIBS = ['GL', 'GLU', 'noise', 'boost_filesystem', 'tolua++', 'lua'])
env.ParseConfig('sdl-config --cflags --libs')
env.ParseConfig('pkg-config --cflags --libs SDL_image')
env.ParseConfig('pkg-config --cflags --libs ftgl')
@@ -24,6 +24,8 @@ if GetOption('profiling'):
Export('env')
-env.Program('foo', Glob('*.cpp') + ['noiseutils/noiseutils.cpp'] + Glob('widgets/*.cpp'))
+env.SConscript('scripting/SConscript')
+
+env.Program('foo', Glob('*.cpp') + ['noiseutils/noiseutils.cpp'] + Glob('widgets/*.cpp') + Glob('scripting/*.cpp'))
# vim: syn=python
diff --git a/gui.cpp b/gui.cpp
index 2303470..ed53cb4 100644
--- a/gui.cpp
+++ b/gui.cpp
@@ -68,7 +68,9 @@ bool GUI::showing() {
/* ConsoleWindow */
-ConsoleWindow::ConsoleWindow() {
+ConsoleWindow::ConsoleWindow(Lua *lua) {
+ this->lua = lua;
+
WindowManager& wmgr(WindowManager::getSingleton());
wnd = wmgr.loadWindowLayout("console.layout");
@@ -128,7 +130,21 @@ void ConsoleWindow::handle_input() {
if(!s.size())
return;
- FormattedListboxTextItem *item = new FormattedListboxTextItem(String((utf8*)s.c_str()), HTF_WORDWRAP_LEFT_ALIGNED);
+ add_line(s);
+
+ try {
+ lua->dostring(s);
+ } catch(LuaError& e) {
+ add_line(e.what());
+ }
+}
+
+void ConsoleWindow::add_line(const std::string& line) {
+ add_line(line.c_str());
+}
+
+void ConsoleWindow::add_line(const char *line) {
+ FormattedListboxTextItem *item = new FormattedListboxTextItem(String((utf8*)line), HTF_WORDWRAP_LEFT_ALIGNED);
listbox->addItem(item);
listbox->ensureItemIsVisible(item);
}
diff --git a/gui.h b/gui.h
index 9e769f5..b770ed0 100644
--- a/gui.h
+++ b/gui.h
@@ -1,6 +1,8 @@
#ifndef GUI_H
#define GUI_H
+#include "scripting.h"
+
// TODO: Remove temporary workaround for CEGUI + GCC 4.6
#include <cstddef>
#include <CEGUI.h>
@@ -29,6 +31,8 @@ class ConsoleWindow : public GUI {
CEGUI::Window *editbox;
CEGUI::Listbox *listbox;
+ Lua *lua;
+
bool clicked(const CEGUI::EventArgs& e);
bool keydown(const CEGUI::EventArgs& e);
@@ -36,10 +40,13 @@ class ConsoleWindow : public GUI {
void handle_input();
public:
- ConsoleWindow();
+ ConsoleWindow(Lua *lua);
virtual ~ConsoleWindow();
virtual void update();
+
+ void add_line(const std::string& line);
+ void add_line(const char *line);
};
class RaiseWindow : public GUI {
diff --git a/scene.cpp b/scene.cpp
index e179a3b..352893e 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -4,6 +4,7 @@
#include <SDL_image.h>
#include <boost/format.hpp>
+#include <boost/bind.hpp>
#include "gl.h"
@@ -55,13 +56,19 @@ Scene::Scene() {
font = new FTTextureFont("fonts/VeraMono.ttf");
font->FaceSize(10);
+ lua = new Lua();
+
GUI::init();
- console = new ConsoleWindow();
+ console = new ConsoleWindow(lua);
console->hide();
+
+ void (ConsoleWindow::*add_line)(const char*) = &ConsoleWindow::add_line;
+ lua->set_log_func(boost::bind(add_line, console, _1));
}
Scene::~Scene() {
+ delete lua;
if(tool)
delete tool;
if(terrain)
diff --git a/scene.h b/scene.h
index 89a5ec0..7d68583 100644
--- a/scene.h
+++ b/scene.h
@@ -7,6 +7,7 @@
#include "shader.h"
#include "gui.h"
#include "tool.h"
+#include "scripting.h"
#include <FTGL/ftgl.h>
@@ -20,6 +21,7 @@ class Scene {
GUI *gui;
Tool *tool;
ConsoleWindow *console;
+ Lua *lua;
bool running;
bool grid;
@@ -37,8 +39,6 @@ class Scene {
int sx, sy;
GLShaderProgram terrain_program;
- //GLVertexShader terrain_vertex;
- //GLFragmentShader terrain_fragment;
GLuint grass_texture, rock_texture, soil_texture, marker_texture;
diff --git a/scripting.cpp b/scripting.cpp
new file mode 100644
index 0000000..ed671a2
--- /dev/null
+++ b/scripting.cpp
@@ -0,0 +1,61 @@
+#include "scripting.h"
+
+#include "tolua++.h"
+#include "scripting/tolua_test.h"
+
+#include <boost/algorithm/string/join.hpp>
+
+#include <iostream>
+#include <list>
+
+Lua::Lua() {
+ L = luaL_newstate();
+ luaL_openlibs(L);
+ tolua_test_open(L);
+
+ /* store a pointer to 'this' in the lua state */
+ lua_pushlightuserdata(L, this);
+ lua_setglobal(L, "lua_instance");
+}
+
+Lua::~Lua() {
+ lua_close(L);
+}
+
+void Lua::set_log_func(boost::function<void (const char*)> log_func) {
+ this->log_func = log_func;
+ log_func("Lua::set_log_func() called");
+}
+
+void Lua::print(const char *s) {
+ if(log_func)
+ log_func(s);
+ else
+ std::cout << s << std::endl;
+}
+
+void Lua::dostring(std::string s) {
+ int before = lua_gettop(L);
+ int err = luaL_dostring(L, s.c_str());
+ if(err == 1) {
+ std::string s= lua_tostring(L, -1);
+ lua_pop(L, 1);
+ throw(LuaError(s));
+ } else {
+ int after = lua_gettop(L);
+ std::list<std::string> vals;
+ for(int i = before; i < after; i++) {
+ const char *s = lua_tostring(L, -1);
+ std::string str;
+ if(s == NULL) {
+ str = lua_typename(L, lua_type(L, -1));
+ } else {
+ str = s;
+ }
+ vals.push_front(str);
+ lua_pop(L, 1);
+ }
+
+ this->print(boost::algorithm::join(vals, ",").c_str());
+ }
+}
diff --git a/scripting.h b/scripting.h
new file mode 100644
index 0000000..d14aa3c
--- /dev/null
+++ b/scripting.h
@@ -0,0 +1,30 @@
+#ifndef SCRIPTING_H
+#define SCRIPTING_H
+
+#include <lua.hpp>
+#include <boost/function.hpp>
+
+#include <string>
+#include <stdexcept>
+
+class LuaError : public std::runtime_error {
+ public:
+ LuaError(const std::string& s) : std::runtime_error(s) {};
+};
+
+class Lua {
+ protected:
+ lua_State *L;
+ boost::function<void (const char*)> log_func;
+
+ public:
+ Lua();
+ virtual ~Lua();
+
+ void set_log_func(boost::function<void (const char*)> log_func);
+ void print(const char *s);
+
+ void dostring(std::string s);
+};
+
+#endif
diff --git a/scripting/SConscript b/scripting/SConscript
new file mode 100644
index 0000000..eaf9f21
--- /dev/null
+++ b/scripting/SConscript
@@ -0,0 +1,22 @@
+Import('env')
+
+def tolua_generator(source, target, env, for_signature):
+ name = str(source[0]).rsplit('/', 1)[-1].rsplit('.' , 1)[0]
+ return 'tolua++ -o %s -H %s -n %s %s' % (target[1], target[2], name, source[0])
+
+def tolua_emitter(target, source, env):
+ target.append('tolua_%s.cpp' % target[0])
+ target.append('tolua_%s.h' % target[0])
+ return target, source
+
+tolua_bld = Builder(
+ generator = tolua_generator,
+ emitter = tolua_emitter,
+ src_suffix = '.pkg',
+)
+
+env.Append(BUILDERS = {'tolua': tolua_bld})
+
+env.tolua('test')
+
+# vim: syn=python
diff --git a/scripting/test.cpp b/scripting/test.cpp
new file mode 100644
index 0000000..1a378b7
--- /dev/null
+++ b/scripting/test.cpp
@@ -0,0 +1,11 @@
+#include "scripting/test.h"
+#include "scripting.h"
+
+#include <iostream>
+
+void print(lua_State *L, const char *s) {
+ lua_getglobal(L, "lua_instance");
+ Lua *lua = static_cast<Lua*>(lua_touserdata(L, -1));
+ lua_pop(L, 1);
+ lua->print(s);
+}
diff --git a/scripting/test.h b/scripting/test.h
new file mode 100644
index 0000000..48f560e
--- /dev/null
+++ b/scripting/test.h
@@ -0,0 +1,8 @@
+#ifndef TEST_H
+#define TEST_H
+
+#include <lua.hpp>
+
+void print(lua_State *L, const char *s);
+
+#endif