diff --git a/.gitignore b/.gitignore index 636ea36..f2e30a3 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,8 @@ !.gitignore !codecov.yml !skeleton.html -!meson.build +!**/meson.build +!**/*.wrap !meson_options.txt !compile_wasm.py !compile_android.py \ No newline at end of file diff --git a/README.md b/README.md index b223f72..d70058c 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,6 @@ There are some assumptions that should be considered when developing application * Better EventManager - there are several optimization and improvements that can be added in the future. * More demos and examples - demo appliaction is very basic now, but in future more minigames and sanbox mode (opportunity to mix many components and systems) are planned. * C API - in highly depends on amount of work required. Makes possible to use library from different languages. - * GPU compute - idea in draft stage. Special components and systems whose data wolud be on GPU memory. * More smaller improvements... For more information about design and usage feel free to read [documentation](https://mergul.gitlab.io/bubel-ecs/ecs.html)**(WIP)** and [WIKI](https://gitlab.com/Mergul/bubel-ecs/-/wikis/home). @@ -104,14 +103,12 @@ Online demo support multithreading and page tries to check if client support WAS struct Position { - mixin ECS.Components; //makes struct component float x; float y; } struct Velocity { - mixin ECS.Components; //default values works float x = 0.1; float y = 1; @@ -119,7 +116,6 @@ struct Velocity struct StaticFlag { - mixin ECS.Components; } struct UpdateSystem @@ -132,7 +128,7 @@ struct UpdateSystem { int length; //entities count @readonly Entity[] entities; //entities arrays, entity contain ID only - Position[] positions; //positions array + Position[] positions; //positions array, by default components are considered to has write access (used for multithreading dependencies) @readonly Velocity[] velocities; //veocities array, readonly (Multithreading tag) } @@ -158,7 +154,7 @@ void main() manager.endRegister(); //allocate template - EntityTemplate* tmpl = manager.allocateEmplate([Velocity.component_id, Position.component_id].staticArray); + EntityTemplate* tmpl = manager.allocateEmplate([becsID!Velocity, becsID!Position].staticArray); scope (exit) manager.freeTemplate(tmpl); //gets pointer to template component data @@ -170,9 +166,9 @@ void main() manager.addEntity(tmpl); } - manager.begin(); //start frame + manager.begin(); //start frame, inside system onBegin callbacks are called manager.update(); //update all systems, there onUpdate callbacks are called - manager.end(); //end frame + manager.end(); //end frame, inside system onEnd callbacks are called } ``` diff --git a/demos/.gitignore b/demos/.gitignore index d74e2b0..d137ce7 100644 --- a/demos/.gitignore +++ b/demos/.gitignore @@ -15,5 +15,6 @@ !emscripten_shell.html !emscripten_multi_shell.html !compile_android.py +!**/meson.build .dub Android \ No newline at end of file diff --git a/demos/assets/shaders/additive_particles.fp b/demos/assets/shaders/additive_particles.fp index 047f647..df711a2 100644 --- a/demos/assets/shaders/additive_particles.fp +++ b/demos/assets/shaders/additive_particles.fp @@ -1,10 +1,9 @@ -precision mediump int; -precision mediump float; -precision lowp sampler2D; -precision lowp samplerCube; - #ifdef GLES + precision mediump int; + precision mediump float; + precision lowp sampler2D; + precision lowp samplerCube; #define TEX(x,y) texture2D(x,y) #if __VERSION__ >290 #define M_IN in mediump diff --git a/demos/assets/shaders/additive_particles.vp b/demos/assets/shaders/additive_particles.vp index 2777a24..cf90081 100644 --- a/demos/assets/shaders/additive_particles.vp +++ b/demos/assets/shaders/additive_particles.vp @@ -1,8 +1,9 @@ -precision highp float; -precision highp int; -precision lowp sampler2D; -precision lowp samplerCube; + #ifdef GLES + precision highp float; + precision highp int; + precision lowp sampler2D; + precision lowp samplerCube; #if __VERSION__ >290 #define LOC(x) layout(location = x) #define ATT in diff --git a/demos/assets/shaders/base.fp b/demos/assets/shaders/base.fp index d86e92e..d667b24 100644 --- a/demos/assets/shaders/base.fp +++ b/demos/assets/shaders/base.fp @@ -1,10 +1,9 @@ -precision mediump int; -precision mediump float; -precision lowp sampler2D; -precision lowp samplerCube; - #ifdef GLES + precision mediump int; + precision mediump float; + precision lowp sampler2D; + precision lowp samplerCube; #define TEX(x,y) texture2D(x,y) #if __VERSION__ >290 #define M_IN in mediump @@ -14,11 +13,12 @@ precision lowp samplerCube; #define L_IN varying lowp #endif #else - #define TEX(x,y) texture(x,y) #if __VERSION__ > 320 + #define TEX(x,y) texture(x,y) #define M_IN in #define L_IN in #else + #define TEX(x,y) texture2D(x,y) #define M_IN varying #define L_IN varying #endif diff --git a/demos/assets/shaders/base.vp b/demos/assets/shaders/base.vp index 6c4c183..333ae59 100644 --- a/demos/assets/shaders/base.vp +++ b/demos/assets/shaders/base.vp @@ -1,8 +1,9 @@ -precision highp float; -precision highp int; -precision lowp sampler2D; -precision lowp samplerCube; + #ifdef GLES + precision highp float; + precision highp int; + precision lowp sampler2D; + precision lowp samplerCube; #if __VERSION__ >290 #define LOC(x) layout(location = x) #define ATT in diff --git a/demos/assets/shaders/circle.fp b/demos/assets/shaders/circle.fp index 15f46fd..dd0449c 100644 --- a/demos/assets/shaders/circle.fp +++ b/demos/assets/shaders/circle.fp @@ -1,10 +1,9 @@ -precision mediump int; -precision mediump float; -precision lowp sampler2D; -precision lowp samplerCube; - #ifdef GLES + precision mediump int; + precision mediump float; + precision lowp sampler2D; + precision lowp samplerCube; #define TEX(x,y) texture2D(x,y) #if __VERSION__ >290 #define M_IN in mediump diff --git a/demos/assets/shaders/circle.vp b/demos/assets/shaders/circle.vp index 6997121..9c1b85c 100644 --- a/demos/assets/shaders/circle.vp +++ b/demos/assets/shaders/circle.vp @@ -1,8 +1,9 @@ -precision highp float; -precision highp int; -precision lowp sampler2D; -precision lowp samplerCube; + #ifdef GLES + precision highp float; + precision highp int; + precision lowp sampler2D; + precision lowp samplerCube; #if __VERSION__ >290 #define LOC(x) layout(location = x) #define ATT in diff --git a/demos/external/meson.build b/demos/external/meson.build new file mode 100644 index 0000000..0bfd84c --- /dev/null +++ b/demos/external/meson.build @@ -0,0 +1,12 @@ +demos_src += files( + 'sources/cimgui/cimgui.d', + 'sources/glad/gl/all.d', + 'sources/glad/gl/enums.d', + 'sources/glad/gl/ext.d', + 'sources/glad/gl/funcs.d', + 'sources/glad/gl/gl.d', + 'sources/glad/gl/gles2.d', + 'sources/glad/gl/loader.d', + 'sources/glad/gl/types.d', + 'sources/mmutils/thread_pool.d', +) \ No newline at end of file diff --git a/demos/meson.build b/demos/meson.build new file mode 100644 index 0000000..20df64c --- /dev/null +++ b/demos/meson.build @@ -0,0 +1,35 @@ +# Files +demos_src = files() +external_src = files() +subdir('source') +subdir('external') + +demos_inc = include_directories('source/') +external_inc = include_directories('external/sources/') + +# Argumesnts +versions = ['BindSDL_Image','SDL_208', 'BindBC_Static', 'BindSDL_Static'] + +# Dependencies +bindbc_loader_dep = dependency('bindbc-loader') +bindbc_sdl_dep = dependency('bindbc-sdl') +cimgui_dep = dependency('cimgui') +sdl2_dep = dependency('SDL2') +sdl2_image_dep = dependency('SDL2_image') + +subdir('utils') # Utils library + +executable('decs-demos', [demos_src, external_src], + include_directories : [demos_inc, external_inc], + d_module_versions : versions, + link_with : [ecs_lib, ecs_utils_lib], + dependencies : [ + bindbc_loader_dep, + bindbc_sdl_dep, + cimgui_dep, + decs_dep, + ecs_utils_dep, + sdl2_dep, + sdl2_image_dep, + ], +) \ No newline at end of file diff --git a/demos/source/app.d b/demos/source/app.d index 08c154c..fa77aac 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -75,6 +75,7 @@ struct Launcher double delta_time; uint fps; vec2 render_position; + bool play = true; Tool used_tool; int tool_size = 100; @@ -85,6 +86,7 @@ struct Launcher bool tool_mode = true; ToolCircle* tool_circle; bool show_filtered; + EntityID selected_entity; bool swap_interval = true; @@ -95,6 +97,7 @@ struct Launcher bool show_stat_wnd = true; bool show_tips = true; bool show_demo_wnd = true; + bool show_tools_wnd = true; bool show_virtual_keys_wnd = false; bool show_profile_wnd = true; @@ -110,10 +113,16 @@ struct Launcher float draw_time = 0; } + double deltaTime() + { + return delta_time * play; + } + DemoCallbacks demo; void switchDemo(DemoCallbacks callbacks)//void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, const (char)* tips) { + show_tips = true; gui_manager.clear(); //launcher.ent @@ -164,6 +173,7 @@ struct Launcher ComponentRef[] add_comps; ushort[] rem_comps; ushort[] filter; + float distance = float.max; bool filterEntity(ref const Entity entity) { @@ -222,6 +232,21 @@ struct Launcher if(length < size2)gEM.removeComponents(data.entity[i].id, rem_comps); } } + + void selectEntity(IteratorSystem.EntitiesData data) + { + if(!filterEntity(data.entity[0]))return; + foreach(i;0..data.length) + { + vec2 rel_vec = data.location[i] - position; + float length = rel_vec.x * rel_vec.x + rel_vec.y * rel_vec.y; + if(length < distance) + { + distance = length; + launcher.selected_entity = data.entity[i].id; + } + } + } } float half_size = tool_size * 0.5; @@ -276,6 +301,10 @@ struct Launcher } } break; + case Tool.selector: + iterator.distance = size2; + manager.callEntitiesFunction!IteratorSystem(&iterator.selectEntity); + break; default: break; } @@ -717,12 +746,14 @@ void mainLoop(void* arg) if(launcher.show_tips) { - igSetNextWindowPos(ImVec2(launcher.window_size.x - 550, 80), ImGuiCond_Once, ImVec2(0,0)); - igSetNextWindowSize(ImVec2(300, 0), ImGuiCond_Once); - igSetNextWindowBgAlpha(launcher.windows_alpha); + igSetNextWindowPos(ImVec2(launcher.window_size.x /2 -250, 100), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(500, -1), ImGuiCond_Once); + igSetNextWindowBgAlpha(0.95); if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) { + // igBeginChild("",ImVec2(0,0),0,0); igTextWrapped(launcher.demo.tips); + // igEndChild(); } igEnd(); } @@ -730,9 +761,10 @@ void mainLoop(void* arg) if(launcher.show_demo_wnd) { igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, 30), ImGuiCond_Once, ImVec2(0,0)); - igSetNextWindowSize(ImVec2(250, launcher.window_size.y - 60), ImGuiCond_Once); + igSetNextWindowSize(ImVec2(250, 300), ImGuiCond_Once); if(igBegin("Demo",&launcher.show_demo_wnd,0)) { + igCheckbox("Play",&launcher.play); ImDrawList* draw_list = igGetWindowDrawList(); igBeginGroup(); launcher.gui_manager.gui(); @@ -742,11 +774,11 @@ void mainLoop(void* arg) //ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), -1, 0, 1); //igBeginChildFrame(1,ImVec2(0,-1),ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_ChildWindow); //igBeginChild("Tool frame",ImVec2(-1,-1),true,0); - igBeginGroup(); - if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) - { - igIndent(8); - if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0)) + // igBeginGroup(); + // if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) + // { + // igIndent(8); + /*if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0)) { if(igSelectable("Entity spawner",false,0,ImVec2(0,0))) { @@ -761,8 +793,48 @@ void mainLoop(void* arg) launcher.used_tool = Tool.selector; } igEndCombo(); + }*/ + /*if(igSelectable("Entity spawner",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.entity_spawner; } - if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); + if(igSelectable("Component manipulator",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.component_manipulator; + } + if(igSelectable("Selector",false,0,ImVec2(0,0))) + { + launcher.used_tool = Tool.selector; + }*/ + /*if(igBeginTabBar("Tool",ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) + { + if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); + bool a = 1; + //this is used as hack to make CTRL+1/2/3 tab selection possible + static Tool prev_tool = Tool.entity_spawner; + bool different = prev_tool != launcher.used_tool; + Tool tool; + if(igBeginTabItem("Entity spawner", &a, launcher.used_tool == Tool.entity_spawner && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.entity_spawner; + igEndTabItem(); + } + if(igBeginTabItem("Component manipulator", &a, launcher.used_tool == Tool.component_manipulator && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.component_manipulator; + igEndTabItem(); + } + if(igBeginTabItem("Selector", &a, launcher.used_tool == Tool.selector && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.selector; + igEndTabItem(); + } + launcher.used_tool = tool; + prev_tool = launcher.used_tool; + } + igEndTabBar(); + + igCheckbox("Show Tool", &launcher.tool_show); if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); igSameLine(0,4); @@ -785,10 +857,11 @@ void mainLoop(void* arg) igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); - launcher.gui_manager.toolGui(); - igUnindent(8); - } - igEndGroup(); + launcher.gui_manager.toolGui();*/ + + // igUnindent(8); + // } + // igEndGroup(); ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 2, ImDrawCornerFlags_All, 1); //igBeginGroup(); @@ -813,6 +886,75 @@ void mainLoop(void* arg) igEnd(); } + if(launcher.show_tools_wnd) + { + + igSetNextWindowPos(ImVec2(launcher.window_size.x - 300, 340), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowSize(ImVec2(300, launcher.window_size.y - 370), ImGuiCond_Once); + if(igBegin("Tools", &launcher.show_tools_wnd, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) + { + if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); + + if(igBeginTabBar("Tool",ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) + { + bool a = 1; + //this is used as hack to make CTRL+1/2/3 tab selection possible + static Tool prev_tool = Tool.entity_spawner; + bool different = prev_tool != launcher.used_tool; + Tool tool; + if(igBeginTabItem("Entity spawner", &a, launcher.used_tool == Tool.entity_spawner && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.entity_spawner; + igEndTabItem(); + } + if(igBeginTabItem("Component manipulator", &a, launcher.used_tool == Tool.component_manipulator && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.component_manipulator; + igEndTabItem(); + } + if(igBeginTabItem("Selector", &a, launcher.used_tool == Tool.selector && different ? ImGuiTabItemFlags_SetSelected : 0)) + { + tool = Tool.selector; + igEndTabItem(); + } + launcher.used_tool = tool; + prev_tool = launcher.used_tool; + } + igEndTabBar(); + + + igCheckbox("Show Tool", &launcher.tool_show); + if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); + igSameLine(0,4); + igCheckbox("Show Filtered", &launcher.show_filtered); + if(igIsItemHovered(0))igSetTooltip("Show/hide filtered entities"); + if(launcher.used_tool == Tool.component_manipulator) + { + igCheckbox("Override", &launcher.override_); + } + + //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); + if(launcher.used_tool != Tool.selector) + { + if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; + if(igIsItemHovered(0))igSetTooltip("Tool should adding (Entities or components)"); + igSameLine(0,4); + if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; + if(igIsItemHovered(0))igSetTooltip("Tool should removing (Entities or components)"); + } + + igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); + igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); + + if(igBeginChild("",ImVec2(0,0),1,0)) + { + launcher.gui_manager.toolGui(); + } + igEndChild(); + } + igEnd(); + } + if(launcher.show_profile_wnd) { //igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0)); @@ -864,10 +1006,20 @@ void mainLoop(void* arg) double loop_time = launcher.getTime(); launcher.job_updater.pool.tryWaitCount = 10000; - if(launcher.demo.loop && !launcher.demo.loop()) - { - quit(); - *cast(bool*)arg = false; + if(launcher.play) + { + if(launcher.demo.loop && !launcher.demo.loop()) + { + quit(); + *cast(bool*)arg = false; + } + } + else + { + launcher.manager.begin(); + import game_core.rendering; + launcher.manager.callEntitiesFunction!DrawSystem(&(launcher.manager.getSystem!DrawSystem).onUpdate); + launcher.manager.end(); } launcher.job_updater.pool.tryWaitCount = 0; @@ -1119,7 +1271,7 @@ int app_main(int argc, char** argv) // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); // launcher.switchDemo(getParticlesDemo()); // launcher.switchDemo(getSimpleDemo()); - launcher.switchDemo(getBrickBreakerDemo()); + launcher.switchDemo(getSimpleDemo()); } int key_num; diff --git a/demos/source/demos/brick_breaker.d b/demos/source/demos/brick_breaker.d index 3540449..51e213c 100644 --- a/demos/source/demos/brick_breaker.d +++ b/demos/source/demos/brick_breaker.d @@ -24,6 +24,13 @@ extern(C): private enum float px = 1.0/512.0; +float clamp(float v, float min, float max) +{ + if(vmax)return max; + else return v; +} + /*####################################################################################################################### ------------------------------------------------ Components ------------------------------------------------------------------ #######################################################################################################################*/ @@ -185,6 +192,7 @@ struct BallCollisionSystem { bool test(EntityID id) { + if(id == data.entity[i].id)return true; Entity* entity = launcher.manager.getEntity(id); if(entity) { @@ -192,50 +200,32 @@ struct BallCollisionSystem CScale* scale = entity.getComponent!CScale; if(location && scale) { - float radius = data.scale[i].x; + float radius = data.scale[i].x*0.5; vec2 rel_pos = *location - data.location[i]; - vec2 abs_rel_pos = rel_pos; - if(abs_rel_pos.x < 0)abs_rel_pos.x = -abs_rel_pos.x; - if(abs_rel_pos.y < 0)abs_rel_pos.y = -abs_rel_pos.y; - vec2 half_scale = *scale * 0.25f; + vec2 half_scale = *scale * 0.5f; + + vec2 nearest_point; + nearest_point.x = clamp(rel_pos.x, -half_scale.x, half_scale.x); + nearest_point.y = clamp(rel_pos.y, -half_scale.y, half_scale.y); - if(abs_rel_pos.x < half_scale.x + radius && - abs_rel_pos.y < half_scale.y + radius) + vec2 vector; + if(nearest_point == rel_pos) { - if(abs_rel_pos.x < half_scale.x) - { - if(rel_pos.y * data.velocity[i].y > 0) - { - data.velocity[i].y = -data.velocity[i].y; - launcher.manager.sendEvent(id,EDamage(1)); - return false; - } - } - else if(abs_rel_pos.y < half_scale.y) - { - if(rel_pos.x * data.velocity[i].x > 0) - { - data.velocity[i].x = -data.velocity[i].x; - launcher.manager.sendEvent(id,EDamage(1)); - return false; - } - } - else - { - vec2 vector = abs_rel_pos - half_scale; - if(rel_pos.x > 0)vector.x = -vector.x; - if(rel_pos.y > 0)vector.y = -vector.y; + vector = nearest_point; + radius = float.max; + } + else vector = nearest_point - rel_pos; + float pow_dist = dot(vector, vector); - float pow_dist = vector.length2(); - if(pow_dist < radius*radius) - { - vector = vector / sqrtf(pow_dist); - data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i])); - launcher.manager.sendEvent(id,EDamage(1)); - return false; - } - } + if(dot(data.velocity[i], vector) > 0.01)return true; + + if(pow_dist < radius*radius) + { + vector = vector / sqrtf(pow_dist); + data.velocity[i] = data.velocity[i] - vector * (2 * dot(vector, data.velocity[i])); + launcher.manager.sendEvent(id,EDamage(1)); + return cast(bool)(hits--); } } } @@ -244,6 +234,7 @@ struct BallCollisionSystem EntitiesData data; uint i; + uint hits; } ShootGrid* grid; @@ -279,6 +270,7 @@ struct BallCollisionSystem foreach(i; 0..data.length) { state.i = i; + state.hits = 1; //float radius = data.scale[i].x; AABB bounding = AABB(data.location[i]-data.scale[i], data.location[i]+data.scale[i]); tree.test(bounding, cast(bool delegate(EntityID id))&state.test); @@ -317,7 +309,11 @@ struct DamageSystem struct BrickBreakerDemo { - __gshared const (char)* tips = "Brick breaker demo. It's a game about destroying evil bricks."; + __gshared const (char)* tips = "Brick breaker demo. It's a game about destroying evil bricks. + +This demo is usnfinished yet but collision works well. Bricks can be destroyed. Spawning thousands of bricks and then thousands of balls is good way to try demo. +Bricks uses StaticBVH, ball don't collide witch each other, paddle is added to dynamic BVH and collide with balls. But nothing keeps you from adding dynamic collision for balls. +Currently dynamic collisions are pretty slow as dynamic BVH is rebuilded every frame on single thread."; //EntityTemplate* tmpl; Texture texture; @@ -418,6 +414,7 @@ void brickBreakerStart() launcher.gui_manager.addComponent(CBall(), "Ball"); launcher.gui_manager.addComponent(CBVH(), "BVH"); launcher.gui_manager.addComponent(CAABB(), "AABB"); + launcher.gui_manager.addComponent(CStatic(), "Static Flag"); launcher.gui_manager.addSystem(becsID!MoveSystem, "Move System"); launcher.gui_manager.addSystem(becsID!EdgeCollisionSystem, "Edge Collision System"); diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d index b976308..bbb68ee 100644 --- a/demos/source/demos/particles.d +++ b/demos/source/demos/particles.d @@ -180,7 +180,7 @@ struct DrawSystem // { // foreach(i; 0..data.length) // { -// data.locations[i] += data.velocity[i] * launcher.delta_time; +// data.locations[i] += data.velocity[i] * launcher.deltaTime; // } // } // } @@ -208,7 +208,7 @@ struct MouseAttractSystem void onUpdate(EntitiesData data) { - float speed = launcher.delta_time * 0.01; + float speed = launcher.deltaTime * 0.01; foreach(i;0..data.length) { vec2 rel_pos = mouse_pos - data.locations[i]; @@ -236,7 +236,7 @@ struct AttractSystem void onUpdate(AttractorIterator.EntitiesData adata) { - float speed = launcher.delta_time * 0.00004; + float speed = launcher.deltaTime * 0.00004; if(adata.vortex) { foreach(i;0..data.length) @@ -365,7 +365,7 @@ struct PlayAreaSystem // { // foreach(i;0..10) // { -// damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1); +// damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.deltaTime*0.1); // } // return true; @@ -395,7 +395,7 @@ struct ParticleLifeSystem bool onBegin() { - delta_time = cast(int)(launcher.delta_time * 1000); + delta_time = cast(int)(launcher.deltaTime * 1000); return true; } @@ -423,7 +423,7 @@ struct GravitySystem void onUpdate(EntitiesData data) { - float delta_time = launcher.delta_time * 0.00_092; + float delta_time = launcher.deltaTime * 0.00_092; foreach(i; 0..data.length) { data.velocity[i].y -= delta_time; @@ -437,7 +437,8 @@ struct GravitySystem struct ParticlesDemo { - __gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window."; + __gshared const (char)* tips = "Particles by default have no velocity. You can spawn \"Attractor\" which attract particles, or \"Vortex\" which attracts and spin particles. +Please do not spawn to many of them as every \"Attractor\" iterate over all particles (brute force)."; Texture texture; } @@ -471,6 +472,7 @@ void particlesRegister() launcher.manager.registerComponent!CParticleLife; launcher.manager.registerComponent!CForceRange; launcher.manager.registerComponent!CMaterialIndex; + launcher.manager.registerComponent!CVelocityFactor; launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); diff --git a/demos/source/demos/sandbox.d b/demos/source/demos/sandbox.d index e7abb06..c59b432 100644 --- a/demos/source/demos/sandbox.d +++ b/demos/source/demos/sandbox.d @@ -98,6 +98,7 @@ DemoCallbacks getSanboxDemo() demo.initialize = &sandboxStart; demo.deinitialize = &sandboxEnd; demo.loop = &sandboxLoop; - demo.tips = "tips"; + demo.tips = "This demo contains all components, systems and events from previous demos. They was not designed for that kind of coexisting. Some system collide with other making some weird things. +This gives biggest opportunities. You can add tower on top of snake, or lasers to paddle from BrickBreaker. This will be improved in next versions of ECS demo."; return demo; } \ No newline at end of file diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 7a8357a..bfbb74c 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -99,7 +99,32 @@ struct MoveSystem struct Simple { - __gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window."; + __gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Demo\" window. +\"Tools\" window exists of three tools which can be used to manipulate game. +Options: + * Show Tool - enable/disable rendering of blue circle around cursor + * Show Filtered - enable/disable higliting filtered entities. For \"Component manipulator\" tool it shows entities which has selected component. + * Add/Remove - select primary action. LMB - primary action, RMB - secondary action + * Tools size - size of tool + * Tool repeat - how many times in one second tool should take action (e.g. 1000 means every second \"Entity spawner\" will spawn 1000 enties) + * Override - enabled means that \"Component manipulator\" will override components data if entity already has that component +Tools: + * Entity spawner - used to spawn new entities + * Component manipulator - used to add/remove components to/from entities + * Selector - allow to select entity, show and modify his data. Only one entity can be selected, selector selects entity nearest co cursor. + +ShortCuts: + * CRTL*1/2/3 - change tool + * Mouse wheel - change tool size + * SHIFT + Mouse wheel - change entity/component in tool list + * LBM - primary action (default: add entity / add component) + * RMB - secondary action (default: remove entity / remove component) + +\"Statistic\" windows shows FPS and entities count. + +From top menu bar (upper left corner) you can select different demos or change some options. Multihtreading is highly recommended, but it can not working on mobile phones or Firefox browser. + +Demo is capable rendering of hundreds of thousands of entities. Playable area is heavily too small to show that count of entities, but you can try it :)"; EntityTemplate* tmpl; Texture texture; @@ -137,6 +162,9 @@ void simpleStart() launcher.gui_manager.addSystem(becsID!MoveSystem,"Move Up System"); launcher.gui_manager.addSystem(becsID!DrawSystem,"Draw System"); + launcher.gui_manager.addComponent(CLocation(), "Location"); + launcher.gui_manager.addComponent(CDrawDefault(), "DrawDefault"); + simple.tmpl = launcher.manager.allocateTemplate([becsID!CLocation, becsID!CDrawDefault].staticArray); //*simple.tmpl.getComponent!CTexCoordsIndex = TexCoordsManager.instance.getCoordIndex(vec4(0,48,16,16)*px); //CLocation* loc_comp = simple.tmpl.getComponent!CLocation; diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 7591978..395f283 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -58,7 +58,8 @@ enum SnakePart : ubyte struct Snake { - __gshared const (char)* tips = "Use \"WASD\" keys to move."; + __gshared const (char)* tips = "Use \"WASD\" keys to move. If you loose you can always spawn new snake... or several snakes. +This demo is an example that in ECS you can make very \"non-ECS\" game"; EntityTemplate* apple_tmpl; EntityTemplate* snake_tmpl; @@ -286,7 +287,7 @@ struct ParticleSystem { foreach(i;0..data.length) { - data.particle[i].life -= launcher.delta_time; + data.particle[i].life -= launcher.deltaTime; if(data.particle[i].life < 0)launcher.manager.removeEntity(data.entities[i].id); } } @@ -328,7 +329,7 @@ struct AnimationSystem { foreach(i;0..data.length) { - data.animation[i].time += launcher.delta_time * 0.01; + data.animation[i].time += launcher.deltaTime * 0.01; while(data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; } } @@ -971,7 +972,7 @@ bool snakeLoop() launcher.manager.begin(); - float delta_time = launcher.delta_time; + float delta_time = launcher.deltaTime; if(delta_time > 2000)delta_time = 2000; __gshared float time = 0; diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 67332f8..c3decc2 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -36,7 +36,9 @@ extern(C): struct SpaceInvaders { - __gshared const (char)* tips = "Use \"WASD\" keys to move and \"Space\" for shooting."; + __gshared const (char)* tips = "Use \"WASD\" keys to move and \"Space\" for shooting. +On start there is not to much to do. But you can spawn thousands of entities. You can even change guild for enemies to make them kilking themselves. +You can add any component to any entity which sometimes can give fun results. This demo wasn't created with such combination in mind, but that is something which comes naturally with ECS."; EntityTemplate* enemy_tmpl; EntityTemplate* ship_tmpl; @@ -1019,7 +1021,7 @@ struct ShootingSystem foreach(i;0..data.length) { CWeapon* laser = &data.laser[i]; - laser.shoot_time += launcher.delta_time; + laser.shoot_time += launcher.deltaTime; while(laser.shoot_time > CWeapon.levels[laser.level - 1].reload_time) { CVelocity laser_velocity; @@ -1824,7 +1826,7 @@ struct AnimationSystem void onUpdate(EntitiesData data) { - float dt = launcher.delta_time * 0.01; + float dt = launcher.deltaTime * 0.01; if(data.looped) { foreach(i;0..data.length) @@ -1865,7 +1867,7 @@ struct ParticleSystem { foreach(i;0..data.length) { - data.particle[i].life -= launcher.delta_time; + data.particle[i].life -= launcher.deltaTime; if(data.particle[i].life < 0)launcher.manager.removeEntity(data.entitiy[i].id); } } @@ -2086,6 +2088,7 @@ void spaceInvadersRegister() launcher.manager.registerComponent!CTargetPlayerShip; launcher.manager.registerComponent!CChildren; launcher.manager.registerComponent!CWeaponLocation; + launcher.manager.registerComponent!CVelocityFactor; launcher.manager.registerComponent!CInit; launcher.manager.registerComponent!CBoss; launcher.manager.registerComponent!CParts; diff --git a/demos/source/game_core/basic.d b/demos/source/game_core/basic.d index b47ba52..ec32d87 100644 --- a/demos/source/game_core/basic.d +++ b/demos/source/game_core/basic.d @@ -97,6 +97,10 @@ struct CVelocityFactor vec2 value = vec2(1); } +struct CStatic +{ + mixin ECS.Component; +} struct DampingSystem { diff --git a/demos/source/game_core/collision.d b/demos/source/game_core/collision.d index 794f8d8..647bfdb 100644 --- a/demos/source/game_core/collision.d +++ b/demos/source/game_core/collision.d @@ -49,11 +49,6 @@ struct CBVH uint index; } -struct CStatic -{ - mixin ECS.Component; -} - struct CAABB { mixin ECS.Component; @@ -1003,6 +998,7 @@ struct AABBUpdater @readonly CLocation[] location; @readonly CScale[] scale; @optional @readonly CRotation[] rotation; + @optional @readonly CStatic[] static_flag; } void onAddEntity(EntitiesData data) @@ -1015,6 +1011,8 @@ struct AABBUpdater void onUpdate(EntitiesData data) { + if(data.static_flag)return; + foreach(i; 0..data.length) { data.bounding[i] = AABB(data.location[i]-data.scale[i],data.location[i]+data.scale[i]); diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index b172ffc..26eba2b 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -395,7 +395,7 @@ struct GUIManager } } - void entityComponentsGUI() + void templateComponentsGUI() { if(selected_template >= templates.length)return; EntityTemplate* tmpl = templates[selected_template].tmpl; @@ -408,6 +408,19 @@ struct GUIManager } } + void entityComponentsGUI(Entity* entity) + { + if(!entity)return; + EntityMeta meta = entity.getMeta(); + EntityManager.EntityInfo* info = meta.block.type_info; + foreach(comp_id; info.components) + { + // void* data_ptr = tmpl.entity_data.ptr; + void* comp_ptr = meta.getComponent(comp_id);//data_ptr + info.tmpl_deltas[comp_id]; + componentGUI(comp_id, comp_ptr); + } + } + void toolGui() { ImGuiStyle * style = igGetStyle(); @@ -436,7 +449,7 @@ struct GUIManager if(igIsItemHovered(0))igSetTooltip("Select entity to spawn (SHIFT + Scroll)"); } style.Colors[ImGuiCol_Header] = col; - entityComponentsGUI(); + templateComponentsGUI(); break; case Tool.component_manipulator: if(components.length) @@ -458,6 +471,11 @@ struct GUIManager if(selected_component < components.length)componentGUI(components[selected_component].component_id, components[selected_component].data); break; case Tool.selector: + { + Entity* entity = gEM.getEntity(launcher.selected_entity); + style.Colors[ImGuiCol_Header] = col; + entityComponentsGUI(entity); + } break; } diff --git a/demos/source/meson.build b/demos/source/meson.build new file mode 100644 index 0000000..e578ca0 --- /dev/null +++ b/demos/source/meson.build @@ -0,0 +1,20 @@ +demos_src += files( + 'app.d', + 'demos/brick_breaker.d', + 'demos/bullet_madnes.d', + 'demos/particles.d', + 'demos/physics.d', + 'demos/sandbox.d', + 'demos/simple.d', + 'demos/snake.d', + 'demos/space_invaders.d', + 'game_core/basic.d', + 'game_core/collision.d', + 'game_core/job_updater.d', + 'game_core/rendering.d', + 'gui/component.d', + 'gui/manager.d', + 'gui/system.d', + 'gui/template_.d', + 'gui/tool_circle.d', +) \ No newline at end of file diff --git a/demos/utils/dub.json b/demos/utils/dub.json index 5302fd8..d47af9e 100644 --- a/demos/utils/dub.json +++ b/demos/utils/dub.json @@ -16,7 +16,7 @@ ], "dependencies": { "bindbc-sdl":"0.19.0", - "ecs":{"path":"../../"} + "bubel_ecs":{"path":"../../"} }, "versions": [ "BindSDL_Image", diff --git a/demos/utils/meson.build b/demos/utils/meson.build new file mode 100644 index 0000000..de9e958 --- /dev/null +++ b/demos/utils/meson.build @@ -0,0 +1,25 @@ +# Files +utils_src = files() +subdir('source/ecs_utils') + +utils_inc = include_directories('source/') + +# Dependencies +ecs_utils_lib = library('ecs_utils', utils_src, + include_directories : [demos_inc, external_inc, utils_inc], + link_args : link_args, + d_module_versions : versions, + dependencies : [ + decs_dep, + bindbc_loader_dep, + bindbc_sdl_dep, + ] +) + +ecs_utils_dep = declare_dependency( + include_directories : utils_inc, + link_with : ecs_utils_lib, +) +#shared_library('ecs_utils', utils_src, include_directories : [utils_inc], d_args: args, link_args: link_args, link_with: ecs_lib) + + diff --git a/demos/utils/source/ecs_utils/gfx/shader.d b/demos/utils/source/ecs_utils/gfx/shader.d index e941289..c3d656a 100644 --- a/demos/utils/source/ecs_utils/gfx/shader.d +++ b/demos/utils/source/ecs_utils/gfx/shader.d @@ -70,7 +70,7 @@ struct Shader version(WebAssembly)const char* glsl = "#version 100\n"; else version(Android)const char* glsl = "#version 100\n"; - else const char* glsl = "#version 330\n"; + else const char* glsl = "#version 120\n"; const char* buffer = data.code.ptr; char* ver; version(WebAssembly)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr; diff --git a/demos/utils/source/ecs_utils/meson.build b/demos/utils/source/ecs_utils/meson.build new file mode 100644 index 0000000..14d443d --- /dev/null +++ b/demos/utils/source/ecs_utils/meson.build @@ -0,0 +1,18 @@ +utils_src += files( + 'gfx/mesh.d', + 'gfx/sprite.d', + 'gfx/mesh_module.d', + 'gfx/material.d', + 'gfx/shader.d', + 'gfx/vertex.d', + 'gfx/config.d', + 'gfx/buffer.d', + 'gfx/render_list.d', + 'gfx/renderer.d', + 'gfx/texture.d', + 'utils.d', + 'math/matrix.d', + 'math/vector.d', + 'imgui_styles.d', + 'imgui_bind.d', +) \ No newline at end of file diff --git a/dub.json b/dub.json index 1a99040..8cf891d 100755 --- a/dub.json +++ b/dub.json @@ -1,6 +1,6 @@ { "name": "bubel_ecs", - "targetName" : "ecs", + "targetName" : "bubel_ecs", "authors": [ "MichaƂ Masiukiewicz", "Dawid Masiukiewicz" ], @@ -50,7 +50,8 @@ ], "dflags": [ "-unittest" - ] + ], + "targetName" : "ecs" }, { "name": "unittest-runner-cov", @@ -64,7 +65,8 @@ "dflags": [ "-unittest", "-cov" - ] + ], + "targetName" : "ecs" }, { "name" : "library-betterC", @@ -127,7 +129,8 @@ "excludedSourceFiles":[ "source\/win_dll.d", "tests/tests.d" - ] + ], + "targetName" : "ecs" } ] } \ No newline at end of file diff --git a/meson.build b/meson.build index 4951584..d5cb683 100644 --- a/meson.build +++ b/meson.build @@ -1,42 +1,29 @@ -project('DECS', 'd') - -src = [ - 'source/bubel/ecs/atomic.d', - 'source/bubel/ecs/attributes.d', - 'source/bubel/ecs/block_allocator.d', - 'source/bubel/ecs/core.d', - 'source/bubel/ecs/entity.d', - 'source/bubel/ecs/events.d', - 'source/bubel/ecs/hash_map.d', - 'source/bubel/ecs/id_manager.d', - 'source/bubel/ecs/manager.d', - 'source/bubel/ecs/package.d', - 'source/bubel/ecs/simple_vector.d', - 'source/bubel/ecs/std.d', - 'source/bubel/ecs/system.d', - 'source/bubel/ecs/traits.d', - 'source/bubel/ecs/vector.d' -] - -tests_src = [ - 'tests/tests.d' -] +project('decs', 'd', version : '0.5.0') +# Options betterC_opt = get_option('betterC') BuildDemos_opt = get_option('BuildDemos') LTO_otp = get_option('LTO') -comp = meson.get_compiler('d') +summary('betterC enabled', betterC_opt) +summary('build demos', BuildDemos_opt) +summary('LTO enabled', LTO_otp) -comp_id = comp.get_id() +meson_minimum_version = '>=0.57.1' +assert(meson.version().version_compare(meson_minimum_version), 'Newer verson of meson required, current version: @0@, required: @1@'.format(meson.version(), meson_minimum_version)) +# Files +src = files() +subdir('source') + +inc = include_directories('source/') + +# Arguments args = [] link_args = [] -if comp_id == 'gcc' - args += '-pthread' - link_args += '-pthread' -endif +comp = meson.get_compiler('d') +comp_id = comp.get_id() if LTO_otp if comp_id == 'gcc' @@ -46,7 +33,7 @@ if LTO_otp args += '-flto=thin' link_args += '-flto=thin' else - message('LTO don\'t work with DMD') + assert(false, 'Compiler "@0@" doesn\'t support LTO'.format(comp_id)) endif endif @@ -60,16 +47,27 @@ if betterC_opt endif endif -inc = include_directories('source/') -tests_inc = include_directories('source/') +add_global_arguments(args, language : 'd') +add_global_link_arguments(link_args, language : 'd') -ecs_lib = library('ecs', src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args) +# Dependencies +threads_dep = dependency('threads') -executable('tests', tests_src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args, link_with: ecs_lib) +ecs_lib = library('decs', + src, + include_directories : [inc], +) -bubel_ecs_dep = declare_dependency(include_directories : [inc], link_with : ecs_lib) +decs_dep = declare_dependency( + include_directories : [inc], + link_with : ecs_lib, + dependencies : threads_dep, +) +# Tests +subdir('tests') + +# Demos if BuildDemos_opt - subdir('demos/utils') subdir('demos') endif diff --git a/meson_options.txt b/meson_options.txt index 0ea2df9..1ab62f0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,3 @@ option('betterC', type: 'boolean', value: false) option('BuildDemos', type: 'boolean', value: false) -option('LTO', type: 'boolean', value: false) \ No newline at end of file +option('LTO', type: 'boolean', value: false) diff --git a/source/meson.build b/source/meson.build new file mode 100644 index 0000000..de5da33 --- /dev/null +++ b/source/meson.build @@ -0,0 +1,17 @@ +src += files( + 'bubel/ecs/atomic.d', + 'bubel/ecs/attributes.d', + 'bubel/ecs/block_allocator.d', + 'bubel/ecs/core.d', + 'bubel/ecs/entity.d', + 'bubel/ecs/events.d', + 'bubel/ecs/hash_map.d', + 'bubel/ecs/id_manager.d', + 'bubel/ecs/manager.d', + 'bubel/ecs/package.d', + 'bubel/ecs/simple_vector.d', + 'bubel/ecs/std.d', + 'bubel/ecs/system.d', + 'bubel/ecs/traits.d', + 'bubel/ecs/vector.d', +) \ No newline at end of file diff --git a/subprojects/bindbc-loader.wrap b/subprojects/bindbc-loader.wrap new file mode 100644 index 0000000..b99f744 --- /dev/null +++ b/subprojects/bindbc-loader.wrap @@ -0,0 +1,7 @@ +[wrap-git] +url = https://github.com/BindBC/bindbc-loader.git +revision = 9a51af991acce3c67e51695c07bf3fa6419ef938 +patch_directory = bindbc-loader + +[provide] +dependency_names = bindbc-loader diff --git a/subprojects/bindbc-sdl.wrap b/subprojects/bindbc-sdl.wrap new file mode 100644 index 0000000..3b159a0 --- /dev/null +++ b/subprojects/bindbc-sdl.wrap @@ -0,0 +1,7 @@ +[wrap-git] +url = https://github.com/BindBC/bindbc-sdl.git +revision = 5c936064b7226630f5080f4b12b77ee39c8ac64b +patch_directory = bindbc-sdl + +[provide] +dependency_names = bindbc-sdl diff --git a/subprojects/cimgui.wrap b/subprojects/cimgui.wrap new file mode 100644 index 0000000..67d2107 --- /dev/null +++ b/subprojects/cimgui.wrap @@ -0,0 +1,8 @@ +[wrap-git] +url = https://github.com/cimgui/cimgui.git +revision = 1c65ee2bdc719fb3ef62b4615d66fe8effa21148 +clone-recursive = true +patch_directory = cimgui + +[provide] +dependency_names = cimgui diff --git a/subprojects/packagefiles/bindbc-loader/meson.build b/subprojects/packagefiles/bindbc-loader/meson.build new file mode 100644 index 0000000..ce3bdf0 --- /dev/null +++ b/subprojects/packagefiles/bindbc-loader/meson.build @@ -0,0 +1,24 @@ +project('bindbc-loader', 'd', version : '0.3.2', default_options: ['default_library=static']) + +# Files +src = files( + 'source/bindbc/loader/package.d', + 'source/bindbc/loader/sharedlib.d', + 'source/bindbc/loader/system.d', +) + +inc = include_directories('source') + +# Dependencies +lib = library('bindbc-loader', src, + include_directories : [inc], + pic : true, + d_module_versions: ['BindBC_Static'], +) + +bindbc_loader_dep = declare_dependency( + include_directories : [inc], + link_with : lib, +) + +meson.override_dependency('bindbc-loader', bindbc_loader_dep) \ No newline at end of file diff --git a/subprojects/packagefiles/bindbc-sdl/meson.build b/subprojects/packagefiles/bindbc-sdl/meson.build new file mode 100644 index 0000000..0c95cc5 --- /dev/null +++ b/subprojects/packagefiles/bindbc-sdl/meson.build @@ -0,0 +1,72 @@ +project('bindbc-sdl', 'd', version : '0.19.2', default_options: ['default_library=static']) + +# Files +src = files( + 'source/bindbc/sdl/bind/package.d', + 'source/bindbc/sdl/bind/sdl.d', + 'source/bindbc/sdl/bind/sdlassert.d', + 'source/bindbc/sdl/bind/sdlatomic.d', + 'source/bindbc/sdl/bind/sdlaudio.d', + 'source/bindbc/sdl/bind/sdlblendmode.d', + 'source/bindbc/sdl/bind/sdlclipboard.d', + 'source/bindbc/sdl/bind/sdlcpuinfo.d', + 'source/bindbc/sdl/bind/sdlerror.d', + 'source/bindbc/sdl/bind/sdlevents.d', + 'source/bindbc/sdl/bind/sdlfilesystem.d', + 'source/bindbc/sdl/bind/sdlgamecontroller.d', + 'source/bindbc/sdl/bind/sdlgesture.d', + 'source/bindbc/sdl/bind/sdlhaptic.d', + 'source/bindbc/sdl/bind/sdlhints.d', + 'source/bindbc/sdl/bind/sdljoystick.d', + 'source/bindbc/sdl/bind/sdlkeyboard.d', + 'source/bindbc/sdl/bind/sdlkeycode.d', + 'source/bindbc/sdl/bind/sdlloadso.d', + 'source/bindbc/sdl/bind/sdllog.d', + 'source/bindbc/sdl/bind/sdlmessagebox.d', + 'source/bindbc/sdl/bind/sdlmouse.d', + 'source/bindbc/sdl/bind/sdlmutex.d', + 'source/bindbc/sdl/bind/sdlpixels.d', + 'source/bindbc/sdl/bind/sdlplatform.d', + 'source/bindbc/sdl/bind/sdlpower.d', + 'source/bindbc/sdl/bind/sdlrect.d', + 'source/bindbc/sdl/bind/sdlrender.d', + 'source/bindbc/sdl/bind/sdlrwops.d', + 'source/bindbc/sdl/bind/sdlscancode.d', + 'source/bindbc/sdl/bind/sdlshape.d', + 'source/bindbc/sdl/bind/sdlstdinc.d', + 'source/bindbc/sdl/bind/sdlsurface.d', + 'source/bindbc/sdl/bind/sdlsystem.d', + 'source/bindbc/sdl/bind/sdlsyswm.d', + 'source/bindbc/sdl/bind/sdlthread.d', + 'source/bindbc/sdl/bind/sdltimer.d', + 'source/bindbc/sdl/bind/sdltouch.d', + 'source/bindbc/sdl/bind/sdlversion.d', + 'source/bindbc/sdl/bind/sdlvideo.d', + 'source/bindbc/sdl/bind/sdlvulkan.d', + 'source/bindbc/sdl/config.d', + 'source/bindbc/sdl/dynload.d', + 'source/bindbc/sdl/image.d', + 'source/bindbc/sdl/mixer.d', + 'source/bindbc/sdl/net.d', + 'source/bindbc/sdl/package.d', + 'source/bindbc/sdl/ttf.d', +) + +inc = include_directories('source') + +# Dependencies +bindbc_loader_dep = dependency('bindbc-loader') + +lib = library('bindbc-sdl', src, + dependencies : bindbc_loader_dep, + include_directories : [inc], + d_module_versions: ['BindBC_Static'], + pic : true, +) + +bindbc_sdl_dep = declare_dependency( + include_directories : [inc], + link_with : lib, +) + +meson.override_dependency('bindbc-sdl', bindbc_sdl_dep) \ No newline at end of file diff --git a/subprojects/packagefiles/cimgui/meson.build b/subprojects/packagefiles/cimgui/meson.build new file mode 100644 index 0000000..e4c1a41 --- /dev/null +++ b/subprojects/packagefiles/cimgui/meson.build @@ -0,0 +1,29 @@ +project('cimgui', 'cpp', version : '1.73.0', default_options: ['default_library=shared', 'warning_level=1']) + +# Files +src = [ + 'cimgui.cpp', + 'imgui/imgui.cpp', + 'imgui/imgui_draw.cpp', + 'imgui/imgui_demo.cpp', + 'imgui/imgui_widgets.cpp', +] + +inc = [ '.' ] +pub_inc = [ 'imgui' ] + +# Dependencies +# bindbc_loader_dep = dependency('bindbc-loader') + +lib = shared_library('cimgui', src, + # dependencies : bindbc_loader_dep, + include_directories : [inc, pub_inc], + # pic : true, +) + +cimgui_dep = declare_dependency( + include_directories : [pub_inc], + link_with : lib, +) + +meson.override_dependency('cimgui', cimgui_dep) \ No newline at end of file diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 0000000..dae8536 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1,13 @@ +tests_src = files( + 'tests.d', +) + +exe = executable('decs-tests', + tests_src, + include_directories : [inc], + d_args : args, + link_args : link_args, + dependencies : decs_dep, +) + +test('basic-tests', exe) diff --git a/tests/tests.d b/tests/tests.d index d539f89..f82519d 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -102,7 +102,7 @@ static struct CPosition static struct TestComp { - mixin ECS.Component; //__gshared ushort component_id; + mixin ECS.Component; //__gshared becsID!ushort; int a = 1; ulong b = 2; @@ -119,7 +119,7 @@ static struct TestComp static struct TestComp2 { - mixin ECS.Component; //__gshared ushort component_id; + mixin ECS.Component; //__gshared becsID!ushort; int b = 3; int a = 4; @@ -136,7 +136,7 @@ static struct TestComp2 static struct TestComp3 { - mixin ECS.Component; //__gshared ushort component_id; + mixin ECS.Component; //__gshared becsID!ushort; uint gg = 5; //good game uint bg = 6; //bad game @@ -153,7 +153,7 @@ static struct TestComp3 static struct TestComp4 { - mixin ECS.Component; //__gshared ushort component_id; + mixin ECS.Component; //__gshared becsID!ushort; uint gg = 7; //good game uint bg = 8; //bad game ulong a = 9; @@ -174,7 +174,7 @@ static struct TestComp4 static struct TestComp5 { - mixin ECS.Component; //__gshared ushort component_id; + mixin ECS.Component; //__gshared becsID!ushort; uint gg = 7; //good game uint bg = 8; //bad game ulong a = 9; @@ -735,12 +735,12 @@ else: printf("Systems register: %f usecs\n", cast(float)(Time.getUSecTime() - time)); time = Time.getUSecTime(); - //ushort[3] ids = [TestComp2.component_id, TestComp.component_id, TestComp4.component_id]; - ushort[2] ids = [TestComp2.component_id, TestComp.component_id]; + //ushort[3] ids = [becsID!TestComp2, becsID!TestComp, becsID!TestComp4]; + ushort[2] ids = [becsID!TestComp2, becsID!TestComp]; EntityTemplate* tmpl = gEM.allocateTemplate(ids); - //ushort[3] ids2 = [TestComp3.component_id, TestComp.component_id, TestComp4.component_id]; - ushort[2] ids2 = [TestComp3.component_id, TestComp.component_id]; + //ushort[3] ids2 = [becsID!TestComp3, becsID!TestComp, becsID!TestComp4]; + ushort[2] ids2 = [becsID!TestComp3, becsID!TestComp]; EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2); ////writeln(tmpl.info.components[]); //*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1); @@ -751,7 +751,7 @@ else: time = Time.getUSecTime(); - ushort[1] empty_ids = [CPosition.component_id]; + ushort[1] empty_ids = [becsID!CPosition]; EntityTemplate* tmpl_empty = gEM.allocateTemplate(empty_ids); gEM.commit(); @@ -1003,7 +1003,7 @@ else: gEM.commit(); - System* sys = EntityManager.instance.getSystem(TestSystem2.system_id); + System* sys = EntityManager.instance.getSystem(becsID!TestSystem2); ExternalUpdateCallTest external_update_test;