diff --git a/Content/Content.vcxitems b/Content/Content.vcxitems
index 0bc4db635..877e71ce6 100644
--- a/Content/Content.vcxitems
+++ b/Content/Content.vcxitems
@@ -558,6 +558,10 @@
true
true
+
+ true
+ true
+
true
true
@@ -578,7 +582,10 @@
true
true
-
+
+ true
+ true
+
true
true
@@ -599,7 +606,14 @@
true
true
-
+
+ true
+ true
+
+
+ true
+ true
+
diff --git a/Content/Content.vcxitems.filters b/Content/Content.vcxitems.filters
index aaf422097..e870423c8 100644
--- a/Content/Content.vcxitems.filters
+++ b/Content/Content.vcxitems.filters
@@ -22,6 +22,9 @@
{c66293fd-fe0c-444e-9502-f0864bfbf736}
+
+ {7a1dfecb-b9bf-4fb6-94cf-39b5fb5860c1}
+
@@ -207,6 +210,12 @@
models
+
+ scripts
+
+
+ scripts\subscript_demo
+
diff --git a/Content/scripts/character_controller_tps.lua b/Content/scripts/character_controller_tps.lua
index 6944e49a0..3aae4848e 100644
--- a/Content/scripts/character_controller_tps.lua
+++ b/Content/scripts/character_controller_tps.lua
@@ -284,7 +284,7 @@ Character = {
local waterRay = Ray(head_transform.GetPosition(),Vector(0,-1,0))
local w,wp,wn = Pick(waterRay,PICK_WATER)
if(w ~= INVALID_ENTITY and self.velocity.Length() > 2) then
- PutWaterRipple("../models/ripple.png",wp)
+ PutWaterRipple(script_dir() .. "../models/ripple.png",wp)
end
end,
@@ -420,9 +420,9 @@ runProcess(function()
font.SetShadowColor(Vector(0,0,0,1))
path.AddFont(font)
- LoadModel("../models/playground.wiscene")
+ LoadModel(script_dir() .. "../models/playground.wiscene")
- player:Create(LoadModel("../models/girl.wiscene"))
+ player:Create(LoadModel(script_dir() .. "../models/girl.wiscene"))
camera:Create(player)
while true do
@@ -442,7 +442,7 @@ runProcess(function()
backlog_post("RELOAD")
killProcesses()
application.SetActivePath(prevPath)
- dofile("character_controller_tps.lua")
+ dofile(script_dir() .. "character_controller_tps.lua")
return
end
diff --git a/Content/scripts/dungeon_generator.lua b/Content/scripts/dungeon_generator.lua
index b67f150b2..17c81bc3c 100644
--- a/Content/scripts/dungeon_generator.lua
+++ b/Content/scripts/dungeon_generator.lua
@@ -1,7 +1,7 @@
-- Simplistic random dungeon generator lua script
-- You can call this from Editor for example, and it will load a complete dungeon from set pieces
-local modelpath = "../models/"
+local modelpath = script_dir() .. "../models/"
dungeon={
diff --git a/Content/scripts/emitter_burst.lua b/Content/scripts/emitter_burst.lua
index ca181bea4..f87f040bf 100644
--- a/Content/scripts/emitter_burst.lua
+++ b/Content/scripts/emitter_burst.lua
@@ -5,7 +5,7 @@ backlog_post("---> START SCRIPT: emitter_burst.lua")
scene = GetScene()
scene.Clear()
-LoadModel("../models/emitter_smoke.wiscene")
+LoadModel(script_dir() .. "../models/emitter_smoke.wiscene")
emitter_entity = scene.Entity_FindByName("smoke") -- query the emitter entity by name
emitter_component = scene.Component_GetEmitter(emitter_entity)
emitter_component.SetEmitCount(0) -- don't emit continuously
diff --git a/Content/scripts/fighting_game.lua b/Content/scripts/fighting_game.lua
index bb2a37994..0e4a94815 100644
--- a/Content/scripts/fighting_game.lua
+++ b/Content/scripts/fighting_game.lua
@@ -1234,7 +1234,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
-- We use a custom scene because if two models are loaded into the global scene, they will have name collisions
-- and thus we couldn't properly query entities by name
local model_scene = Scene()
- self.model = LoadModel(model_scene, "../models/Havoc/havoc.wiscene")
+ self.model = LoadModel(model_scene, script_dir() .. "../models/Havoc/havoc.wiscene")
-- Place model according to starting facing direction:
self.face = face
@@ -1270,31 +1270,31 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
local effect_scene = Scene()
effect_scene.Clear()
- LoadModel(effect_scene, "../models/emitter_dust.wiscene")
+ LoadModel(effect_scene, script_dir() .. "../models/emitter_dust.wiscene")
self.effect_dust = effect_scene.Entity_FindByName("dust") -- query the emitter entity by name
effect_scene.Component_GetEmitter(self.effect_dust).SetEmitCount(0) -- don't emit continuously
scene.Merge(effect_scene)
effect_scene.Clear()
- LoadModel(effect_scene, "../models/emitter_hiteffect.wiscene")
+ LoadModel(effect_scene, script_dir() .. "../models/emitter_hiteffect.wiscene")
self.effect_hit = effect_scene.Entity_FindByName("hit") -- query the emitter entity by name
effect_scene.Component_GetEmitter(self.effect_hit).SetEmitCount(0) -- don't emit continuously
scene.Merge(effect_scene)
effect_scene.Clear()
- LoadModel(effect_scene, "../models/emitter_guardeffect.wiscene")
+ LoadModel(effect_scene, script_dir() .. "../models/emitter_guardeffect.wiscene")
self.effect_guard = effect_scene.Entity_FindByName("guard") -- query the emitter entity by name
effect_scene.Component_GetEmitter(self.effect_guard).SetEmitCount(0) -- don't emit continuously
scene.Merge(effect_scene)
effect_scene.Clear()
- LoadModel(effect_scene, "../models/emitter_spark.wiscene")
+ LoadModel(effect_scene, script_dir() .. "../models/emitter_spark.wiscene")
self.effect_spark = effect_scene.Entity_FindByName("spark") -- query the emitter entity by name
effect_scene.Component_GetEmitter(self.effect_spark).SetEmitCount(0) -- don't emit continuously
scene.Merge(effect_scene)
effect_scene.Clear()
- self.model_fireball = LoadModel(effect_scene, "../models/emitter_fireball.wiscene")
+ self.model_fireball = LoadModel(effect_scene, script_dir() .. "../models/emitter_fireball.wiscene")
self.effect_fireball = effect_scene.Entity_FindByName("fireball") -- query the emitter entity by name
effect_scene.Component_GetEmitter(self.effect_fireball).SetEmitCount(0) -- don't emit continuously
self.effect_fireball_haze = effect_scene.Entity_FindByName("haze") -- query the emitter entity by name
@@ -1307,7 +1307,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
-- HP bar, etc. sprites:
local renderPath = application.GetActivePath()
- self.sprite_hpbar_background = Sprite("hp_bar.png")
+ self.sprite_hpbar_background = Sprite(script_dir() .. "hp_bar.png")
local fx = self.sprite_hpbar_background.GetParams()
fx.SetStencilRefMode(STENCILREFMODE_USER) -- we set the stencil ref in user space
fx.SetStencil(STENCILMODE_NOT, stencilref_cutout)
@@ -1323,7 +1323,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
self.sprite_hpbar_background.SetParams(fx)
renderPath.AddSprite(self.sprite_hpbar_background)
- self.sprite_hpbar_hp = Sprite("hp_bar.png")
+ self.sprite_hpbar_hp = Sprite(script_dir() .. "hp_bar.png")
fx = self.sprite_hpbar_hp.GetParams()
fx.SetStencilRefMode(STENCILREFMODE_USER) -- we set the stencil ref in user space
fx.SetStencil(STENCILMODE_NOT, stencilref_cutout)
@@ -1339,7 +1339,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
self.sprite_hpbar_hp.SetParams(fx)
renderPath.AddSprite(self.sprite_hpbar_hp)
- self.sprite_hpbar_pattern = Sprite("hp_bar.png", "hp_bar.png")
+ self.sprite_hpbar_pattern = Sprite(script_dir() .. "hp_bar.png", script_dir() .. "hp_bar.png")
fx = self.sprite_hpbar_pattern.GetParams()
fx.SetStencilRefMode(STENCILREFMODE_USER) -- we set the stencil ref in user space
fx.SetStencil(STENCILMODE_NOT, stencilref_cutout)
@@ -1361,7 +1361,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
self.sprite_hpbar_pattern.SetAnim(pattern_anim)
renderPath.AddSprite(self.sprite_hpbar_pattern)
- self.sprite_hpbar_pattern2 = Sprite("hp_bar.png", "hp_bar.png")
+ self.sprite_hpbar_pattern2 = Sprite(script_dir() .. "hp_bar.png", script_dir() .. "hp_bar.png")
fx = self.sprite_hpbar_pattern2.GetParams()
fx.SetStencilRefMode(STENCILREFMODE_USER) -- we set the stencil ref in user space
fx.SetStencil(STENCILMODE_NOT, stencilref_cutout)
@@ -1383,7 +1383,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
self.sprite_hpbar_pattern2.SetAnim(pattern_anim)
renderPath.AddSprite(self.sprite_hpbar_pattern2)
- self.sprite_hpbar_border = Sprite("hp_bar.png")
+ self.sprite_hpbar_border = Sprite(script_dir() .. "hp_bar.png")
fx = self.sprite_hpbar_border.GetParams()
fx.SetStencilRefMode(STENCILREFMODE_USER) -- we set the stencil ref in user space
fx.SetStencil(STENCILMODE_NOT, stencilref_cutout)
@@ -1399,7 +1399,7 @@ local function Character(face, skin_color, shirt_color, hair_color, shoe_color)
renderPath.AddSprite(self.sprite_hpbar_border)
if(self.face > 0) then
- self.sprite_timer = Sprite("hp_bar.png")
+ self.sprite_timer = Sprite(script_dir() .. "hp_bar.png")
fx = self.sprite_timer.GetParams()
fx.SetStencilRefMode(STENCILREFMODE_USER) -- we set the stencil ref in user space
fx.SetStencil(STENCILMODE_NOT, stencilref_cutout)
@@ -1960,7 +1960,7 @@ runProcess(function()
info.SetShadowColor(Vector(0,0,0,1))
path.AddFont(info)
- LoadModel("../models/dojo.wiscene")
+ LoadModel(script_dir() .. "../models/dojo.wiscene")
-- Create the two player characters. Parameters are facing direction and material colors to differentiate between them:
-- Facing: skin color: shirt color hair color shoe color
@@ -2034,7 +2034,7 @@ runProcess(function()
backlog_post("RELOAD")
killProcesses()
application.SetActivePath(prevPath)
- dofile("fighting_game.lua")
+ dofile(script_dir() .. "fighting_game.lua")
return
end
diff --git a/Content/scripts/move_object.lua b/Content/scripts/move_object.lua
index d350b28e5..1a3e6f644 100644
--- a/Content/scripts/move_object.lua
+++ b/Content/scripts/move_object.lua
@@ -5,7 +5,7 @@ backlog_post("---> START SCRIPT: move_object.lua")
scene = GetScene()
scene.Clear()
-LoadModel("../models/teapot.wiscene")
+LoadModel(script_dir() .. "../models/teapot.wiscene")
top_entity = scene.Entity_FindByName("Top") -- query the teapot lid object by name
transform_component = scene.Component_GetTransform(top_entity)
rest_matrix = transform_component.GetMatrix()
diff --git a/Content/scripts/pick.lua b/Content/scripts/pick.lua
index edda30cce..7578026e6 100644
--- a/Content/scripts/pick.lua
+++ b/Content/scripts/pick.lua
@@ -5,7 +5,7 @@ backlog_post("---> START SCRIPT: pick.lua")
scene = GetScene()
scene.Clear()
-model_entity = LoadModel("../models/teapot.wiscene")
+model_entity = LoadModel(script_dir() .. "../models/teapot.wiscene")
runProcess(function()
local t = 0
diff --git a/Content/scripts/rotate_model.lua b/Content/scripts/rotate_model.lua
index cefe33749..138904983 100644
--- a/Content/scripts/rotate_model.lua
+++ b/Content/scripts/rotate_model.lua
@@ -5,7 +5,7 @@ backlog_post("---> START SCRIPT: rotate_model.lua")
scene = GetScene()
scene.Clear()
-model_entity = LoadModel("../models/teapot.wiscene")
+model_entity = LoadModel(script_dir() .. "../models/teapot.wiscene")
transform_component = scene.Component_GetTransform(model_entity)
runProcess(function()
diff --git a/Content/scripts/script_tracking.lua b/Content/scripts/script_tracking.lua
new file mode 100644
index 000000000..84b8668ec
--- /dev/null
+++ b/Content/scripts/script_tracking.lua
@@ -0,0 +1,81 @@
+-- This is a script which showcases the new path system for scripts, and new handling for processes
+
+-- There are new APIs exist too for managing scripts
+-- killProcess(coroutine) >>> To kill exactly one process if you know the coroutine,
+-- runProcess exposes this by returning two variables: success, and coroutine
+-- coroutine holds the index to kill this exact runProcess you're running
+-- killProcessPID(script_pid()) >>> To kill all processes within one instance of the script
+-- script_pid() are a local variable exposed to each script for the user to track and kill one full script
+-- killProcessFile(script_file()) >> To kill all instances of scripts which originates from one file
+-- script_pid() are a local variable exposed to each script for the user to track and kill all
+-- instances of scripts that uses the same file
+
+backlog_post("---> START SCRIPT: script_tracking.lua")
+
+-- Now you can track even the coroutine that the script has
+-- You can exactly kill this one coroutine by killing them like this: killProcess(proc_coroutine)
+local proc_success, proc_coroutine = runProcess(function()
+ -- If you want to do stuff once but never again on the next sequence of reloads, you can do it like this
+ -- (apply to any scripts you have their PID tracked on script too)
+ if not Script_Initialized(script_pid()) then
+ backlog_post("\n")
+ backlog_post("== Script INFO ==")
+ backlog_post("script_dir(): "..script_dir())
+ backlog_post("script_file(): "..script_file())
+ backlog_post("script_pid(): "..script_pid())
+ backlog_post("\n")
+
+ -- By using a global table you can keep code data across reloads
+ -- And if you want to keep each script instance separate you can use script_pid() to store the data
+ -- e.g D[script_pid()].counter = 0
+ D = {}
+ D.counter = 0
+
+ ClearWorld()
+ D.prevPath = application.GetActivePath()
+ D.path = RenderPath3D()
+ D.path.SetLightShaftsEnabled(true)
+ application.SetActivePath(D.path)
+
+ D.font = SpriteFont("");
+ D.font.SetSize(30)
+ D.font.SetPos(Vector(10, 10))
+ D.font.SetAlign(WIFALIGN_LEFT, WIFALIGN_TOP)
+ D.font.SetColor(0xFFADA3FF)
+ D.font.SetShadowColor(Vector(0,0,0,1))
+ D.path.AddFont(D.font)
+
+ -- With the new scripting system, use script_dir() string variable to load files relative to the script directory.
+ -- Also running a script can now return its PID, which you can use to kill the script you just launched in this script
+ -- Down below is a small demo to open a file on another script and open it relative to that script's path
+ D.subscript_PID = dofile(script_dir() .. "subscript_demo/load_dojo.lua", true)
+ backlog_post("subscript PID: "..D.subscript_PID)
+ end
+
+ while true do
+ D.counter = D.counter + 0.00001
+ -- Here's a fun thing: edit the text below and reload the script (press R)!
+ -- e.g "Hello There!"" to "Yeehaw"
+ D.font.SetText("Script directory: " .. script_dir() .. "\nScript file: " .. script_file() .. "\nScript PID: " .. script_pid() .. "\nPersistent counter value: " .. D.counter .. "\nSubscript PID: " .. D.subscript_PID)
+ update()
+ -- Here's an example on how to reload exactly this script
+ if(input.Press(string.byte('R'))) then
+ -- This is an example to restart a script using killProcessPID, to keep script PID add true to the argument
+ killProcessPID(script_pid(), true)
+ backlog_post("RESTART")
+ dofile(script_file(), script_pid())
+ return
+ end
+ if(input.Press(KEYBOARD_BUTTON_ESCAPE)) then
+ -- restore previous component
+ -- so if you loaded this script from the editor, you can go back to the editor with ESC
+ -- This is an example to exit a script using killProcessPID
+ killProcesses()
+ backlog_post("EXIT")
+ application.SetActivePath(D.prevPath)
+ return
+ end
+ end
+end)
+
+backlog_post("---> END SCRIPT: script_tracking.lua")
diff --git a/Content/scripts/set_material_color.lua b/Content/scripts/set_material_color.lua
index b7afffed4..f4a98c88c 100644
--- a/Content/scripts/set_material_color.lua
+++ b/Content/scripts/set_material_color.lua
@@ -5,7 +5,7 @@ backlog_post("---> START SCRIPT: set_material_color.lua")
scene = GetScene()
scene.Clear()
-LoadModel("../models/teapot.wiscene")
+LoadModel(script_dir() .. "../models/teapot.wiscene")
material_entity = scene.Entity_FindByName("teapot_material") -- query the teapot's material by name
material_component = scene.Component_GetMaterial(material_entity)
diff --git a/Content/scripts/set_material_emissive.lua b/Content/scripts/set_material_emissive.lua
index 0ae70201b..333edd2ec 100644
--- a/Content/scripts/set_material_emissive.lua
+++ b/Content/scripts/set_material_emissive.lua
@@ -5,7 +5,7 @@ backlog_post("---> START SCRIPT: set_material_color.lua")
scene = GetScene()
scene.Clear()
-LoadModel("../models/teapot.wiscene")
+LoadModel(script_dir() .. "../models/teapot.wiscene")
material_entity = scene.Entity_FindByName("teapot_material") -- query the teapot's material by name
material_component = scene.Component_GetMaterial(material_entity)
diff --git a/Content/scripts/subscript_demo/load_dojo.lua b/Content/scripts/subscript_demo/load_dojo.lua
new file mode 100644
index 000000000..40440ce54
--- /dev/null
+++ b/Content/scripts/subscript_demo/load_dojo.lua
@@ -0,0 +1,8 @@
+-- This script shows how content can be accessed relative to the current script directory
+-- This will work when calling scripts from scripts
+
+backlog_post("---> START SCRIPT: load_dojo.lua")
+
+LoadModel(script_dir() .. "../../models/dojo.wiscene")
+
+backlog_post("---> END SCRIPT: load_dojo.lua")
diff --git a/Editor/Editor_UWP.vcxproj b/Editor/Editor_UWP.vcxproj
index 04c7af2a5..21fab2a9e 100644
--- a/Editor/Editor_UWP.vcxproj
+++ b/Editor/Editor_UWP.vcxproj
@@ -152,6 +152,17 @@
+
+
+ Document
+
+
+ Document
+
+
+ Document
+
+
diff --git a/WickedEngine/wiAudio_BindLua.cpp b/WickedEngine/wiAudio_BindLua.cpp
index 2ca18e94c..1c241c1f7 100644
--- a/WickedEngine/wiAudio_BindLua.cpp
+++ b/WickedEngine/wiAudio_BindLua.cpp
@@ -34,7 +34,7 @@ namespace wi::lua
Sound_BindLua* sound = Luna::lightcheck(L, 2);
if (sound != nullptr)
{
- bool result = wi::audio::CreateSound(wi::lua::GetScriptPath() + wi::lua::SGetString(L, 1), &sound->sound);
+ bool result = wi::audio::CreateSound(wi::lua::SGetString(L, 1), &sound->sound);
wi::lua::SSetBool(L, result);
}
else
diff --git a/WickedEngine/wiLua.cpp b/WickedEngine/wiLua.cpp
index 0c2d7ab0e..76d367a14 100644
--- a/WickedEngine/wiLua.cpp
+++ b/WickedEngine/wiLua.cpp
@@ -42,7 +42,44 @@ namespace wi::lua
}
};
LuaInternal luainternal;
- std::string script_path;
+
+ uint32_t Internal_GenScriptPID(){
+ static std::atomic scriptpid_next{ 0 + 1 };
+ return scriptpid_next.fetch_add(1);
+ }
+
+ uint32_t Internal_EncapsulateScript(std::string& script, const std::string& filename = "", uint32_t PID = 0){
+ static const std::string persistent_inject = R"(
+ local runProcess = function(func)
+ success, co = Internal_runProcess(script_file(), script_pid(), func)
+ return success, co
+ end
+ if _ENV.PROCESSES_DATA[script_pid()] == nil then
+ _ENV.PROCESSES_DATA[script_pid()] = { _INITIALIZED = -1 }
+ end
+ if _ENV.PROCESSES_DATA[script_pid()]._INITIALIZED < 1 then
+ _ENV.PROCESSES_DATA[script_pid()]._INITIALIZED = _ENV.PROCESSES_DATA[script_pid()]._INITIALIZED + 1
+ end
+ )";
+
+ if(PID == 0){
+ PID = Internal_GenScriptPID();
+ }
+
+ // Make sure the file path doesn't contain backslash characters, replace them with forward slash.
+ // - backslash would be recognized by lua as escape character
+ // - the path string could be coming from unknown location (content, programmer, filepicker), so always do this
+ std::string filepath = filename;
+ std::replace(filepath.begin(), filepath.end(), '\\', '/');
+
+ std::string dynamic_inject = "local function script_file() return \""+ filepath +"\" end\n";
+ dynamic_inject += "local function script_pid() return \""+std::to_string(PID)+"\" end\n";
+ dynamic_inject += "local function script_dir() return \""+wi::helper::GetDirectoryFromPath(filepath)+"\" end\n";
+ dynamic_inject += persistent_inject;
+ script = dynamic_inject + script;
+
+ return PID;
+ }
int Internal_DoFile(lua_State* L)
{
@@ -50,17 +87,25 @@ namespace wi::lua
if (argc > 0)
{
+ bool fixedpath = false;
+ uint32_t PID = 0;
+
std::string filename = SGetString(L, 1);
- filename = script_path + filename;
+ if(argc >= 2) PID = SGetInt(L, 2);
+
wi::vector filedata;
+
if (wi::helper::FileRead(filename, filedata))
{
- script_path = wi::helper::GetDirectoryFromPath(filename);
std::string command = std::string(filedata.begin(), filedata.end());
+ PID = Internal_EncapsulateScript(command, filename, PID);
+
int status = luaL_loadstring(L, command.c_str());
if (status == 0)
{
status = lua_pcall(L, 0, LUA_MULTRET, 0);
+ auto return_PID = std::to_string(PID);
+ SSetString(L, return_PID);
}
else
{
@@ -82,7 +127,7 @@ namespace wi::lua
SError(L, "dofile(string filename) not enough arguments!");
}
- return 0;
+ return 1;
}
void Initialize()
@@ -164,8 +209,9 @@ namespace wi::lua
wi::vector filedata;
if (wi::helper::FileRead(filename, filedata))
{
- script_path = wi::helper::GetDirectoryFromPath(filename);
- return RunText(std::string(filedata.begin(), filedata.end()));
+ auto script = std::string(filedata.begin(), filedata.end());
+ Internal_EncapsulateScript(script, filename);
+ return RunText(script);
}
return false;
}
@@ -238,10 +284,6 @@ namespace wi::lua
lua_pushinteger(luainternal.m_luaState, data);
lua_setfield(luainternal.m_luaState, -2, name.c_str());
}
- const std::string& GetScriptPath()
- {
- return script_path;
- }
void SetDeltaTime(double dt)
{
diff --git a/WickedEngine/wiLua.h b/WickedEngine/wiLua.h
index 5d1ea707b..ba8172638 100644
--- a/WickedEngine/wiLua.h
+++ b/WickedEngine/wiLua.h
@@ -45,8 +45,6 @@ namespace wi::lua
void AddFuncArray(const luaL_Reg* functions);
//add int member to registered object
void AddInt(const std::string& name, int data);
- //returns the path of the last executed script:
- const std::string& GetScriptPath();
//set delta time to use with lua
void SetDeltaTime(double dt);
diff --git a/WickedEngine/wiLua_Globals.h b/WickedEngine/wiLua_Globals.h
index 33c329ff3..8d181947e 100644
--- a/WickedEngine/wiLua_Globals.h
+++ b/WickedEngine/wiLua_Globals.h
@@ -83,7 +83,7 @@ function runProcess(func)
if not success then
error("[Lua Error] "..errorMsg)
end
- return success
+ return success, co
end
-- Signal helpers
@@ -125,6 +125,96 @@ function killProcesses()
WAITING_ON_TIME = {}
end
+-- Kill one process, has to know the coroutine first
+function killProcess(co)
+ for signalName, threads in pairs(WAITING_ON_SIGNAL) do
+ for index, co in ipairs(threads) do
+ threads[index] = nil
+ break
+ end
+ end
+ if WAITING_ON_TIME[co] ~= nil then
+ WAITING_ON_TIME[co] = nil
+ end
+end
+
+-- Track processes by PID and File, useful when you want to kill specifically by file or pid
+local PROCESSES_PID = {}
+local PROCESSES_FILE = {}
+PROCESSES_DATA = {}
+
+-- This is for the new runprocess which now handles tracking script PID and file
+-- There is a hook function that exists on the script side
+function Internal_runProcess(file, pid, func)
+ local co = coroutine.create(func)
+ local success, errorMsg = coroutine.resume(co)
+ if not success then
+ error("[Lua Error] "..errorMsg)
+ end
+ if (file == "-") and (pid == 1) then
+ return success, co
+ end
+
+ if PROCESSES_PID[pid] == nil then
+ PROCESSES_PID[pid] = {}
+ end
+ PROCESSES_PID[pid][1] = file
+ if PROCESSES_PID[pid][2] == nil then
+ PROCESSES_PID[pid][2] = {}
+ end
+ table.insert(PROCESSES_PID[pid][2], co)
+ if PROCESSES_FILE[file] == nil then
+ PROCESSES_FILE[file] = {}
+ end
+ PROCESSES_FILE[file][pid] = 1
+ return success, co
+end
+
+-- To check if the script has already been initialized
+function Script_Initialized(pid)
+ local result = true
+ if PROCESSES_DATA[pid]._INITIALIZED == 0 then
+ result = false
+ end
+ return result
+end
+
+-- To kill processes by PID and File is exposed using these two functions below
+function killProcessPID(...)
+ local argc = {...}
+ if #argc > 0 then
+ local pid = argc[1]
+ if PROCESSES_PID[pid] ~= nil then
+ for _, co in ipairs(PROCESSES_PID[pid][2]) do
+ killProcess(co)
+ end
+ end
+ PROCESSES_PID[pid] = nil
+ if #argc < 2 then
+ PROCESSES_DATA[pid] = nil
+ untrack_pid(pid)
+ end
+ end
+end
+
+-- Kill process by file which each file has sets of PID, then kill by all PIDs known by the file
+function killProcessFile(...)
+ local argc = {...}
+ if #argc > 0 then
+ local file = argc[1]
+ if PROCESSES_FILE[file] ~= nil then
+ for pid, _ in pairs(PROCESSES_FILE[file]) do
+ if #argc >= 2 then
+ killProcessPID(pid, true)
+ else
+ killProcessPID(pid)
+ end
+ end
+ end
+ PROCESSES_FILE[file] = nil
+ end
+end
+
-- Store the delta time for the current frame
local lastDeltaTime = 0
function setDeltaTime(dt)
diff --git a/WickedEngine/wiRenderer_BindLua.cpp b/WickedEngine/wiRenderer_BindLua.cpp
index bb5a53e6f..ea2d5dea6 100644
--- a/WickedEngine/wiRenderer_BindLua.cpp
+++ b/WickedEngine/wiRenderer_BindLua.cpp
@@ -360,7 +360,7 @@ namespace wi::lua::renderer
{
XMFLOAT3 pos;
XMStoreFloat3(&pos, XMLoadFloat4(v));
- GetGlobalScene()->PutWaterRipple(wi::lua::GetScriptPath() + name, pos);
+ GetGlobalScene()->PutWaterRipple(name, pos);
}
else
wi::lua::SError(L, "PutWaterRipple(String imagename, Vector position) argument is not a Vector!");
diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp
index 426e806eb..4b37d2399 100644
--- a/WickedEngine/wiScene_BindLua.cpp
+++ b/WickedEngine/wiScene_BindLua.cpp
@@ -61,7 +61,6 @@ int LoadModel(lua_State* L)
if (argc > 1)
{
std::string fileName = wi::lua::SGetString(L, 2);
- fileName = wi::lua::GetScriptPath() + fileName;
XMMATRIX transform = XMMatrixIdentity();
if (argc > 2)
{
@@ -89,7 +88,6 @@ int LoadModel(lua_State* L)
{
// Overload 2: global scene version
std::string fileName = wi::lua::SGetString(L, 1);
- fileName = wi::lua::GetScriptPath() + fileName;
XMMATRIX transform = XMMatrixIdentity();
if (argc > 1)
{
diff --git a/WickedEngine/wiSprite_BindLua.cpp b/WickedEngine/wiSprite_BindLua.cpp
index 9aad8b4ec..a0fc10f15 100644
--- a/WickedEngine/wiSprite_BindLua.cpp
+++ b/WickedEngine/wiSprite_BindLua.cpp
@@ -30,11 +30,9 @@ namespace wi::lua
if (argc > 0)
{
name = wi::lua::SGetString(L, 1);
- name = wi::lua::GetScriptPath() + name;
if (argc > 1)
{
mask = wi::lua::SGetString(L, 2);
- mask = wi::lua::GetScriptPath() + mask;
}
}
sprite = wi::Sprite(name, mask);
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index d25cc24d0..c22d6239f 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -7,9 +7,9 @@ namespace wi::version
// main engine core
const int major = 0;
// minor features, major updates, breaking compatibility changes
- const int minor = 70;
+ const int minor = 71;
// minor bug fixes, alterations, refactors, updates
- const int revision = 22;
+ const int revision = 0;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);