Pārlūkot izejas kodu

Implement first idea for a state wrapper

Ole 10 gadi atpakaļ
vecāks
revīzija
68c1baeb6b
4 mainītis faili ar 182 papildinājumiem un 1 dzēšanām
  1. 1 1
      Makefile
  2. 28 0
      examples/state.cpp
  3. 1 0
      lib/luwra.hpp
  4. 152 0
      lib/luwra/state.hpp

+ 1 - 1
Makefile

@@ -12,7 +12,7 @@ TEST_OBJS       := $(TEST_SRCS:%.cpp=$(TEST_DIR)/%.o)
 
 # Example artifacts
 EXAMPLE_DIR     := examples
-EXAMPLE_SRCS    := types.cpp stack.cpp functions.cpp usertypes.cpp
+EXAMPLE_SRCS    := types.cpp stack.cpp functions.cpp usertypes.cpp state.cpp
 EXAMPLE_DEPS    := $(EXAMPLE_SRCS:%.cpp=$(EXAMPLE_DIR)/%.d)
 EXAMPLE_OBJS    := $(EXAMPLE_SRCS:%.cpp=$(EXAMPLE_DIR)/%.out)
 

+ 28 - 0
examples/state.cpp

@@ -0,0 +1,28 @@
+#include <lua.hpp>
+#include <luwra.hpp>
+
+#include <string>
+#include <iostream>
+
+using namespace luwra;
+
+int main() {
+	StateWrapper state;
+	state.loadStandardLibrary();
+
+	state["foo"] = 1337;
+
+	int r = state.runString(
+		"foo = foo + 1"
+	);
+
+	if (r != LUA_OK) {
+		std::cerr << read<std::string>(state, -1) << std::endl;
+		return 1;
+	}
+
+	int value = state["foo"];
+	std::cout << value << std::endl;
+
+	return 0;
+}

+ 1 - 0
lib/luwra.hpp

@@ -6,5 +6,6 @@
 #include "luwra/stack.hpp"
 #include "luwra/functions.hpp"
 #include "luwra/usertypes.hpp"
+#include "luwra/state.hpp"
 
 #endif

+ 152 - 0
lib/luwra/state.hpp

@@ -0,0 +1,152 @@
+/* Luwra
+ * Minimal-overhead Lua wrapper for C++
+ *
+ * Copyright (C) 2015, Ole Krüger <ole@vprsm.de>
+ */
+
+#ifndef LUWRA_STATEWRAPPER_H_
+#define LUWRA_STATEWRAPPER_H_
+
+#include "common.hpp"
+#include "stack.hpp"
+
+#include <string>
+#include <utility>
+
+LUWRA_NS_BEGIN
+
+/**
+ * Accessor for an entry in the global namespace
+ */
+struct GlobalAccessor {
+	State* state;
+	std::string key;
+
+	inline
+	GlobalAccessor(State* state, const std::string& key): state(state), key(key) {}
+
+	/**
+	 * Assign a new value.
+	 */
+	template <typename V> inline
+	GlobalAccessor& set(V value) {
+		assert(1 == push(state, value));
+		lua_setglobal(state, key.c_str());
+		return *this;
+	}
+
+	/**
+	 * Shortcut for `set()`
+	 */
+	template <typename V> inline
+	GlobalAccessor& operator =(V value) {
+		return set<V>(value);
+	}
+
+	/**
+	 * Retrieve the associated value.
+	 */
+	template <typename V> inline
+	V get() {
+		lua_getglobal(state, key.c_str());
+
+		V instance = read<V>(state, -1);
+		lua_pop(state, 1);
+
+		return instance;
+	}
+
+	/**
+	 * Shortcut for `get()`
+	 */
+	template <typename V> inline
+	operator V() {
+		return get<V>();
+	}
+};
+
+/**
+ * Wrapper for a Lua state
+ */
+struct StateWrapper {
+	State* state;
+	bool close_state;
+
+	/**
+	 * Operate on a foreign state instance.
+	 */
+	inline
+	StateWrapper(State* state): state(state), close_state(false) {}
+
+	/**
+	 * Create a new Lua state.
+	 */
+	inline
+	StateWrapper(): state(luaL_newstate()), close_state(true) {}
+
+	inline
+	~StateWrapper() {
+		if (close_state)
+			lua_close(state);
+	}
+
+	inline
+	operator State*() {
+		return state;
+	}
+
+	inline
+	void loadStandardLibrary() {
+		luaL_openlibs(state);
+	}
+
+	/**
+	 * Retrieve a global value.
+	 */
+	template <typename V> inline
+	V getGlobal(const std::string& key) const {
+		lua_getglobal(state, key.c_str());
+
+		V instance = read<V>(state, -1);
+		lua_pop(state, 1);
+
+		return instance;
+	}
+
+	/**
+	 * Assign a global value.
+	 */
+	template <typename V> inline
+	void setGlobal(const std::string& key, V value) const {
+		assert(1 == push(state, value));
+		lua_setglobal(state, key.c_str());
+	}
+
+	/**
+	 * Create an accessor to a global value.
+	 */
+	inline
+	GlobalAccessor operator [](const std::string& key) const {
+		return GlobalAccessor(state, key);
+	}
+
+	/**
+	 * Execute a piece of code.
+	 */
+	inline
+	int runString(const std::string& code) {
+		return luaL_dostring(state, code.c_str());
+	}
+
+	/**
+	 * Execute a file.
+	 */
+	inline
+	int runFile(const std::string& filepath) {
+		return luaL_dofile(state, filepath.c_str());
+	}
+};
+
+LUWRA_NS_END
+
+#endif