diff --git a/Content/Documentation/ScriptingAPI-Documentation.md b/Content/Documentation/ScriptingAPI-Documentation.md
index b49d26eb8..adce9bd6d 100644
--- a/Content/Documentation/ScriptingAPI-Documentation.md
+++ b/Content/Documentation/ScriptingAPI-Documentation.md
@@ -22,6 +22,7 @@ This is a reference and explanation of Lua scripting features in Wicked Engine.
3. [SoundInstance3D](#soundinstance3d)
7. [Vector](#vector)
8. [Matrix](#matrix)
+ 8. [Async](#async)
9. [Scene](#scene)
1. [Entity](#entity)
2. [Scene](#scene)
@@ -641,6 +642,13 @@ A four by four matrix, efficient calculations with SIMD support.
- GetRight(Matrix mat) : Vector -- returns right direction of parameter matrix
+### Async
+The Async object can be used for tracking or Wait for completion of functions that are running on background threads.
+
+- [constructor]Async() -- constructs a new Async tracker object
+- Wait() -- wait for completion of async tasks on this tracker
+- IsCompleted() : bool -- checks if all async tasks on this tracker have been completed
+
### Scene System (using entity-component system)
Manipulate the 3D scene with these components.
@@ -676,11 +684,13 @@ The scene holds components. Entity handles can be used to retrieve associated co
- Clear() -- deletes every entity and component inside the scene
- Merge(Scene other) -- moves contents from an other scene into this one. The other scene will be empty after this operation (contents are moved, not copied)
- UpdateHierarchy() -- updates the full scene hierarchy system. Useful if you modified for example a parent transform and children immediately need up to date result in the script
+- Instantiate(Scene prefab, opt bool attached = false) : Entity -- Duplicates everything in the prefab scene into the current scene. If attached parameter is st to `true` then everything in prefab scene will be attached to a common root entity (with TransformComponent and LayerComponent) and the function will return that root entity.
- CreateEntity() : int entity -- creates an empty entity and returns it
- FindAllEntities() : table[entities] -- returns a table with all the entities present in the given scene
- Entity_FindByName(string value, opt Entity ancestor = INVALID_ENTITY) : int entity -- returns an entity ID if it exists, and INVALID_ENTITY otherwise. You can specify an ancestor entity if you only want to find entities that are descendants of ancestor entity
- Entity_Remove(Entity entity, bool recursive = true, bool keep_sorted = false) -- removes an entity and deletes all its components if it exists. If recursive is specified, then all children will be removed as well (enabled by default). If keep_sorted is specified, then component order will be kept (disabled by default, slower)
+- Entity_Remove_Async(Async async, Entity entity, bool recursive = true, bool keep_sorted = false) -- Same as Entity_Remove, but it runs on a background thread, status can be tracked by the [Async](#async) object that you provide
- Entity_Duplicate(Entity entity) : int entity -- duplicates all of an entity's components and creates a new entity with them. Returns the clone entity handle
- Entity_IsDescendant(Entity entity, Entity ancestor) : bool result -- Check whether entity is a descendant of ancestor. Returns `true` if entity is in the hierarchy tree of ancestor, `false` otherwise
diff --git a/WickedEngine/CMakeLists.txt b/WickedEngine/CMakeLists.txt
index 2970fd580..918811ba0 100644
--- a/WickedEngine/CMakeLists.txt
+++ b/WickedEngine/CMakeLists.txt
@@ -152,6 +152,7 @@ set(HEADER_FILES
wiPathQuery_BindLua.h
wiTrailRenderer.h
wiTrailRenderer_BindLua.h
+ wiAsync_BindLua.h
)
add_library(${TARGET_NAME} ${WICKED_LIBRARY_TYPE}
@@ -232,6 +233,7 @@ add_library(${TARGET_NAME} ${WICKED_LIBRARY_TYPE}
wiPathQuery_BindLua.cpp
wiTrailRenderer.cpp
wiTrailRenderer_BindLua.cpp
+ wiAsync_BindLua.cpp
${HEADER_FILES}
)
add_library(WickedEngine ALIAS ${TARGET_NAME})
diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems b/WickedEngine/WickedEngine_SOURCE.vcxitems
index 05ddddd6f..a277cd091 100644
--- a/WickedEngine/WickedEngine_SOURCE.vcxitems
+++ b/WickedEngine/WickedEngine_SOURCE.vcxitems
@@ -236,6 +236,7 @@
+
@@ -521,6 +522,7 @@
+
diff --git a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters
index af629b040..c5e58a0af 100644
--- a/WickedEngine/WickedEngine_SOURCE.vcxitems.filters
+++ b/WickedEngine/WickedEngine_SOURCE.vcxitems.filters
@@ -1143,6 +1143,9 @@
ENGINE\Scripting\LuaBindings
+
+ ENGINE\Scripting\LuaBindings
+
@@ -1916,6 +1919,9 @@
ENGINE\Scripting\LuaBindings
+
+ ENGINE\Scripting\LuaBindings
+
diff --git a/WickedEngine/wiAsync_BindLua.cpp b/WickedEngine/wiAsync_BindLua.cpp
new file mode 100644
index 000000000..34074e71b
--- /dev/null
+++ b/WickedEngine/wiAsync_BindLua.cpp
@@ -0,0 +1,34 @@
+#include "wiAsync_BindLua.h"
+
+namespace wi::lua
+{
+ Luna::FunctionType Async_BindLua::methods[] = {
+ lunamethod(Async_BindLua, Wait),
+ lunamethod(Async_BindLua, IsCompleted),
+ { NULL, NULL }
+ };
+ Luna::PropertyType Async_BindLua::properties[] = {
+ { NULL, NULL }
+ };
+
+ int Async_BindLua::Wait(lua_State* L)
+ {
+ wi::jobsystem::Wait(ctx);
+ return 0;
+ }
+ int Async_BindLua::IsCompleted(lua_State* L)
+ {
+ wi::lua::SSetBool(L, wi::jobsystem::IsBusy(ctx) == false);
+ return 1;
+ }
+
+ void Async_BindLua::Bind()
+ {
+ static bool initialized = false;
+ if (!initialized)
+ {
+ initialized = true;
+ Luna::Register(wi::lua::GetLuaState());
+ }
+ }
+}
diff --git a/WickedEngine/wiAsync_BindLua.h b/WickedEngine/wiAsync_BindLua.h
new file mode 100644
index 000000000..21ce927c1
--- /dev/null
+++ b/WickedEngine/wiAsync_BindLua.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "wiLua.h"
+#include "wiLuna.h"
+#include "wiJobSystem.h"
+
+namespace wi::lua
+{
+ class Async_BindLua
+ {
+ public:
+ wi::jobsystem::context ctx;
+ inline static constexpr char className[] = "Async";
+ static Luna::FunctionType methods[];
+ static Luna::PropertyType properties[];
+
+ Async_BindLua() = default;
+ Async_BindLua(lua_State* L) {}
+
+ int Wait(lua_State* L);
+ int IsCompleted(lua_State* L);
+
+ static void Bind();
+ };
+}
diff --git a/WickedEngine/wiLua.cpp b/WickedEngine/wiLua.cpp
index 7ee7634e6..638147021 100644
--- a/WickedEngine/wiLua.cpp
+++ b/WickedEngine/wiLua.cpp
@@ -24,6 +24,7 @@
#include "wiVoxelGrid_BindLua.h"
#include "wiPathQuery_BindLua.h"
#include "wiTrailRenderer_BindLua.h"
+#include "wiAsync_BindLua.h"
#include "wiTimer.h"
#include "wiVector.h"
@@ -234,6 +235,7 @@ namespace wi::lua
VoxelGrid_BindLua::Bind();
PathQuery_BindLua::Bind();
TrailRenderer_BindLua::Bind();
+ Async_BindLua::Bind();
wi::backlog::post("wi::lua Initialized (" + std::to_string((int)std::round(timer.elapsed())) + " ms)");
}
diff --git a/WickedEngine/wiLuna.h b/WickedEngine/wiLuna.h
index 9117caf65..75d3bbd8c 100644
--- a/WickedEngine/wiLuna.h
+++ b/WickedEngine/wiLuna.h
@@ -160,7 +160,7 @@ public:
Loads an instance of the class into the Lua stack, and provides you a pointer so you can modify it.
*/
template
- static void push(lua_State * L, ARG&&... args)
+ static T* push(lua_State * L, ARG&&... args)
{
T **a = (T **)lua_newuserdata(L, sizeof(T *)); // Create userdata
*a = allocator.allocate(std::forward(args)...);
@@ -168,6 +168,7 @@ public:
luaL_getmetatable(L, T::className);
lua_setmetatable(L, -2);
+ return *a;
}
// Pushes an instance and registers it into a global object
diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp
index 47a8f7eb2..94a6d260b 100644
--- a/WickedEngine/wiScene_BindLua.cpp
+++ b/WickedEngine/wiScene_BindLua.cpp
@@ -12,6 +12,7 @@
#include "wiUnorderedMap.h"
#include "wiVoxelGrid_BindLua.h"
#include "wiAudio_BindLua.h"
+#include "wiAsync_BindLua.h"
#include
@@ -521,6 +522,7 @@ Luna::FunctionType Scene_BindLua::methods[] = {
lunamethod(Scene_BindLua, FindAllEntities),
lunamethod(Scene_BindLua, Entity_FindByName),
lunamethod(Scene_BindLua, Entity_Remove),
+ lunamethod(Scene_BindLua, Entity_Remove_Async),
lunamethod(Scene_BindLua, Entity_Duplicate),
lunamethod(Scene_BindLua, Entity_IsDescendant),
lunamethod(Scene_BindLua, Component_CreateName),
@@ -812,6 +814,40 @@ int Scene_BindLua::Entity_Remove(lua_State* L)
}
return 0;
}
+int Scene_BindLua::Entity_Remove_Async(lua_State* L)
+{
+ int argc = wi::lua::SGetArgCount(L);
+ if (argc > 1)
+ {
+ Async_BindLua* async = Luna::lightcheck(L, 1);
+ if (async == nullptr)
+ {
+ wi::lua::SError(L, "Scene::Entity_Remove_Async(Async async, Entity entity) first argument is not an Async!");
+ return 0;
+ }
+ Entity entity = (Entity)wi::lua::SGetLongLong(L, 2);
+ bool recursive = true;
+ bool keep_sorted = false;
+
+ if (argc > 2)
+ {
+ recursive = wi::lua::SGetBool(L, 3);
+ if (argc > 3)
+ {
+ keep_sorted = wi::lua::SGetBool(L, 4);
+ }
+ }
+
+ wi::jobsystem::Execute(async->ctx, [=](wi::jobsystem::JobArgs args) {
+ scene->Entity_Remove(entity, recursive, keep_sorted);
+ });
+ }
+ else
+ {
+ wi::lua::SError(L, "Scene::Entity_Remove_Async(Async async, Entity entity) not enough arguments!");
+ }
+ return 0;
+}
int Scene_BindLua::Entity_Duplicate(lua_State* L)
{
int argc = wi::lua::SGetArgCount(L);
diff --git a/WickedEngine/wiScene_BindLua.h b/WickedEngine/wiScene_BindLua.h
index c1c4fceb7..0577d99e7 100644
--- a/WickedEngine/wiScene_BindLua.h
+++ b/WickedEngine/wiScene_BindLua.h
@@ -44,6 +44,7 @@ namespace wi::lua::scene
int FindAllEntities(lua_State* L);
int Entity_FindByName(lua_State* L);
int Entity_Remove(lua_State* L);
+ int Entity_Remove_Async(lua_State* L);
int Entity_Duplicate(lua_State* L);
int Entity_IsDescendant(lua_State* L);
diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp
index f5d00b82a..b290c2ab2 100644
--- a/WickedEngine/wiVersion.cpp
+++ b/WickedEngine/wiVersion.cpp
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
- const int revision = 454;
+ const int revision = 455;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);