More abstraction for scripting languages
This commit is contained in:
		
							parent
							
								
									db160c2de4
								
							
						
					
					
						commit
						e99b623fec
					
				| @ -20,29 +20,17 @@ void Input::Use(Window *window){ | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Input::HandleKeys(Window *window, int keys, int code, int action, int mods) { | void Input::HandleKeys(Window *window, int keys, int code, int action, int mods) { | ||||||
| #ifdef LUA_SCRIPTING |   for (KeyHandler keyHandler : instance->keyHandlers) { | ||||||
|   lua_State *L = (lua_State*) glfwGetWindowUserPointer(window); |     keyHandler(window, keys, code, action, mods); | ||||||
|   lua_getglobal(L, "onkey"); |   } | ||||||
|   lua_pushinteger(L, keys); |  | ||||||
|   lua_pushinteger(L, code); |  | ||||||
|   lua_pushinteger(L, action); |  | ||||||
|   lua_pushinteger(L, mods); |  | ||||||
|   lua_call(L, 4, 0); |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Input::HandleMousePosition(Window *window, double xpos, double ypos) { | void Input::HandleMousePosition(Window *window, double xpos, double ypos) { | ||||||
|   double relx = xpos - instance->lastx; |   double relx = xpos - instance->lastx; | ||||||
|   double rely = ypos - instance->lasty; |   double rely = ypos - instance->lasty; | ||||||
| #ifdef LUA_SCRIPTING |   for (MousePositionHandler mousePositionHandler : instance->mousePositionHandlers) { | ||||||
|   lua_State *L = (lua_State*) glfwGetWindowUserPointer(window); |     mousePositionHandler(window, xpos, ypos, relx, rely); | ||||||
|   lua_getglobal(L, "onmousemotion"); |   } | ||||||
|   lua_pushnumber(L, xpos); |  | ||||||
|   lua_pushnumber(L, ypos); |  | ||||||
|   lua_pushnumber(L, relx); |  | ||||||
|   lua_pushnumber(L, rely); |  | ||||||
|   lua_call(L, 4, 0); |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
|   instance->lastx = xpos; |   instance->lastx = xpos; | ||||||
|   instance->lasty = ypos; |   instance->lasty = ypos; | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								core/Input.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								core/Input.h
									
									
									
									
									
								
							| @ -1,20 +1,21 @@ | |||||||
|  | #ifndef COUCH_H | ||||||
|  | #define COUCH_H | ||||||
| #include <GL/glew.h> | #include <GL/glew.h> | ||||||
| #include <GLFW/glfw3.h> | #include <GLFW/glfw3.h> | ||||||
| 
 | 
 | ||||||
| #ifdef LUA_SCRIPTING | #include <vector> | ||||||
| extern "C" { |  | ||||||
| #include <lua.h> |  | ||||||
| #include <lualib.h> |  | ||||||
| #include <lauxlib.h> |  | ||||||
| } |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
| 
 | 
 | ||||||
| #include "types.h" | #include "types.h" | ||||||
| 
 | 
 | ||||||
|  | typedef void (*KeyHandler)(Window *window, int key, int code, int action, int mods); | ||||||
|  | typedef void (*MousePositionHandler)(Window *window, double xpos, double ypos, double xrel, double yrel); | ||||||
|  | 
 | ||||||
| class Input { | class Input { | ||||||
| public: | public: | ||||||
|   static Input *GetInstance(); |   static Input *GetInstance(); | ||||||
|   void Use(Window *window); |   void Use(Window *window); | ||||||
|  |   std::vector<KeyHandler> keyHandlers; | ||||||
|  |   std::vector<MousePositionHandler> mousePositionHandlers; | ||||||
| private: | private: | ||||||
|   double lastx, lasty; |   double lastx, lasty; | ||||||
|   Input(); |   Input(); | ||||||
| @ -22,3 +23,5 @@ private: | |||||||
|   static void HandleMousePosition(Window *window, double xpos, double ypos); |   static void HandleMousePosition(Window *window, double xpos, double ypos); | ||||||
|   static Input *instance; |   static Input *instance; | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
|  | #endif // COUCH_H
 | ||||||
|  | |||||||
							
								
								
									
										90
									
								
								core/Lua.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								core/Lua.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | |||||||
|  | #include "Lua.h" | ||||||
|  | 
 | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  | 
 | ||||||
|  | lua_State *Lua::L { luaL_newstate() }; | ||||||
|  | 
 | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | 
 | ||||||
|  | void Lua::Initialize() { | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  |   language = this; | ||||||
|  |   int err; | ||||||
|  |   // Initialize Lua
 | ||||||
|  |   luaopen_base(L); | ||||||
|  |   luaopen_couch(L); | ||||||
|  |   err = luaL_loadfile(L, "main.lua"); | ||||||
|  |   if (err == LUA_OK) { | ||||||
|  |     err = lua_pcall(L, 0, 0, 0); | ||||||
|  |     if (err != LUA_OK) { | ||||||
|  |       Error(); | ||||||
|  |     } | ||||||
|  |     lua_getglobal(L, "init"); | ||||||
|  |     err = lua_pcall(L, 0, 0, 0); | ||||||
|  |     if (err != LUA_OK) { | ||||||
|  |       Error(); | ||||||
|  |     } | ||||||
|  |   } else if (err == LUA_ERRFILE) { | ||||||
|  |     std::cerr << "Could not find main.lua." << std::endl; | ||||||
|  |     exit(1); | ||||||
|  |   } else { | ||||||
|  |     // Syntax error
 | ||||||
|  |     Error(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   // Bind input functions
 | ||||||
|  |   //glfwSetWindowUserPointer(window, (void*) L);
 | ||||||
|  |   Input *input = Input::GetInstance(); | ||||||
|  |   input->keyHandlers.push_back(LuaKeyHandler); | ||||||
|  |   input->mousePositionHandlers.push_back(LuaMousePositionHandler); | ||||||
|  | #else // LUA_SCRIPTING
 | ||||||
|  |   std::cerr << "Lua is selected as scripting language, but this binary was built without Lua support." << std::endl; | ||||||
|  |   exit(1); | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Lua::Update(double delta) { | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  |   lua_getglobal(L, "update"); | ||||||
|  |   lua_pushnumber(L, delta); | ||||||
|  |   lua_call(L, 1, 0); | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Lua::Close() { | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  |   lua_close(L); | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Lua::Error() { | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  |   const char *error = lua_tolstring(L, -1, 0); | ||||||
|  |   std::cerr << error << std::endl; | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  |   exit(1); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Lua::LuaKeyHandler(Window *window, int key, int code, int action, int mods) { | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  |   // lua_State *L = (lua_State*) glfwGetWindowUserPointer(window);
 | ||||||
|  |   lua_getglobal(L, "onkey"); | ||||||
|  |   lua_pushinteger(L, key); | ||||||
|  |   lua_pushinteger(L, code); | ||||||
|  |   lua_pushinteger(L, action); | ||||||
|  |   lua_pushinteger(L, mods); | ||||||
|  |   lua_call(L, 4, 0); | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void Lua::LuaMousePositionHandler(Window *window, double xpos, double ypos, double relx, double rely) { | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  |   // lua_State *L = (lua_State*) glfwGetWindowUserPointer(window);
 | ||||||
|  |   lua_getglobal(L, "onmousemotion"); | ||||||
|  |   lua_pushnumber(L, xpos); | ||||||
|  |   lua_pushnumber(L, ypos); | ||||||
|  |   lua_pushnumber(L, relx); | ||||||
|  |   lua_pushnumber(L, rely); | ||||||
|  |   lua_call(L, 4, 0); | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | } | ||||||
							
								
								
									
										35
									
								
								core/Lua.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								core/Lua.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | #ifndef LUA_H | ||||||
|  | #define LUA_H | ||||||
|  | 
 | ||||||
|  | #include <iostream> | ||||||
|  | #include <stdlib.h> | ||||||
|  | 
 | ||||||
|  | #include "Input.h" | ||||||
|  | 
 | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  | // Lua includes
 | ||||||
|  | extern "C" { | ||||||
|  | #include "lua.h" | ||||||
|  | #include "lualib.h" | ||||||
|  | #include "lauxlib.h"   | ||||||
|  | } | ||||||
|  | extern "C" int luaopen_couch(lua_State* L); | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | 
 | ||||||
|  | #include "ScriptingLanguage.h" | ||||||
|  | 
 | ||||||
|  | class Lua : public ScriptingLanguage { | ||||||
|  | public: | ||||||
|  |   void Initialize(); | ||||||
|  |   void Update(double delta); | ||||||
|  |   void Close(); | ||||||
|  |   void Error(); | ||||||
|  | private: | ||||||
|  | #ifdef LUA_SCRIPTING | ||||||
|  |   static lua_State *L; | ||||||
|  |   static void LuaKeyHandler(Window *window, int key, int code, int action, int mods); | ||||||
|  |   static void LuaMousePositionHandler(Window *window, double xpos, double ypos, double xrel, double yrel); | ||||||
|  | #endif // LUA_SCRIPTING
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #endif /* LUA_H */ | ||||||
							
								
								
									
										8
									
								
								core/ScriptingLanguage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								core/ScriptingLanguage.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | #include "ScriptingLanguage.h" | ||||||
|  | 
 | ||||||
|  | ScriptingLanguage *ScriptingLanguage::language { nullptr }; | ||||||
|  | 
 | ||||||
|  | ScriptingLanguage *ScriptingLanguage::GetCurrentLanguage() { | ||||||
|  |   return language; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| @ -1,10 +1,15 @@ | |||||||
| #ifndef SCRIPTINGLANGUAGE_H | #ifndef SCRIPTINGLANGUAGE_H | ||||||
| #define SCRIPTINGLANGUAGE_H | #define SCRIPTINGLANGUAGE_H | ||||||
| 
 | 
 | ||||||
| class ScriptingLangauge { | class ScriptingLanguage { | ||||||
|   void Initialize(); | public: | ||||||
|   void Update(); |   virtual void Initialize() = 0; | ||||||
|   void Close(); |   virtual void Update(double delta) = 0; | ||||||
| } |   virtual void Close() = 0; | ||||||
|  |   virtual void Error() = 0; | ||||||
|  |   static ScriptingLanguage *GetCurrentLanguage(); | ||||||
|  | protected: | ||||||
|  |   static ScriptingLanguage *language; | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| #endif /* SCRIPTINGLANGUAGE_H */ | #endif /* SCRIPTINGLANGUAGE_H */ | ||||||
|  | |||||||
| @ -1,15 +1,6 @@ | |||||||
| // C++ includes
 | // C++ includes
 | ||||||
| #include <iostream> | #include <iostream> | ||||||
| 
 | 
 | ||||||
| #ifdef LUA_SCRIPTING |  | ||||||
| // Lua includes
 |  | ||||||
| extern "C" { |  | ||||||
| #include <lua.h> |  | ||||||
| #include <lualib.h> |  | ||||||
| #include <lauxlib.h>   |  | ||||||
| } |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
| 
 |  | ||||||
| // OpenGL Includes
 | // OpenGL Includes
 | ||||||
| #include <GL/glew.h> | #include <GL/glew.h> | ||||||
| #include <GLFW/glfw3.h> | #include <GLFW/glfw3.h> | ||||||
| @ -22,6 +13,7 @@ extern "C" { | |||||||
| #include "Camera.h" | #include "Camera.h" | ||||||
| #include "Input.h" | #include "Input.h" | ||||||
| #include "Node.h" | #include "Node.h" | ||||||
|  | #include "Lua.h" | ||||||
| 
 | 
 | ||||||
| Window *window; | Window *window; | ||||||
| 
 | 
 | ||||||
| @ -30,12 +22,6 @@ const int height = 600; | |||||||
| 
 | 
 | ||||||
| Node *root; | Node *root; | ||||||
| 
 | 
 | ||||||
| #ifdef LUA_SCRIPTING |  | ||||||
| 
 |  | ||||||
| extern "C" int luaopen_couch(lua_State* L); |  | ||||||
| 
 |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
| 
 |  | ||||||
| void render(Node *curr, Shader shader, Matrix model) { | void render(Node *curr, Shader shader, Matrix model) { | ||||||
|   if (curr->IsDrawable()) { |   if (curr->IsDrawable()) { | ||||||
|     if (curr->IsTransformable()) { |     if (curr->IsTransformable()) { | ||||||
| @ -81,22 +67,6 @@ int main() { | |||||||
| 
 | 
 | ||||||
|   root = Node::GetRoot(); |   root = Node::GetRoot(); | ||||||
| 
 | 
 | ||||||
| #ifdef LUA_SCRIPTING |  | ||||||
|   lua_State *L; |  | ||||||
|   L = luaL_newstate(); |  | ||||||
|   luaopen_base(L); |  | ||||||
|   luaopen_couch(L); |  | ||||||
|   if (luaL_loadfile(L, "main.lua") == 0){ |  | ||||||
|     lua_call(L, 0, 0); |  | ||||||
|     lua_getglobal(L, "init"); |  | ||||||
|     lua_call(L, 0, 0); |  | ||||||
|   } else { |  | ||||||
|     std::cerr << "Could not find main.lua" << std::endl; |  | ||||||
|     return 1; |  | ||||||
|   } |  | ||||||
|   glfwSetWindowUserPointer(window, (void*) L); |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
| 
 |  | ||||||
|   Input *input = Input::GetInstance(); |   Input *input = Input::GetInstance(); | ||||||
|   input->Use(window); |   input->Use(window); | ||||||
| 
 | 
 | ||||||
| @ -108,6 +78,10 @@ int main() { | |||||||
|   Matrix projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f); |   Matrix projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f); | ||||||
|   shader.UpdateProjection(projection); |   shader.UpdateProjection(projection); | ||||||
| 
 | 
 | ||||||
|  |   // TODO Allow multiple scripting languages
 | ||||||
|  |   Lua *lua = new Lua(); | ||||||
|  |   lua->Initialize(); | ||||||
|  | 
 | ||||||
|   double lastTime = glfwGetTime(); |   double lastTime = glfwGetTime(); | ||||||
|   double delta = 0.0; |   double delta = 0.0; | ||||||
| 
 | 
 | ||||||
| @ -115,6 +89,7 @@ int main() { | |||||||
|     glClearColor(0.5f, 0.5f, 0.5f, 1.0f); |     glClearColor(0.5f, 0.5f, 0.5f, 1.0f); | ||||||
|     glClear(GL_COLOR_BUFFER_BIT); |     glClear(GL_COLOR_BUFFER_BIT); | ||||||
| 
 | 
 | ||||||
|  |     lua->Update(delta); | ||||||
| 
 | 
 | ||||||
|     Matrix view(1.0f); |     Matrix view(1.0f); | ||||||
|     Camera *camera = Camera::GetCurrentCamera(); |     Camera *camera = Camera::GetCurrentCamera(); | ||||||
| @ -124,16 +99,8 @@ int main() { | |||||||
|     view = glm::translate(view, -camera->transform.position); |     view = glm::translate(view, -camera->transform.position); | ||||||
|     shader.UpdateView(view); |     shader.UpdateView(view); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| #ifdef LUA_SCRIPTING |  | ||||||
|     lua_getglobal(L, "update"); |  | ||||||
|     lua_pushnumber(L, delta); |  | ||||||
|     lua_call(L, 1, 0); |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
| 
 |  | ||||||
|     // Render the scene tree
 |     // Render the scene tree
 | ||||||
|     render(root, shader, Matrix(1.0f)); |     render(root, shader, Matrix(1.0f)); | ||||||
| 
 |  | ||||||
|      |      | ||||||
|     glfwSwapBuffers(window); |     glfwSwapBuffers(window); | ||||||
|     glfwPollEvents(); |     glfwPollEvents(); | ||||||
| @ -143,12 +110,7 @@ int main() { | |||||||
|     lastTime = curTime; |     lastTime = curTime; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| #ifdef LUA_SCRIPTING |   lua->Close(); | ||||||
| 
 |  | ||||||
|   lua_close(L); |  | ||||||
| 
 |  | ||||||
| #endif // LUA_SCRIPTING
 |  | ||||||
|    |  | ||||||
|   glfwDestroyWindow(window); |   glfwDestroyWindow(window); | ||||||
|   glfwTerminate(); |   glfwTerminate(); | ||||||
|   return 0; |   return 0; | ||||||
|  | |||||||
| @ -27,3 +27,12 @@ I want to be able to build this for Windows | |||||||
| - I have no clue what that entails | - I have no clue what that entails | ||||||
| - CMake? | - CMake? | ||||||
| - How to run SWIG on windows? | - How to run SWIG on windows? | ||||||
|  | 
 | ||||||
|  | ### Windows Compatible Postmortem | ||||||
|  | Pretty brittle as a result of needing to download Windows binaries, but it works | ||||||
|  | Eventually, we might need to include the source files as submodules, and build them all with CMake | ||||||
|  | For now, what we've got is good | ||||||
|  | 
 | ||||||
|  | ### Better error messages | ||||||
|  | Okay, now I want a message other than "main.lua not found!" if the lua file fucks up. | ||||||
|  | Also, I want Lua errors to kill the program with an error message and a stack trace. | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Dane Johnson
						Dane Johnson