From 61f8e6c071866e940427c7d077a5bcd4eda5d70e Mon Sep 17 00:00:00 2001
From: Hartmut Seichter <hartmut@technotecture.com>
Date: Wed, 23 Jan 2019 09:05:09 +0100
Subject: [PATCH] attempting to cleanup the scripting interface

---
 src/engine/pixwerx.cpp                        |   2 +-
 src/scripting/CMakeLists.txt                  |  23 +--
 src/scripting/include/pw/scripting/script.hpp |  26 ++-
 src/scripting/src/runtime_lua.hpp             |  64 ++++++++
 src/scripting/src/script.cpp                  |  62 +++----
 src/scripting/src/script_core.cpp             | 155 +++++++++---------
 src/scripting/src/script_core.hpp             |  17 --
 src/scripting/src/script_scene.cpp            |   7 +-
 src/scripting/src/script_scene.hpp            |  17 --
 src/scripting/src/script_system.cpp           |   4 +-
 src/scripting/src/script_system.hpp           |  17 --
 src/scripting/src/script_visual.cpp           |   3 +-
 src/scripting/src/script_visual.hpp           |  17 --
 src/scripting/src/scripting.hpp               |  22 ---
 src/scripts/tests/test_core.lua               |   6 +-
 15 files changed, 215 insertions(+), 227 deletions(-)
 create mode 100644 src/scripting/src/runtime_lua.hpp
 delete mode 100644 src/scripting/src/script_core.hpp
 delete mode 100644 src/scripting/src/script_scene.hpp
 delete mode 100644 src/scripting/src/script_system.hpp
 delete mode 100644 src/scripting/src/script_visual.hpp
 delete mode 100644 src/scripting/src/scripting.hpp

diff --git a/src/engine/pixwerx.cpp b/src/engine/pixwerx.cpp
index c59766a..7ed8e41 100644
--- a/src/engine/pixwerx.cpp
+++ b/src/engine/pixwerx.cpp
@@ -53,5 +53,5 @@ int main(int argc,const char** argv) {
 
     pw::script s;
 
-    return s.run(sout.str().c_str());
+    return s.eval(sout.str().c_str());
 }
diff --git a/src/scripting/CMakeLists.txt b/src/scripting/CMakeLists.txt
index 783a2ae..d0b4082 100644
--- a/src/scripting/CMakeLists.txt
+++ b/src/scripting/CMakeLists.txt
@@ -5,16 +5,17 @@ set(hdrs
 
 set(srcs
 	src/script.cpp
-	src/script_core.hpp
-	src/script_core.cpp
-	src/script_system.hpp
-	src/script_system.cpp
-	src/script_scene.hpp
-	src/script_scene.cpp
-        src/script_visual.hpp
-        src/script_visual.cpp
-        src/scripting.hpp
-        )
+#	src/script_core.hpp
+    src/script_core.cpp
+#	src/script_system.hpp
+    src/script_system.cpp
+#	src/script_scene.hpp
+    src/script_scene.cpp
+#	src/script_visual.hpp
+    src/script_visual.cpp
+	src/runtime_lua.hpp
+	src/runtime_lua.cpp
+	)
 
 add_library(pwscripting
 	STATIC
@@ -26,7 +27,7 @@ add_library(pwscripting
 target_include_directories(
 	pwscripting
 	PRIVATE
-        ${CMAKE_SOURCE_DIR}/src/deps/lua-5.3.5/src
+	${CMAKE_SOURCE_DIR}/src/deps/lua-5.3.5/src
 	${CMAKE_SOURCE_DIR}/src/deps/sol2-2.20.6
 	PUBLIC
 	include
diff --git a/src/scripting/include/pw/scripting/script.hpp b/src/scripting/include/pw/scripting/script.hpp
index 6bd813d..3834a0c 100644
--- a/src/scripting/include/pw/scripting/script.hpp
+++ b/src/scripting/include/pw/scripting/script.hpp
@@ -1,10 +1,30 @@
+/*
+ * Copyright (c) 1999-2019 Hartmut Seichter
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
 #ifndef PW_SCRIPTING_SCRIPT_HPP
 #define PW_SCRIPTING_SCRIPT_HPP
 
 #include <pw/core/globals.hpp>
 
-#include <string>
-
 namespace pw {
 
 class script {
@@ -13,7 +33,7 @@ public:
     script();
     ~script();
 
-    int run(const std::string& s);
+	int eval(const std::string& s);
 
 protected:
 
diff --git a/src/scripting/src/runtime_lua.hpp b/src/scripting/src/runtime_lua.hpp
new file mode 100644
index 0000000..93a925c
--- /dev/null
+++ b/src/scripting/src/runtime_lua.hpp
@@ -0,0 +1,64 @@
+#ifndef PW_SCRIPTING_RUNTIME_LUA_HPP
+#define PW_SCRIPTING_RUNTIME_LUA_HPP
+
+#include "sol/sol.hpp"
+#include <lua.hpp>
+#include <map>
+
+namespace pw {
+
+class runtime_lua {
+public:
+	typedef std::function<void(sol::state&,sol::table&)> register_function_t;
+	typedef std::map<std::string,register_function_t> register_func_list_t;
+
+	static runtime_lua& get();
+
+	register_func_list_t register_functions() { return _register_function_list; }
+
+	void add(const std::string& name,register_function_t f);
+
+protected:
+
+	runtime_lua();
+
+	register_func_list_t _register_function_list;
+
+};
+
+template<typename Derived>
+struct runtime_lua_register
+{
+	Derived& derived() { return static_cast<Derived&>(*this); }
+	const Derived& derived() const { return static_cast<const Derived&>(*this); }
+
+	runtime_lua_register()
+	{
+		printf("Test\n");
+		runtime_lua::get().add(derived().module_name(),&Derived::register_function);
+	}
+
+	static runtime_lua_register<Derived> _instance;
+};
+
+
+extern "C" {
+	typedef void (* CModuleFunction) (void);
+}
+
+struct ModuleFunctionProxy
+{
+	ModuleFunctionProxy(CModuleFunction function) { (function)(); }
+};
+
+}
+
+#define PW_RUNTIME_LUA_USE(name) \
+	extern "C" void pw_runtime_lua_##name(void) { printf("Meh!\n"); };
+
+
+#define PW_RUNTIME_LUA_REGISTER(name) \
+	extern "C" void pw_runtime_lua_##name(void); \
+	static pw::ModuleFunctionProxy proxy_##name(pw_runtime_lua_##name);
+
+#endif
diff --git a/src/scripting/src/script.cpp b/src/scripting/src/script.cpp
index 3ee1169..837cde1 100644
--- a/src/scripting/src/script.cpp
+++ b/src/scripting/src/script.cpp
@@ -1,11 +1,6 @@
 #include "pw/scripting/script.hpp"
 
-#include "scripting.hpp"
-
-//#include "script_core.hpp"
-//#include "script_system.hpp"
-//#include "script_scene.hpp"
-//#include "script_visual.hpp"
+#include "runtime_lua.hpp"
 
 #include "pw/core/debug.hpp"
 
@@ -16,24 +11,11 @@ struct script::state {
 	sol::state _state;
 	sol::table _namespace;
 
+	state();
+
 	void load_modules();
 	void load(const std::string& name);
 
-	state() {
-
-		// create global pw namespace
-		_namespace = _state.create_named_table("pw");
-
-		// add the script as a user type
-		_namespace.new_usertype<state>("script",
-									   "initialize",&state::load_modules,
-									   "load",&state::load
-									   );
-
-		// add this instance as "script"
-		_namespace.set("script",this);
-	}
-
 	int run(const std::string &s);
 
 };
@@ -45,28 +27,36 @@ int script::state::run(const std::string &s)
 
 void script::state::load(const std::string& name)
 {
-	lua_runtime::register_function_list[name](_state,_namespace);
+	runtime_lua::get().register_functions()[name](_state,_namespace);
+}
+
+script::state::state()
+{
+	// create global pw namespace
+	_namespace = _state.create_named_table("pw");
+
+
+	// add the script as a user type
+	_namespace.new_usertype<state>("script",
+								   "initialize",&state::load_modules,
+								   "load",&state::load
+								   );
+
+	// add this instance as "script"
+	_namespace.set("script",this);
+
+	debug::d() << "available " << runtime_lua::get().register_functions().size();
+
 }
 
 void script::state::load_modules() {
 
 	// open all libraries
 	_state.open_libraries();
-
-	for (auto lib_reg : lua_runtime::register_function_list) {
-		lib_reg.second(_state,_namespace);
-		debug::d() << lib_reg.first;
-	}
-
-//	script_core::load(_namespace);
-//	script_system::load(_namespace);
-//	script_scene::load(_namespace);
-//    script_visual::load(_namespace);
-
 }
 
 //
-//
+// script
 //
 
 script::script()
@@ -76,13 +66,11 @@ script::script()
 
 script::~script()
 {
-	_state = nullptr;
 }
 
-int script::run(const std::string &s)
+int script::eval(const std::string &s)
 {
 	return _state->run(s);
-
 }
 
 
diff --git a/src/scripting/src/script_core.cpp b/src/scripting/src/script_core.cpp
index 5b92b9f..d2c3051 100644
--- a/src/scripting/src/script_core.cpp
+++ b/src/scripting/src/script_core.cpp
@@ -1,5 +1,3 @@
-#include "script_core.hpp"
-
 #include "pw/core/vector.hpp"
 #include "pw/core/quaternion.hpp"
 #include "pw/core/axisangle.hpp"
@@ -9,106 +7,105 @@
 #include "pw/core/timer.hpp"
 #include "pw/core/mesh.hpp"
 
-#include "scripting.hpp"
+#include "runtime_lua.hpp"
 
 namespace pw {
 
-void lua_register_core(sol::state& lua,sol::table& ns)
-{
+struct lua_core : runtime_lua_register<lua_core> {
 
-    typedef real_t Scalar;
+	std::string module_name() const { return "core"; }
 
-    ns.set("pi",pw::pi<Scalar>());
+	void register_function(sol::state& lua,sol::table& ns)
+	{
+
+		typedef real_t Scalar;
+
+		ns.set("pi",pw::pi<Scalar>());
 
 
-	ns.new_usertype<vector3>
-			(
-				"vector3",
-				sol::constructors<vector3(),vector3(vector3::value_type,vector3::value_type,vector3::value_type)>(),
-				"x", sol::property(sol::resolve<const vector3::value_type&() const>(&vector3::x), [](vector3& v,vector3::value_type val){ v.x() = val;}),
+		ns.new_usertype<vector3>
+				(
+					"vector3",
+					sol::constructors<vector3(),vector3(vector3::value_type,vector3::value_type,vector3::value_type)>(),
+					"x", sol::property(sol::resolve<const vector3::value_type&() const>(&vector3::x), [](vector3& v,vector3::value_type val){ v.x() = val;}),
 				"y", sol::property(sol::resolve<const vector3::value_type&() const>(&vector3::y), [](vector3& v,vector3::value_type val){ v.y() = val;}),
-				"z", sol::property(sol::resolve<const vector3::value_type&() const>(&vector3::z), [](vector3& v,vector3::value_type val){ v.z() = val;}),
-				"cross",&vector3::cross,
+		"z", sol::property(sol::resolve<const vector3::value_type&() const>(&vector3::z), [](vector3& v,vector3::value_type val){ v.z() = val;}),
+		"cross",&vector3::cross,
 				"lerp",&vector3::lerp
-			);
+				);
 
 
 
-	ns.new_usertype<quaternion>
-			(
-				"quaternion",
-				sol::constructors<quaternion(), quaternion(quaternion::value_type,quaternion::value_type,quaternion::value_type,quaternion::value_type)>(),
-				"x", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::x), [](quaternion& v,quaternion::value_type val){ v.x() = val;}),
+		ns.new_usertype<quaternion>
+				(
+					"quaternion",
+					sol::constructors<quaternion(), quaternion(quaternion::value_type,quaternion::value_type,quaternion::value_type,quaternion::value_type)>(),
+					"x", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::x), [](quaternion& v,quaternion::value_type val){ v.x() = val;}),
 				"y", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::y), [](quaternion& v,quaternion::value_type val){ v.y() = val;}),
-				"z", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::z), [](quaternion& v,quaternion::value_type val){ v.z() = val;}),
-				"w", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::w), [](quaternion& v,quaternion::value_type val){ v.w() = val;}),
-				"identity",sol::readonly_property(&quaternion::identity),
+		"z", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::z), [](quaternion& v,quaternion::value_type val){ v.z() = val;}),
+		"w", sol::property(sol::resolve<const quaternion::value_type&() const>(&quaternion::w), [](quaternion& v,quaternion::value_type val){ v.w() = val;}),
+		"identity",sol::readonly_property(&quaternion::identity),
 				"dot",&quaternion::dot,
 				"inverse",sol::readonly_property(&quaternion::inverse),
 				"normalized",&quaternion::normalized,
 				"lerp",&quaternion::lerp,
 				"slerp",&quaternion::slerp
-			);
-
-	ns.new_usertype<axisangle>
-		("axisangle",
-			sol::constructors<axisangle(), axisangle(vector3,Scalar)>(),
-			"axis",sol::property(&axisangle::axis,&axisangle::set_axis),
-			"angle",sol::property(&axisangle::angle,&axisangle::set_angle)
-		);
-
-
-    ns.new_usertype<size>("size",
-                          sol::constructors<size(),size(Scalar,Scalar)>(),
-                          "width",&size::width,
-                          "height",&size::height
-                          //						   "none",sol::debug::level::none
-                          );
-
-    ns.new_usertype<point>("point",
-                           sol::constructors<point(),point(Scalar,Scalar)>(),
-                           "x",&point::x,
-                           "y",&point::y
-                           );
-
-
-    ns.new_usertype<debug>("debug",
-                           "new",sol::no_constructor,
-                           "get",&debug::get,
-                           "write",&debug::write
-                           //						   "none",sol::debug::level::none
-                           );
-
-
-    ns.new_usertype<timer>("timer",
-                           "now",sol::readonly_property(&timer::now),
-                           "elapsed",sol::readonly_property(&timer::elapsed),
-                           "reset",&timer::reset
-                           );
-
-	ns.new_usertype<mesh>
-			(
-				"mesh",
-				sol::constructors<mesh()>()
 				);
 
-//	lua["mesh"].new_enum()
-//			(
-//				"mesh",
-//				sol::constructors<mesh()>()
-//				);
-}
+		ns.new_usertype<axisangle>
+				("axisangle",
+				 sol::constructors<axisangle(), axisangle(vector3,Scalar)>(),
+				 "axis",sol::property(&axisangle::axis,&axisangle::set_axis),
+				 "angle",sol::property(&axisangle::angle,&axisangle::set_angle)
+				 );
 
-struct _register_core {
-	static _register_core& get() {
-		lua_runtime::register_function_list["core"] = lua_register_core;
-		static _register_core instance;
-		return  instance;
+
+		ns.new_usertype<size>("size",
+							  sol::constructors<size(),size(Scalar,Scalar)>(),
+							  "width",&size::width,
+							  "height",&size::height
+							  //						   "none",sol::debug::level::none
+							  );
+
+		ns.new_usertype<point>("point",
+							   sol::constructors<point(),point(Scalar,Scalar)>(),
+							   "x",&point::x,
+							   "y",&point::y
+							   );
+
+
+		ns.new_usertype<debug>("debug",
+							   "new",sol::no_constructor,
+							   "get",&debug::get,
+							   "write",&debug::write
+							   //						   "none",sol::debug::level::none
+							   );
+
+
+		ns.new_usertype<timer>("timer",
+							   "now",sol::readonly_property(&timer::now),
+							   "elapsed",sol::readonly_property(&timer::elapsed),
+							   "reset",&timer::reset
+							   );
+
+		ns.new_usertype<mesh>
+				(
+					"mesh",
+					sol::constructors<mesh()>()
+					);
+
+		//	lua["mesh"].new_enum()
+		//			(
+		//				"mesh",
+		//				sol::constructors<mesh()>()
+		//				);
 	}
+
+
 };
 
+};
+
+PW_RUNTIME_LUA_REGISTER(core)
 
 
-
-
-}
diff --git a/src/scripting/src/script_core.hpp b/src/scripting/src/script_core.hpp
deleted file mode 100644
index 458ec78..0000000
--- a/src/scripting/src/script_core.hpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef PW_SCRIPTING_PRIVATE_CORE_HPP
-#define PW_SCRIPTING_PRIVATE_CORE_HPP
-
-#include "scripting.hpp"
-
-namespace pw {
-
-struct script_core {
-
-	static void load(sol::table& ns);
-
-};
-
-
-}
-
-#endif
diff --git a/src/scripting/src/script_scene.cpp b/src/scripting/src/script_scene.cpp
index 21e6232..f68fa2c 100644
--- a/src/scripting/src/script_scene.cpp
+++ b/src/scripting/src/script_scene.cpp
@@ -1,10 +1,11 @@
-#include "script_scene.hpp"
+//#include "script_scene.hpp"
 
-#include <pw/scene/node.hpp>
+#include "pw/scene/node.hpp"
+#include "runtime_lua.hpp"
 
 namespace pw {
 
-void lua_register_scene(sol::table &ns)
+void lua_register_scene(sol::state& lua,sol::table &ns)
 {
 
 	ns.new_usertype<node>("node",
diff --git a/src/scripting/src/script_scene.hpp b/src/scripting/src/script_scene.hpp
deleted file mode 100644
index 9dc7b0d..0000000
--- a/src/scripting/src/script_scene.hpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef PW_SCRIPTING_PRIVATE_SCENE_HPP
-#define PW_SCRIPTING_PRIVATE_SCENE_HPP
-
-#include "scripting.hpp"
-
-namespace pw {
-
-//struct script_scene {
-
-//	static void load(scripting::table& ns);
-
-//};
-
-
-}
-
-#endif
diff --git a/src/scripting/src/script_system.cpp b/src/scripting/src/script_system.cpp
index 6a4551a..8160c72 100644
--- a/src/scripting/src/script_system.cpp
+++ b/src/scripting/src/script_system.cpp
@@ -1,9 +1,11 @@
-#include "script_system.hpp"
+//#include "script_system.hpp"
 
 #include "pw/system/window.hpp"
 #include "pw/system/input.hpp"
 #include "pw/system/display.hpp"
 
+#include "runtime_lua.hpp"
+
 #include "pw/core/debug.hpp"
 
 namespace pw {
diff --git a/src/scripting/src/script_system.hpp b/src/scripting/src/script_system.hpp
deleted file mode 100644
index 77ef544..0000000
--- a/src/scripting/src/script_system.hpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef PW_SCRIPTING_PRIVATE_SYSTEM_HPP
-#define PW_SCRIPTING_PRIVATE_SYSTEM_HPP
-
-#include "scripting.hpp"
-
-namespace pw {
-
-//struct script_system {
-
-//	static void load(scripting::table& ns);
-
-//};
-
-
-}
-
-#endif
diff --git a/src/scripting/src/script_visual.cpp b/src/scripting/src/script_visual.cpp
index 2eb2281..d4a79f6 100644
--- a/src/scripting/src/script_visual.cpp
+++ b/src/scripting/src/script_visual.cpp
@@ -1,8 +1,9 @@
-#include "script_visual.hpp"
 
 #include "pw/core/debug.hpp"
 #include "pw/visual/pipeline.hpp"
 
+#include "runtime_lua.hpp"
+
 namespace pw {
 
 void lua_register_visual(sol::table &ns)
diff --git a/src/scripting/src/script_visual.hpp b/src/scripting/src/script_visual.hpp
deleted file mode 100644
index b40e2d0..0000000
--- a/src/scripting/src/script_visual.hpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef PW_SCRIPTING_PRIVATE_VISUAL_HPP
-#define PW_SCRIPTING_PRIVATE_VISUAL_HPP
-
-#include "scripting.hpp"
-
-namespace pw {
-
-//struct script_visual {
-
-//    static void load(scripting::table& ns);
-
-//};
-
-
-}
-
-#endif
diff --git a/src/scripting/src/scripting.hpp b/src/scripting/src/scripting.hpp
deleted file mode 100644
index ff67368..0000000
--- a/src/scripting/src/scripting.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef PW_SCRIPTING_SCRIPTING_HPP
-#define PW_SCRIPTING_SCRIPTING_HPP
-
-#include "sol/sol.hpp"
-#include <lua.hpp>
-#include <map>
-
-namespace pw {
-
-struct lua_runtime {
-
-	typedef std::function<void(sol::state&,sol::table&)> register_function_t;
-	typedef std::map<std::string,register_function_t> register_func_list_t;
-	static register_func_list_t register_function_list;
-
-};
-
-lua_runtime::register_func_list_t lua_runtime::register_function_list = lua_runtime::register_func_list_t();
-
-}
-
-#endif
diff --git a/src/scripts/tests/test_core.lua b/src/scripts/tests/test_core.lua
index c766e7d..5658363 100644
--- a/src/scripts/tests/test_core.lua
+++ b/src/scripts/tests/test_core.lua
@@ -1,7 +1,11 @@
+--
+-- pixwerx - test - core
+--
+
 -- loading our libraries
 pw.script:initialize()
 
-print("hello pixwerx!")
+os.exit()
 
 local v1 = pw.vector3.new(3,2,1)