Jelajahi Sumber

Started on new scripting system

Ivan Safrin 9 tahun lalu
induk
melakukan
8274594791

+ 8 - 0
build/osx/PolycodeCore/PolycodeCore.xcodeproj/project.pbxproj

@@ -7,6 +7,8 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		6D904FCD1CC2A4DA00D0E80A /* PolyScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D904FCC1CC2A4DA00D0E80A /* PolyScript.cpp */; };
+		6D904FCF1CC2A4E900D0E80A /* PolyScript.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D904FCE1CC2A4E900D0E80A /* PolyScript.h */; };
 		8A7349081B86A53C00F660C0 /* lodepng.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A7349071B86A53C00F660C0 /* lodepng.h */; };
 		8A73490A1B86A54800F660C0 /* lodepng.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8A7349091B86A54800F660C0 /* lodepng.cpp */; };
 		8A825F231B829BA70039E823 /* PolyPAAudioInterface.h in Headers */ = {isa = PBXBuildFile; fileRef = 8A825F221B829BA70039E823 /* PolyPAAudioInterface.h */; };
@@ -169,6 +171,8 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
+		6D904FCC1CC2A4DA00D0E80A /* PolyScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PolyScript.cpp; path = ../../../src/core/PolyScript.cpp; sourceTree = "<group>"; };
+		6D904FCE1CC2A4E900D0E80A /* PolyScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PolyScript.h; path = ../../../include/polycode/core/PolyScript.h; sourceTree = "<group>"; };
 		8A7349071B86A53C00F660C0 /* lodepng.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lodepng.h; path = ../../../include/lodepng.h; sourceTree = "<group>"; };
 		8A7349091B86A54800F660C0 /* lodepng.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lodepng.cpp; path = ../../../src/core/lodepng.cpp; sourceTree = "<group>"; };
 		8A825F221B829BA70039E823 /* PolyPAAudioInterface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PolyPAAudioInterface.h; path = ../../../include/polycode/core/PolyPAAudioInterface.h; sourceTree = "<group>"; };
@@ -410,6 +414,7 @@
 				8A8652BD1B72867F009F94DD /* PolySceneRenderTexture.cpp */,
 				8A8652BE1B72867F009F94DD /* PolySceneSound.cpp */,
 				8A8652BF1B72867F009F94DD /* PolySceneSprite.cpp */,
+				6D904FCC1CC2A4DA00D0E80A /* PolyScript.cpp */,
 				8A8652C01B72867F009F94DD /* PolyServer.cpp */,
 				8A8652C11B72867F009F94DD /* PolyShader.cpp */,
 				8A8652C21B72867F009F94DD /* PolySkeleton.cpp */,
@@ -503,6 +508,7 @@
 				8A86521D1B72865C009F94DD /* PolySceneRenderTexture.h */,
 				8A86521E1B72865C009F94DD /* PolySceneSound.h */,
 				8A86521F1B72865C009F94DD /* PolySceneSprite.h */,
+				6D904FCE1CC2A4E900D0E80A /* PolyScript.h */,
 				8A8652211B72865C009F94DD /* PolyServer.h */,
 				8A8652221B72865C009F94DD /* PolyServerWorld.h */,
 				8A8652231B72865C009F94DD /* PolyShader.h */,
@@ -536,6 +542,7 @@
 				8A7349081B86A53C00F660C0 /* lodepng.h in Headers */,
 				8A86523E1B72865C009F94DD /* PolyCubemap.h in Headers */,
 				8A8652741B72865C009F94DD /* PolyTexture.h in Headers */,
+				6D904FCF1CC2A4E900D0E80A /* PolyScript.h in Headers */,
 				8A86526D1B72865C009F94DD /* PolyServerWorld.h in Headers */,
 				8A825F231B829BA70039E823 /* PolyPAAudioInterface.h in Headers */,
 				8A86524F1B72865C009F94DD /* PolyMaterialManager.h in Headers */,
@@ -706,6 +713,7 @@
 				8A8653001B72867F009F94DD /* PolySceneEntityInstance.cpp in Sources */,
 				8A8652DC1B72867F009F94DD /* PolyConfig.cpp in Sources */,
 				8A8652FE1B72867F009F94DD /* PolyResourceManager.cpp in Sources */,
+				6D904FCD1CC2A4DA00D0E80A /* PolyScript.cpp in Sources */,
 				8A8652FF1B72867F009F94DD /* PolyScene.cpp in Sources */,
 				8A8652DB1B72867F009F94DD /* PolyColor.cpp in Sources */,
 				8A8652ED1B72867F009F94DD /* PolyLogger.cpp in Sources */,

+ 9 - 2
build/osx/TemplateApp/TemplateApp.xcodeproj/project.pbxproj

@@ -8,6 +8,8 @@
 
 /* Begin PBXBuildFile section */
 		6D6FD3E11BF122A2005AA8E9 /* PolycodeView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6D6FD3E01BF122A2005AA8E9 /* PolycodeView.mm */; };
+		6D904FD11CC2AAA500D0E80A /* liblua5.1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D904FD01CC2AAA500D0E80A /* liblua5.1.a */; };
+		6D904FD31CC2AEB400D0E80A /* rotate.lua in Resources */ = {isa = PBXBuildFile; fileRef = 6D904FD21CC2AEB400D0E80A /* rotate.lua */; };
 		6DCDD7251C724726007E90E1 /* main_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 6DCDD7241C724726007E90E1 /* main_icon.png */; };
 		6DD2D0B61BEEDC150026D85C /* libportaudio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6DD2D0B51BEEDC150026D85C /* libportaudio.a */; };
 		8A825F271B82A2680039E823 /* libportaudio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A825F261B82A2680039E823 /* libportaudio.a */; };
@@ -22,7 +24,6 @@
 		8A86535D1B72949F009F94DD /* liblibogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653541B72949F009F94DD /* liblibogg.a */; };
 		8A86535E1B72949F009F94DD /* liblibvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653551B72949F009F94DD /* liblibvorbis.a */; };
 		8A86535F1B72949F009F94DD /* liblibvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653561B72949F009F94DD /* liblibvorbisfile.a */; };
-		8A8653601B72949F009F94DD /* liblua5.1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653571B72949F009F94DD /* liblua5.1.a */; };
 		8A8653611B72949F009F94DD /* libphysfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653581B72949F009F94DD /* libphysfs.a */; };
 		8A8653631B72949F009F94DD /* libPolycore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A86535A1B72949F009F94DD /* libPolycore.a */; };
 		8A8653641B72949F009F94DD /* libz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A86535B1B72949F009F94DD /* libz.a */; };
@@ -35,6 +36,8 @@
 
 /* Begin PBXFileReference section */
 		6D6FD3E01BF122A2005AA8E9 /* PolycodeView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = PolycodeView.mm; path = ../../../../src/view/osx/PolycodeView.mm; sourceTree = "<group>"; };
+		6D904FD01CC2AAA500D0E80A /* liblua5.1.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua5.1.a; path = ../../../../lib/osx/liblua5.1.a; sourceTree = "<group>"; };
+		6D904FD21CC2AEB400D0E80A /* rotate.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rotate.lua; sourceTree = "<group>"; };
 		6DCDD7241C724726007E90E1 /* main_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = main_icon.png; path = ../../../../assets/icons/main_icon.png; sourceTree = "<group>"; };
 		6DD2D0B51BEEDC150026D85C /* libportaudio.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libportaudio.a; path = ../../../../lib/osx/libportaudio.a; sourceTree = "<group>"; };
 		8A825F261B82A2680039E823 /* libportaudio.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libportaudio.a; path = ../../../../lib/osx/libportaudio.a; sourceTree = "<group>"; };
@@ -75,14 +78,15 @@
 				8A825F291B82A29B0039E823 /* CoreAudio.framework in Frameworks */,
 				8A8653681B7294B7009F94DD /* OpenGL.framework in Frameworks */,
 				8A8653641B72949F009F94DD /* libz.a in Frameworks */,
+				6D904FD11CC2AAA500D0E80A /* liblua5.1.a in Frameworks */,
 				8A825F271B82A2680039E823 /* libportaudio.a in Frameworks */,
 				8A8653631B72949F009F94DD /* libPolycore.a in Frameworks */,
 				8A86535F1B72949F009F94DD /* liblibvorbisfile.a in Frameworks */,
 				8A86535E1B72949F009F94DD /* liblibvorbis.a in Frameworks */,
 				8A86535C1B72949F009F94DD /* libfreetype.a in Frameworks */,
-				8A8653601B72949F009F94DD /* liblua5.1.a in Frameworks */,
 				6DD2D0B61BEEDC150026D85C /* libportaudio.a in Frameworks */,
 				8A8653611B72949F009F94DD /* libphysfs.a in Frameworks */,
+				6D904FD11CC2AAA500D0E80A /* liblua5.1.a in Frameworks */,
 				8A86535D1B72949F009F94DD /* liblibogg.a in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
@@ -120,6 +124,7 @@
 				8A8653361B72931C009F94DD /* AppDelegate.m */,
 				6D6FD3E01BF122A2005AA8E9 /* PolycodeView.mm */,
 				8A86536E1B72C301009F94DD /* PolycodeView.h */,
+				6D904FD21CC2AEB400D0E80A /* rotate.lua */,
 				8ADFECF91C8E0852007B57A2 /* default.pak */,
 				8ADFECF51C8E07FB007B57A2 /* hdr.pak */,
 				8A86533A1B72931C009F94DD /* Images.xcassets */,
@@ -134,6 +139,7 @@
 			isa = PBXGroup;
 			children = (
 				8A8653531B72949F009F94DD /* libfreetype.a */,
+				6D904FD01CC2AAA500D0E80A /* liblua5.1.a */,
 				8A8653541B72949F009F94DD /* liblibogg.a */,
 				8A8653551B72949F009F94DD /* liblibvorbis.a */,
 				8A825F261B82A2680039E823 /* libportaudio.a */,
@@ -210,6 +216,7 @@
 				8A8653961B752DBE009F94DD /* main_icon.png in Resources */,
 				8ADFECFA1C8E0852007B57A2 /* default.pak in Resources */,
 				8A86533E1B72931C009F94DD /* MainMenu.xib in Resources */,
+				6D904FD31CC2AEB400D0E80A /* rotate.lua in Resources */,
 				8ADFECF61C8E07FB007B57A2 /* hdr.pak in Resources */,
 				6DCDD7251C724726007E90E1 /* main_icon.png in Resources */,
 			);

+ 5 - 23
build/osx/TemplateApp/TemplateApp/PolycodeTemplateApp.mm

@@ -15,6 +15,7 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
     core->addFileSource("archive", "hdr.pak");
     globalPool->loadResourcesFromFolder("hdr", true);
     
+    Polycode::Script *rotateScript = (Polycode::Script*) globalPool->loadResource("rotate.lua");
     
 	// Write your code here!
     
@@ -25,9 +26,10 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
     
    // scene->setOverrideMaterial((Material*)globalPool->getResource(Resource::RESOURCE_MATERIAL, "Unlit"));
     
-    for(int i=0; i  < 3000; i++) {
+    for(int i=0; i  < 5; i++) {
         test = new ScenePrimitive(ScenePrimitive::TYPE_VPLANE, 0.5, 0.5);
         test->setMaterialByName("Unlit");
+        test->attachScript(rotateScript);
         test->getShaderPass(0).shaderBinding->loadTextureForParam("diffuse", "main_icon.png");
         test->setPosition(RANDOM_NUMBER * 0.5, RANDOM_NUMBER * 0.4);
         test->setBlendingMode(Renderer::BLEND_MODE_NONE);
@@ -35,27 +37,11 @@ PolycodeTemplateApp::PolycodeTemplateApp(PolycodeView *view) {
         scene->addChild(test);
         tests.push_back(test);
     }
-       Camera *camera = scene->getDefaultCamera();
+    Camera *camera = scene->getDefaultCamera();
 
-    fpsLabel = new SceneLabel("FPS:", 32, "main", Label::ANTIALIAS_FULL, 0.1);
+    fpsLabel = new SceneLabel("FPS:", 32, "mono", Label::ANTIALIAS_FULL, 0.1);
     scene->addChild(fpsLabel);
     fpsLabel->setPositionX(-0.6);
-
-    scene->getDefaultCamera()->setPostFilterByName("HDRProcessBloom");
-
-    camera->getShaderPass(0).shaderBinding->addParam(ProgramParam::PARAM_NUMBER, "brightThreshold")->setNumber(0.1);
-    camera->getShaderPass(1).shaderBinding->addParam(ProgramParam::PARAM_NUMBER, "blurSize")->setNumber(0.01);
-    camera->getShaderPass(2).shaderBinding->addParam(ProgramParam::PARAM_NUMBER, "blurSize")->setNumber(0.01);
-    camera->getShaderPass(3).shaderBinding->addParam(ProgramParam::PARAM_NUMBER, "bloomFactor")->setNumber(2.0);
-    camera->getShaderPass(3).shaderBinding->addParam(ProgramParam::PARAM_NUMBER, "exposure")->setNumber(0.7);
-
-
-    //scene->getDefaultCamera()->setPostFilterByName("Blur");
-    //camera->getShaderPass(0).shaderBinding->addParam(ProgramParam::PARAM_NUMBER, "blurSize")->setNumber(0.003);
-    //camera->getShaderPass(1).shaderBinding->addParam(ProgramParam::PARAM_NUMBER, "blurSize")->setNumber(0.003);
-
-//    Sound *music = new Sound("BUGSHUFFLE.ogg");
-  //  music->Play();
     
     Services()->getInput()->addEventListener(this, InputEvent::EVENT_KEYDOWN);
 }
@@ -71,10 +57,6 @@ PolycodeTemplateApp::~PolycodeTemplateApp() {
 bool PolycodeTemplateApp::Update() {
     Number elapsed = core->getElapsed();
     
-    for(int i=0; i < tests.size(); i++) {
-        tests[i]->Roll(elapsed * 45.0);
-    }
-    
     if(Services()->getRenderer()->getRenderThread()->getFrameInfo().timeTaken > 0) {
         fpsLabel->setText("FPS:"+String::IntToString(1000/Services()->getRenderer()->getRenderThread()->getFrameInfo().timeTaken));
     }

+ 17 - 0
build/osx/TemplateApp/TemplateApp/rotate.lua

@@ -0,0 +1,17 @@
+-- test script
+
+Rotator = {}
+Rotator.__index = Rotator
+
+function Rotator.init(entity)
+	local rotator = {}
+	rotator.entity = entity
+	print(entity)
+	return rotator
+end
+
+function Rotator:update(elapsed)
+	print(self.entity)
+end
+
+return Rotator

+ 1 - 0
include/Polycode.h

@@ -86,6 +86,7 @@
 #include "polycode/core/PolyRay.h"
 #include "polycode/core/PolySceneSprite.h"
 #include "polycode/core/PolySceneEntityInstance.h"
+#include "polycode/core/PolyScript.h"
 #include "polycode/core/PolyGlobals.h"
 
 #if defined(__APPLE__) && defined(__MACH__)

+ 11 - 1
include/polycode/core/PolyEntity.h

@@ -37,6 +37,8 @@ namespace Polycode {
 
 	class Renderer;
     class Scene;
+    class Script;
+    class ScriptInstance;
 
 	class _PolyExport MouseEventResult {
 		public:
@@ -94,7 +96,8 @@ namespace Polycode {
 			/**
 			* Main update method. Override this to do your updates before the render cycle.
 			*/			
-			virtual void Update(){};			
+			virtual void Update();
+        
 			virtual void fixedUpdate(){};
         
             void transformAndRender(GPUDrawBuffer *drawBuffer, Polycode::Rectangle *parentScissorBox);
@@ -883,8 +886,15 @@ namespace Polycode {
     
             Scene *getContainerScene();
         
+            void attachScript(Script *script);
+            void detachScript(Script *script);
+            unsigned int getNumScripts();
+            ScriptInstance *getScriptAtIndex(unsigned int index);
+        
 		protected:
 
+            std::vector<ScriptInstance*> scripts;
+        
             GPUDrawCall drawCall;
         
             Scene *containerScene;

+ 1 - 0
include/polycode/core/PolyResource.h

@@ -60,6 +60,7 @@ namespace Polycode {
 			static const int RESOURCE_SPRITE = 7;
 			static const int RESOURCE_ENTITY_INSTANCE = 8;
             static const int RESOURCE_FONT = 9;
+            static const int RESOURCE_SCRIPT = 10;
         
 			bool reloadOnFileModify;
         

+ 15 - 0
include/polycode/core/PolyResourceManager.h

@@ -31,6 +31,12 @@ THE SOFTWARE.
 #include FT_FREETYPE_H
 #include FT_LCD_FILTER_H
 
+extern "C" {
+    #include "lua.h"
+    #include "lualib.h"
+    #include "lauxlib.h"
+}
+
 #define RESOURCE_CHECK_INTERVAL	2000
 
 namespace Polycode {
@@ -121,6 +127,15 @@ namespace Polycode {
         FT_Library FTLibrary;
     };
     
+    class _PolyExport ScriptResourceLoader : public ResourceLoader {
+    public:
+        ScriptResourceLoader();
+        ~ScriptResourceLoader();
+        Resource *loadResource(const String &path, ResourcePool *targetPool);
+    private:
+        lua_State *luaState;
+    };
+    
     class _PolyExport MeshResourceLoader : public ResourceLoader {
     public:
         MeshResourceLoader();

+ 70 - 0
include/polycode/core/PolyScript.h

@@ -0,0 +1,70 @@
+/*
+ Copyright (C) 2016 by Ivan Safrin
+ 
+ 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.
+ */
+
+#pragma once
+
+#include "polycode/core/PolyResource.h"
+#include "polycode/core/PolyString.h"
+
+extern "C" {
+    #include "lua.h"
+    #include "lualib.h"
+    #include "lauxlib.h"
+}
+
+namespace Polycode {
+
+    class Entity;
+    class Script;
+    
+    class ScriptInstance {
+        public:
+            Script *script;
+    };
+    
+    class Script : public Resource {
+        public:
+            Script(const String &path);
+        
+            virtual ScriptInstance *callInit(Entity *entity) = 0;
+            virtual void callUpdate(ScriptInstance *instance, Entity *entity, Number elapsed) = 0;
+    };
+    
+    class LuaScriptInstance : public ScriptInstance {
+        public:
+            int tableRef;
+    };
+    
+    class LuaScript : public Script {
+        public:
+            LuaScript(lua_State *state, const String &path);
+        
+            ScriptInstance *callInit(Entity *entity);
+            void callUpdate(ScriptInstance *instance, Entity *entity, Number elapsed);
+        
+        private:
+            lua_State *state;
+            String tableName;
+            int tableRef;
+    };
+
+}

+ 1 - 1
lib

@@ -1 +1 @@
-Subproject commit 8451568da8ae51a6869894f5ca30051da152fa87
+Subproject commit cd559f0ccaef1d97e5b8555eef20b0724a54e71b

+ 35 - 0
src/core/PolyEntity.cpp

@@ -23,6 +23,7 @@
 #include "polycode/core/PolyRenderer.h"
 #include "polycode/core/PolyCoreServices.h"
 #include "polycode/core/PolyInputEvent.h"
+#include "polycode/core/PolyScript.h"
 
 using namespace Polycode;
 
@@ -1196,6 +1197,12 @@ MouseEventResult Entity::onMouseWheelUp(const Ray &ray, int timestamp) {
 	return ret;
 }
 
+void Entity::Update() {
+    for(int i=0; i < scripts.size(); i++) {
+        scripts[i]->script->callUpdate(scripts[i], this, Services()->getCore()->getElapsed());
+    }
+}
+
 MouseEventResult Entity::onMouseWheelDown(const Ray &ray, int timestamp) {
 	MouseEventResult ret;
 	ret.hit = false;
@@ -1233,3 +1240,31 @@ MouseEventResult Entity::onMouseWheelDown(const Ray &ray, int timestamp) {
 	}
 	return ret;
 }
+
+void Entity::attachScript(Script *script) {
+    ScriptInstance *instance = script->callInit(this);
+    scripts.push_back(instance);
+}
+
+void Entity::detachScript(Script *script) {
+    for(int i=0; i < scripts.size(); i++) {
+        if(scripts[i]->script == script) {
+            ScriptInstance *instance = scripts[i];
+            scripts.erase(scripts.begin()+i);
+            delete instance;
+            return;
+        }
+    }
+}
+
+unsigned int Entity::getNumScripts() {
+    return scripts.size();
+}
+
+ScriptInstance *Entity::getScriptAtIndex(unsigned int index) {
+    if(index < scripts.size()) {
+        return scripts[index];
+    } else {
+        return NULL;
+    }
+}

+ 18 - 1
src/core/PolyResourceManager.cpp

@@ -31,6 +31,7 @@
 #include "polycode/core/PolyRenderer.h"
 #include "polycode/core/PolyFont.h"
 #include "polycode/core/PolyMesh.h"
+#include "polycode/core/PolyScript.h"
 #include "tinyxml.h"
 
 using std::vector;
@@ -228,7 +229,6 @@ Resource *ResourcePool::getResourceByPath(const String& resourcePath) const {
     if(fallbackPool) {
         return fallbackPool->getResourceByPath(resourcePath);
     } else {
-        Logger::log("Could not find resource for path [%s] in pool [%s]\n", resourcePath.c_str(), name.c_str());
         return NULL;
     }
 }
@@ -288,6 +288,7 @@ ResourceManager::ResourceManager() : EventDispatcher() {
     resourceLoaders.push_back(new MaterialResourceLoader());
     resourceLoaders.push_back(new FontResourceLoader());
     resourceLoaders.push_back(new MeshResourceLoader());
+    resourceLoaders.push_back(new ScriptResourceLoader());
 }
 
 ResourceManager::~ResourceManager() {
@@ -367,6 +368,22 @@ Resource *ProgramResourceLoader::loadResource(const String &path, ResourcePool *
     return newProgram;
 }
 
+ScriptResourceLoader::ScriptResourceLoader() {
+    luaState =  lua_open();
+    luaL_openlibs(luaState);
+    luaopen_debug(luaState);
+    extensions.push_back("lua");
+}
+
+ScriptResourceLoader::~ScriptResourceLoader() {
+    lua_close(luaState);
+}
+
+Resource *ScriptResourceLoader::loadResource(const String &path, ResourcePool *targetPool) {
+    Script *newScript = new LuaScript(luaState, path);
+    return newScript;
+}
+
 FontResourceLoader::FontResourceLoader() {
     
     FT_Init_FreeType(&FTLibrary);

+ 57 - 0
src/core/PolyScript.cpp

@@ -0,0 +1,57 @@
+/*
+ Copyright (C) 2016 by Ivan Safrin
+ 
+ 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.
+ */
+
+#include "polycode/core/PolyScript.h"
+#include "polycode/core/PolyEntity.h"
+
+using namespace Polycode;
+
+Polycode::Script::Script(const String &path) : Resource(Resource::RESOURCE_SCRIPT) {
+    setResourcePath(path);
+}
+
+LuaScript::LuaScript(lua_State *state, const String &path) : Script(path) {
+    luaL_loadfile(state, path.c_str());
+    lua_pcall(state,0,1,0);
+    tableRef = luaL_ref(state, LUA_REGISTRYINDEX);
+    this->state = state;
+}
+
+ScriptInstance *LuaScript::callInit(Entity *entity) {
+    lua_getglobal(state, tableName.c_str());
+    lua_rawgeti(state, LUA_REGISTRYINDEX, tableRef);
+    lua_getfield(state, -1, "init");
+    lua_pushlightuserdata(state, entity);
+    lua_pcall(state, 1, 1, 0);
+    LuaScriptInstance *scriptInstance = new LuaScriptInstance();
+    scriptInstance->tableRef = luaL_ref(state, LUA_REGISTRYINDEX);
+    scriptInstance->script = this;
+    return scriptInstance;
+}
+
+void LuaScript::callUpdate(ScriptInstance *instance, Entity *entity, Number elapsed) {
+    lua_rawgeti(state, LUA_REGISTRYINDEX, tableRef);
+    lua_getfield(state, -1, "update");
+    lua_rawgeti(state, LUA_REGISTRYINDEX, ((LuaScriptInstance*)instance)->tableRef);
+    lua_pushnumber(state, elapsed);
+    lua_pcall(state, 2, 0, 0);
+}