From 8381ac166bb672b512279ac0d5bc2fda0ded385e Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 24 Apr 2020 20:55:25 +0200 Subject: [PATCH 01/58] Common update: -added VBo batch rendering (current default, no render mode switch yet) -fixed camera positioning calculation -fixed buffer issue with WebGL -added viewport scalling (at least 300 pixels height). Pixels are scalled if screen is bigger. -center demos gameplay area -added fullpage html template for Emscripten build --- demos/compile_wasm.py | 2 +- demos/source/app.d | 15 ++++++++--- demos/source/demos/simple.d | 15 +++++++---- demos/source/demos/snake.d | 12 +++++---- demos/source/demos/space_invaders.d | 23 +++++++++-------- demos/utils/source/ecs_utils/gfx/buffer.d | 6 ++--- demos/utils/source/ecs_utils/gfx/renderer.d | 28 ++++++++++++--------- 7 files changed, 61 insertions(+), 40 deletions(-) diff --git a/demos/compile_wasm.py b/demos/compile_wasm.py index 30d0a0f..b1f3a7e 100644 --- a/demos/compile_wasm.py +++ b/demos/compile_wasm.py @@ -92,7 +92,7 @@ compile(['source'], 'demo.bc') if clean or os.path.exists('../ecs.bc') == 0 or os.path.isfile('../ecs.bc') == 0: compile(['../source'], '../ecs.bc') -emcc_cmd = 'emcc -v ' + shared_flags + emc_flags + '-s ERROR_ON_UNDEFINED_SYMBOLS=0 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s ALLOW_MEMORY_GROWTH=1 -s MINIFY_HTML=0 -s WASM_MEM_MAX=2048MB -s MALLOC=dlmalloc -s WASM=1 -o ecs_demo.html ' +emcc_cmd = 'emcc -v ' + shared_flags + emc_flags + '-s ERROR_ON_UNDEFINED_SYMBOLS=0 -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 -s ALLOW_MEMORY_GROWTH=1 -s MINIFY_HTML=0 -s WASM_MEM_MAX=2048MB -s MALLOC=dlmalloc -s WASM=1 -o ecs_demo.html --shell-file emscripten_shell.html ' #-s ALLOW_MEMORY_GROWTH=1 -s PROXY_TO_PTHREAD=1 -Wl,--no-check-features -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s TOTAL_MEMORY=512MB emcc_cmd += '../ecs.bc ' diff --git a/demos/source/app.d b/demos/source/app.d index 6338035..150d653 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -51,6 +51,7 @@ struct Launcher void function() end; void function(SDL_Event*) event; void function(vec2, Tool, int) tool; + float scalling; ivec2 window_size = ivec2(1024,768); Renderer renderer; ubyte[] keys; @@ -60,6 +61,7 @@ struct Launcher ulong timer_freq; double delta_time; uint fps; + vec2 render_position; Tool used_tool; int tool_size = 0; @@ -229,7 +231,7 @@ void mainLoop(void* arg) } if(launcher.tool && event.button.button == SDL_BUTTON_LEFT && launcher.tool_repeat == 0 && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow)) { - launcher.tool(vec2(event.button.x, launcher.window_size.y - event.button.y), launcher.used_tool, launcher.tool_size); + launcher.tool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position, launcher.used_tool, launcher.tool_size); } } else if(event.type == SDL_MOUSEBUTTONUP) @@ -255,7 +257,7 @@ void mainLoop(void* arg) while(launcher.repeat_time > range) { launcher.repeat_time -= range; - launcher.tool(launcher.mouse.position, launcher.used_tool, launcher.tool_size); + launcher.tool((launcher.mouse.position*launcher.scalling)-launcher.render_position, launcher.used_tool, launcher.tool_size); } } @@ -525,7 +527,14 @@ void mainLoop(void* arg) } launcher.renderer.resize(launcher.window_size); - launcher.renderer.view(vec2(0,0),vec2(launcher.window_size.x,launcher.window_size.y)); + //launcher.renderer.view(vec2(0,0),vec2(launcher.window_size.x,launcher.window_size.y)); + //if(384, 768, 1152, 1536) + //576 960 1344 1728 + //float scalling; + if(launcher.window_size.y < 360)launcher.scalling = 1; + else launcher.scalling = 1.0 / ((launcher.window_size.y+120)/360); + launcher.renderer.view(launcher.render_position,vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling); + //launcher.renderer.view(vec2(0,0),vec2(1024*launcher.window_size.x/launcher.window_size.y,768)); //glClear(GL_COLOR_BUFFER_BIT); launcher.renderer.clear(); diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 36187c8..edd20c6 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -60,7 +60,7 @@ struct DrawSystem { foreach(i; 0..data.length) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(32,32), vec4(0,0,1,1), 0, 0 , 0); + launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0 , 0); //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); } } @@ -81,7 +81,7 @@ struct MoveSystem foreach(i; 0..data.length) { data.locations[i].location.y = data.locations[i].location.y + 1; - if(data.locations[i].location.y > 400)data.locations[i].location.y = 0; + if(data.locations[i].location.y > 300)data.locations[i].location.y = 0; } } } @@ -119,7 +119,7 @@ void simpleStart() foreach(i; 0..10) foreach(j; 0..10) { - loc_comp.location = vec2(i*32+64,j*32+64); + loc_comp.location = vec2(i*16+64,j*16+64); launcher.manager.addEntity(simple.tmpl); } } @@ -147,6 +147,10 @@ void simpleTool(vec2 position, Tool tool, int size) { position.x += (randomf - 0.5) * size; position.y += (randomf - 0.5) * size; + if(position.x > 400)position.x -= 400; + else if(position.x < 0)position.x += 400; + if(position.y > 300)position.y -= 300; + else if(position.y < 0)position.y += 300; *location = position; } launcher.manager.addEntity(tmpl); @@ -169,17 +173,18 @@ void simpleEvent(SDL_Event* event) void spawnEntity() { CLocation* loc_comp = simple.tmpl.getComponent!CLocation; - loc_comp.location = vec2(randomf() * 600,0); + loc_comp.location = vec2(randomf() * 400,0); launcher.manager.addEntity(simple.tmpl); } bool simpleLoop() { + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + if(launcher.getKeyState(SDL_SCANCODE_SPACE)) { foreach(i;0..1)spawnEntity(); } - launcher.manager.begin(); if(launcher.multithreading) diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index f43c5a5..19d0e31 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -90,9 +90,9 @@ struct Snake { switch(element(ivec2(x,y)).type) { - case MapElement.Type.apple:launcher.renderer.draw(texture, vec2(x*32,y*32), vec2(32,32), vec4(0,32*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake:launcher.renderer.draw(texture, vec2(x*32,y*32), vec2(32,32), vec4(0,48*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.wall:launcher.renderer.draw(texture, vec2(x*32,y*32), vec2(32,32), vec4(0,0,1,1), 0, 0 , 0);break; + case MapElement.Type.apple:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0 , 0);break; + case MapElement.Type.snake:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,48*px,16*px,16*px), 0, 0 , 0);break; + case MapElement.Type.wall:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,0,1,1), 0, 0 , 0);break; default:break; } } @@ -520,8 +520,8 @@ void snakeTool(vec2 position, Tool tool, int size) position.x += (randomf - 0.5) * size; position.y += (randomf - 0.5) * size; ivec2 ipos; - ipos.x = cast(int)(position.x / 32); - ipos.y = cast(int)(position.y / 32); + ipos.x = cast(int)(position.x / 16); + ipos.y = cast(int)(position.y / 16); *ilocation = ipos; if(snake.element(ipos).type != MapElement.Type.empty)return; } @@ -540,6 +540,8 @@ void snakeEvent(SDL_Event* event) bool snakeLoop() { + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(288,288)) * 0.5; + /*if(launcher.show_demo_wnd) { igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0)); diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 5473aed..7058b59 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -34,7 +34,7 @@ struct SpaceInvaders bool move_system = true; bool draw_system = true; - const vec2 map_size = vec2(600,600); + const vec2 map_size = vec2(400,300); const float cell_size = 60; } @@ -101,7 +101,7 @@ struct CScale ///use component as it value alias value this; - vec2 value = vec2(32,32); + vec2 value = vec2(16,16); } struct CTexture @@ -564,8 +564,8 @@ struct MovementSystem { foreach(i;0..data.length) { - data.locations[i].x += data.velocity[i].x * launcher.delta_time; - data.locations[i].y += data.velocity[i].y * launcher.delta_time; + data.locations[i].x += data.velocity[i].x * launcher.delta_time * 0.5; + data.locations[i].y += data.velocity[i].y * launcher.delta_time * 0.5; } } } @@ -630,8 +630,8 @@ struct InputMovementSystem //move every entity using movement vector foreach(i; 0..data.length) { - data.locations[i].x += move_vector.x * launcher.delta_time * 0.5; - data.locations[i].y += move_vector.y * launcher.delta_time * 0.5; + data.locations[i].x += move_vector.x * launcher.delta_time * 0.25; + data.locations[i].y += move_vector.y * launcher.delta_time * 0.25; } } } @@ -709,7 +709,7 @@ void spaceInvadersStart() tex_comp.tex = space_invaders.texture;//laser_tex; tex_comp.coords = vec4(0*px,48*px,16*px,16*px); CScale* scale_comp = space_invaders.laser_tmpl.getComponent!CScale; - scale_comp.value = vec2(4,16); + scale_comp.value = vec2(2,8); CVelocity* vel_comp = space_invaders.laser_tmpl.getComponent!CVelocity; vel_comp.value = vec2(0,1); } @@ -727,7 +727,7 @@ void spaceInvadersStart() tex_comp.tex = space_invaders.texture;//ship_tex; tex_comp.coords = vec4(32*px,32*px,16*px,16*px); CLocation* loc_comp = space_invaders.enemy_tmpl.getComponent!CLocation; - loc_comp.value = vec2(64,space_invaders.map_size.y - 64); + loc_comp.value = vec2(64,space_invaders.map_size.y - 16); CShootDirection* shoot_dir_comp = space_invaders.enemy_tmpl.getComponent!CShootDirection; shoot_dir_comp.direction = Direction.down; CVelocity* vel_comp = space_invaders.enemy_tmpl.getComponent!CVelocity; @@ -738,17 +738,17 @@ void spaceInvadersStart() current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl); launcher.manager.addComponents(current_entity.id,CSideMove(0)); - loc_comp.value = vec2(128,space_invaders.map_size.y - 64); + loc_comp.value = vec2(128,space_invaders.map_size.y - 16); current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl); launcher.manager.addComponents(current_entity.id,CSideMove(-1)); enemy_id = current_entity.id; //enemy_tmpl = launcher.manager.allocateTemplate(current_entity.id); - loc_comp.value = vec2(256,space_invaders.map_size.y - 64); + loc_comp.value = vec2(256,space_invaders.map_size.y - 16); launcher.manager.addEntity(space_invaders.enemy_tmpl); - loc_comp.value = vec2(0,space_invaders.map_size.y - 64); + loc_comp.value = vec2(0,space_invaders.map_size.y - 16); current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl); launcher.manager.addComponents(current_entity.id,CSideMove(0)); @@ -809,6 +809,7 @@ void spaceInvadersEvent(SDL_Event* event) bool spaceInvadersLoop() { + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; /*if(launcher.show_demo_wnd) { diff --git a/demos/utils/source/ecs_utils/gfx/buffer.d b/demos/utils/source/ecs_utils/gfx/buffer.d index 1f38624..2c25324 100644 --- a/demos/utils/source/ecs_utils/gfx/buffer.d +++ b/demos/utils/source/ecs_utils/gfx/buffer.d @@ -55,10 +55,10 @@ struct Buffer glBufferStorage(GL_ARRAY_BUFFER,size*count,data, flags); }*/ - void bufferSubData(uint size, uint offset, void* data) nothrow + void bufferSubData(BindTarget target, uint size, uint offset, void* data) nothrow { - bind(BindTarget.array); - glBufferSubData(GL_ARRAY_BUFFER,offset,size,data); + bind(target); + glBufferSubData(target,offset,size,data); } void map(BindTarget target) nothrow diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index e064c9e..2a04c57 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -98,7 +98,7 @@ struct Renderer alias Technique = RenderTechnique; - __gshared Technique technique = Technique.simple; + __gshared Technique technique = Technique.vbo_batch; void* data_ptr; //import ecs_utils.core : RenderTechnique; @@ -339,6 +339,7 @@ struct Renderer //import core.stdc.string; with(this_) { + if(item_id >= MaxObjects)return; //pos += view_pos; size.x *= view_size.x; size.y *= view_size.y; @@ -470,8 +471,8 @@ struct Renderer break; case Technique.vbo_batch: //if(data_index){ - batch_vbo[0].bufferSubData(item_id*4*16,0,batch_vertices.ptr); - batch_ibo[0].bufferSubData(item_id*6*2,0,batch_indices.ptr); + batch_vbo[0].bufferSubData(Buffer.BindTarget.array,item_id*4*16,0,batch_vertices.ptr); + batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,item_id*6*2,0,batch_indices.ptr); batch_vbo[0].bind(Buffer.BindTarget.array); batch_ibo[0].bind(Buffer.BindTarget.element_array); @@ -480,8 +481,8 @@ struct Renderer glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)8);//} break; case Technique.instanced_attrib_divisor: - ubos[0].bufferSubData(data_index,0,uniform_block.ptr); - ubos[0].bind(Buffer.BindTarget.array); + ubos[0].bufferSubData(Buffer.BindTarget.uniform,data_index,0,uniform_block.ptr); + ubos[0].bind(Buffer.BindTarget.uniform); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); glEnableVertexAttribArray(4); @@ -496,7 +497,7 @@ struct Renderer break; case Technique.uniform_buffer: //ubos[0].bufferData(1,64*MaxObjects,BufferUsage,null); - /*if(data_index)*/ubos[0].bufferSubData(data_index,0,uniform_block.ptr); + /*if(data_index)*/ubos[0].bufferSubData(Buffer.BindTarget.uniform,data_index,0,uniform_block.ptr); break; case Technique.uniform_buffer_indexed: ubos[0].bindRange(Buffer.BindTarget.uniform,0,0,block_max_size); @@ -581,6 +582,8 @@ struct Renderer { material_id = render_list[i].material_id; GfxConfig.materials[material_id].bind(); + float[3*4] data = [1,0,0,1,0,0,0,0,0,0,1,1]; + GfxConfig.materials[material_id].pushUniforms(data.ptr); } if(texture.data != render_list[i].texture.data) { @@ -589,17 +592,17 @@ struct Renderer } uint instance_count = 16_384; - if(i*16_384 > item_id) + if((i+1)*16_384 > item_id) { - instance_count = i*16_384 - item_id; + instance_count = item_id%16_384; } - /*glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*16_384*4*16)); + glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*16_384*4*16)); glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)(i*16_384*4*16+8)); - glDrawElements(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2));*/ + glDrawElements(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2)); - glDrawElementsBaseVertex(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2),i*16_384*4); + //glDrawElementsBaseVertex(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2),i*16_384*4); } } else if(technique == Technique.ssbo_instanced || technique == Technique.instanced_attrib_divisor) @@ -794,9 +797,10 @@ struct Renderer void view(vec2 pos, vec2 size) { - view_pos = pos * size - 1; + //view_pos = pos * size - 1; view_size = vec2(2/size.x,2/size.y); sdl_transform = vec4(0,0,1.0/size.x,1.0/size.y); + view_pos = (pos - size * 0.5) * view_size; } __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, float angle, uint material_id, uint mesh_id) __draw; From 50715fbc40a8ea4821ab840e42e60e8600b938ef Mon Sep 17 00:00:00 2001 From: Mergul Date: Tue, 28 Apr 2020 14:13:55 +0200 Subject: [PATCH 02/58] Demos update: -modified texture atlas -fixed bug with high CPU usage (use pthread instead of builtin D multithreading) -added new graphics -snake now render tile coresponding to body part -snake is destroyed after collision and emit some particles -added some functionality to vectors -fixed documentation issue in Manager.d --- demos/assets/textures/atlas.png | Bin 17825 -> 24668 bytes demos/external/sources/mmutils/thread_pool.d | 2 + demos/source/demos/snake.d | 337 ++++++++++++++++++- demos/source/demos/space_invaders.d | 24 +- demos/utils/source/ecs_utils/math/vector.d | 19 ++ source/ecs/manager.d | 7 +- 6 files changed, 366 insertions(+), 23 deletions(-) diff --git a/demos/assets/textures/atlas.png b/demos/assets/textures/atlas.png index 498f34dd82959385bc9a96199c88707d782b46a0..c628969c0e7149419eb62313fb5c3274457838f3 100644 GIT binary patch literal 24668 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 literal 17825 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 data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; + } + } +} + + +struct AnimationRenderSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CAnimation[] animation; + @readonly CLocation[] location; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i].location, vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], 0, 0 , 0); + } + } +} + struct MoveSystem { mixin ECS.System!64; + EntityTemplate* destroy_template; + CLocation* destroy_location; + CParticleVector* destroy_vector; + struct EntitiesData { uint length; @@ -239,6 +380,13 @@ struct MoveSystem CILocation[] location; } + void setTemplates() + { + destroy_template = snake.snake_destroy_particle; + destroy_location = destroy_template.getComponent!CLocation; + destroy_vector = destroy_template.getComponent!CParticleVector; + } + void moveLocation(ref CILocation location, CMovement.Direction direction) { final switch(direction) @@ -276,6 +424,56 @@ struct MoveSystem else .snake.element(MapElement(),location); } + static CMovement.Direction getDirection(ivec2 p1, ivec2 p2) + { + if(p1.x - p2.x == -1)return CMovement.direction.right; + else if(p1.x - p2.x == 1)return CMovement.direction.left; + else if(p1.y - p2.y == -1)return CMovement.direction.up; + else if(p1.y - p2.y == 1)return CMovement.direction.down; + else if(p1.x - p2.x > 1)return CMovement.direction.right; + else if(p1.x - p2.x < -1)return CMovement.direction.left; + else if(p1.y - p2.y > 1)return CMovement.direction.up; + else return CMovement.direction.down; + } + + static MapElement.Type snakePart(ivec2 p1, ivec2 p2, ivec2 p3) + { + CMovement.Direction direction = getDirection(p1, p2); + CMovement.Direction direction2 = getDirection(p1, p3); + uint case_ = direction*4 + direction2; + final switch(case_) + { + case 0:return MapElement.Type.snake_horizontal; + case 1:return MapElement.Type.snake_horizontal; + case 2:return MapElement.Type.snake_turn_lu; + case 3:return MapElement.Type.snake_turn_ru; + case 4:return MapElement.Type.snake_horizontal; + case 5:return MapElement.Type.snake_horizontal; + case 6:return MapElement.Type.snake_turn_ld; + case 7:return MapElement.Type.snake_turn_rd; + case 8:return MapElement.Type.snake_turn_lu; + case 9:return MapElement.Type.snake_turn_ld; + case 10:return MapElement.Type.snake_vertical; + case 11:return MapElement.Type.snake_vertical; + case 12:return MapElement.Type.snake_turn_ru; + case 13:return MapElement.Type.snake_turn_rd; + case 14:return MapElement.Type.snake_vertical; + case 15:return MapElement.Type.snake_vertical; + } + } + + static MapElement.Type snakeTail(ivec2 p1, ivec2 p2) + { + CMovement.Direction direction = getDirection(p1, p2); + final switch(direction) + { + case CMovement.Direction.up:return MapElement.Type.snake_tail_up; + case CMovement.Direction.down:return MapElement.Type.snake_tail_down; + case CMovement.Direction.left:return MapElement.Type.snake_tail_left; + case CMovement.Direction.right:return MapElement.Type.snake_tail_right; + } + } + void onUpdate(EntitiesData data) { if(data.snakes) @@ -286,21 +484,104 @@ struct MoveSystem moveLocation(data.location[i], data.movement[i].direction); final switch(snake.element(data.location[i].location).type) { - case MapElement.Type.snake: - launcher.manager.removeEntity(data.entities[i].id); - break; - case MapElement.Type.wall: + case MapElement.Type.snake_head_up:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_head_down:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_head_left:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_head_right:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_tail_up:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_tail_down:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_tail_left:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_tail_right:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_turn_ld:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_turn_lu:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_turn_rd:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_turn_ru:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_vertical:goto case(MapElement.Type.snake_horizontal); + case MapElement.Type.snake_horizontal: + foreach(ivec2 loc; data.snakes[i].parts) + { + destroy_location.x = loc.x * 16; + destroy_location.y = loc.y * 16; + snake.element(MapElement(MapElement.Type.empty, EntityID()),loc); + launcher.manager.addEntity(snake.snake_destroy_particle); + foreach(j;0..10) + { + destroy_location.x = loc.x * 16 + randomf() * 8 - 4; + destroy_location.y = loc.y * 16 + randomf() * 8 - 4; + destroy_vector.velocity = vec2(randomf(),randomf())*0.4-0.2; + snake.element(MapElement(MapElement.Type.empty, EntityID()),loc); + launcher.manager.addEntity(snake.snake_destroy_particle); + } + + } + destroy_location.x = new_location.x * 16; + destroy_location.y = new_location.y * 16; + snake.element(MapElement(MapElement.Type.empty, EntityID()),new_location); + launcher.manager.addEntity(snake.snake_destroy_particle); launcher.manager.removeEntity(data.entities[i].id); break; + case MapElement.Type.wall:break; + //launcher.manager.removeEntity(data.entities[i].id); + //break; case MapElement.Type.empty: moveSnake(data.snakes[i], new_location); - snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.location[i].location); + final switch(data.movement[i].direction) + { + case CMovement.Direction.up: + snake.element(MapElement(MapElement.Type.snake_head_up, data.entities[i].id),data.location[i].location); + break; + case CMovement.Direction.right: + snake.element(MapElement(MapElement.Type.snake_head_right, data.entities[i].id),data.location[i].location); + break; + case CMovement.Direction.down: + snake.element(MapElement(MapElement.Type.snake_head_down, data.entities[i].id),data.location[i].location); + break; + case CMovement.Direction.left: + snake.element(MapElement(MapElement.Type.snake_head_left, data.entities[i].id),data.location[i].location); + break; + } + if(data.snakes[i].parts.length > 1) + { + MapElement.Type elem_type = snakePart(data.snakes[i].parts[$-1],data.location[i],data.snakes[i].parts[$-2]); + snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[$-1]); + elem_type = snakeTail(data.snakes[i].parts[1], data.snakes[i].parts[0]); + snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[0]); + } + else if(data.snakes[i].parts.length == 1) + { + MapElement.Type elem_type = snakeTail(data.location[i], data.snakes[i].parts[0]); + snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[0]); + } break; case MapElement.Type.apple: launcher.manager.removeEntity(snake.element(data.location[i].location).id); - data.snakes[i].parts.add(new_location); - snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),new_location); - snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.location[i].location); + if(data.snakes[i].parts.length < 100)data.snakes[i].parts.add(new_location); + + if(data.snakes[i].parts.length > 1) + { + MapElement.Type elem_type = snakePart(data.snakes[i].parts[$-1],data.location[i],data.snakes[i].parts[$-2]); + snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[$-1]); + } + else if(data.snakes[i].parts.length == 1) + { + MapElement.Type elem_type = snakeTail(data.location[i], new_location); + snake.element(MapElement(elem_type, data.entities[i].id),new_location); + } + final switch(data.movement[i].direction) + { + case CMovement.Direction.up: + snake.element(MapElement(MapElement.Type.snake_head_up, data.entities[i].id),data.location[i].location); + break; + case CMovement.Direction.right: + snake.element(MapElement(MapElement.Type.snake_head_right, data.entities[i].id),data.location[i].location); + break; + case CMovement.Direction.down: + snake.element(MapElement(MapElement.Type.snake_head_down, data.entities[i].id),data.location[i].location); + break; + case CMovement.Direction.left: + snake.element(MapElement(MapElement.Type.snake_head_left, data.entities[i].id),data.location[i].location); + break; + } snake.addApple(); break; } @@ -455,19 +736,31 @@ void snakeStart() launcher.manager.registerComponent!CSnake; launcher.manager.registerComponent!CApple; launcher.manager.registerComponent!CParticle; + launcher.manager.registerComponent!CParticleVector; launcher.manager.registerComponent!CMovement; launcher.manager.registerComponent!CInput; + launcher.manager.registerComponent!CAnimation; launcher.manager.registerSystem!MoveSystem(0,"fixed"); launcher.manager.registerSystem!InputSystem(-100); launcher.manager.registerSystem!FixSnakeDirectionSystem(-1,"fixed"); launcher.manager.registerSystem!AppleSystem(-1,"fixed"); + launcher.manager.registerSystem!AnimationRenderSystem(100); + launcher.manager.registerSystem!AnimationSystem(-1); + launcher.manager.registerSystem!ParticleSystem(-1); + launcher.manager.registerSystem!ParticleMovementSystem(-1); launcher.manager.endRegister(); launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); launcher.gui_manager.addSystem(InputSystem.system_id,"Input System"); launcher.gui_manager.addSystem(FixSnakeDirectionSystem.system_id,"Fix Direction System"); + launcher.gui_manager.addSystem(AnimationRenderSystem.system_id,"Animation Render System"); + launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation System"); + launcher.gui_manager.addSystem(ParticleSystem.system_id,"Particle Life System"); + launcher.gui_manager.addSystem(ParticleMovementSystem.system_id,"Particle Movement System"); + + snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray); { ushort[4] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id]; @@ -477,14 +770,26 @@ void snakeStart() launcher.manager.addEntity(snake.snake_tmpl); } + { + snake.snake_destroy_particle = launcher.manager.allocateTemplate([CLocation.component_id, CParticle.component_id, CParticleVector.component_id, CAnimation.component_id].staticArray); + CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation; + canim.frames = snake.snake_destroy_particle_frames; + CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle; + particle.life = 400; + } + { ushort[2] components = [CILocation.component_id, CApple.component_id]; snake.apple_tmpl = launcher.manager.allocateTemplate(components); snake.addApple(); } - + launcher.gui_manager.addTemplate(snake.snake_tmpl, "Snake"); launcher.gui_manager.addTemplate(snake.apple_tmpl, "Apple"); + launcher.gui_manager.addTemplate(snake.snake_destroy_particle, "Particle"); + + MoveSystem* move_system = launcher.manager.getSystem!MoveSystem(); + move_system.setTemplates(); /*foreach(i; 0..10) foreach(j; 0..10) diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 7058b59..bddf53c 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -16,6 +16,8 @@ import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; +enum float px = 1.0/512.0; + extern(C): /*####################################################################################################################### @@ -587,6 +589,7 @@ struct InputMovementSystem const (CInput)[] input; //components are treated as required by default CLocation[] locations; + CTexture[] textures; } /** @@ -595,6 +598,7 @@ struct InputMovementSystem */ bool onBegin() { + move_vector = vec2(0,0); if(launcher.getKeyState(SDL_SCANCODE_W)) { move_vector = vec2(0,1); @@ -616,7 +620,7 @@ struct InputMovementSystem return true; } //don't call system update because no key pressed - return false; + return true; } /** @@ -627,11 +631,21 @@ struct InputMovementSystem */ void onUpdate(EntitiesData data) { + if(move_vector.x == 0) + { + foreach(i; 0..data.length) + { + data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); + } + return; + } //move every entity using movement vector foreach(i; 0..data.length) { data.locations[i].x += move_vector.x * launcher.delta_time * 0.25; data.locations[i].y += move_vector.y * launcher.delta_time * 0.25; + if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px); + else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); } } } @@ -644,8 +658,6 @@ __gshared SpaceInvaders* space_invaders; void spaceInvadersStart() { - const float px = 1.0/512.0; - space_invaders = Mallocator.make!SpaceInvaders; space_invaders.texture.create(); @@ -690,9 +702,11 @@ void spaceInvadersStart() ushort[7] components = [CLocation.component_id, CTexture.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CLaserWeapon.component_id, CShootDirection.component_id]; space_invaders.ship_tmpl = launcher.manager.allocateTemplate(components); + CScale* scale_comp = space_invaders.ship_tmpl.getComponent!CScale; + scale_comp.value = vec2(48,32); CTexture* tex_comp = space_invaders.ship_tmpl.getComponent!CTexture; tex_comp.tex = space_invaders.texture;//ship_tex; - tex_comp.coords = vec4(0*px,48*px,16*px,16*px); + tex_comp.coords = vec4(0*px,80*px,48*px,32*px); CLocation* loc_comp = space_invaders.ship_tmpl.getComponent!CLocation; loc_comp.value = vec2(64,64); CLaserWeapon* weapon = space_invaders.ship_tmpl.getComponent!CLaserWeapon; @@ -707,7 +721,7 @@ void spaceInvadersStart() CTexture* tex_comp = space_invaders.laser_tmpl.getComponent!CTexture; tex_comp.tex = space_invaders.texture;//laser_tex; - tex_comp.coords = vec4(0*px,48*px,16*px,16*px); + tex_comp.coords = vec4(0*px,24*px,2*px,8*px); CScale* scale_comp = space_invaders.laser_tmpl.getComponent!CScale; scale_comp.value = vec2(2,8); CVelocity* vel_comp = space_invaders.laser_tmpl.getComponent!CVelocity; diff --git a/demos/utils/source/ecs_utils/math/vector.d b/demos/utils/source/ecs_utils/math/vector.d index 10b4de5..4b9f3af 100644 --- a/demos/utils/source/ecs_utils/math/vector.d +++ b/demos/utils/source/ecs_utils/math/vector.d @@ -30,6 +30,11 @@ struct vec2 else static assert(0, "Operator "~op~" not implemented"); } + ivec2 opCast() + { + return ivec2(cast(int)x,cast(int)y); + } + void opOpAssign(string op)(vec2 v) { static if (op == "+") @@ -69,6 +74,15 @@ struct vec4 } float[4] data; } + + vec4 opBinary(string op)(float v) + { + static if (op == "+") return vec4(x + v, y + v, z + v, w + v); + else static if (op == "-") return vec4(x - v, y - v, z - v, w - v); + else static if (op == "*") return vec4(x * v, y * v, z * v, w * v); + else static if (op == "/") return vec4(x / v, y / v, z / v, w / v); + else static assert(0, "Operator "~op~" not implemented"); + } } struct ivec2 @@ -82,6 +96,11 @@ struct ivec2 } int[2] data; } + + vec2 opCast() + { + return vec2(x,y); + } } struct ivec4 diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 1b9b959..9f5dceb 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -1550,10 +1550,13 @@ export struct EntityManager } /************************************************************************************************************************ - *Allocate EntityTemplate with specifed components and returns pointer to it. + *Allocate EntityTemplate from basic Template with modifications by adding and removing some components and returns pointer to it. + *Arrays of components needen't to be checked for repeated components, as function itself check if components exist in base template. * *Params: - *components_ids = array of components allocated with template + *base_tmpl = template from which components sould be copied + *components_ids = array of new components to add + *remove_components_ids = array of components to remove from base template */ export EntityTemplate* allocateTemplate(EntityTemplate* base_tmpl, ushort[] components_ids, ushort[] remove_components_ids = null) From 7bc07666d010ef9cfe7d66a8ca10fbf7362f3a28 Mon Sep 17 00:00:00 2001 From: Dawid Masiukiewicz Date: Sat, 2 May 2020 21:11:22 +0000 Subject: [PATCH 03/58] Initial release README.md --- README.md | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 177 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d3f6816..abc9709 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,180 @@ -# Dynamic Entity Component System +# Bubel Entity Component System [![pipeline status](https://gitlab.com/Mergul/bubel-ecs/badges/master/pipeline.svg)](https://gitlab.com/Mergul/bubel-ecs/-/commits/master) [![codecov](https://codecov.io/gl/Mergul/bubel-ecs/branch/master/graph/badge.svg?token=Unm0TJhFoW)](https://codecov.io/gl/Mergul/bubel-ecs) -Entity-Component-System implementation in D language. +BubelECS is Entity-Component-System architecture implementation in D language. +Library aims to delivery fast and flexible architecture for developing games. Library is @nogc and betterC compatible. Even Emscripten build works very well. +Important goal is to keep code without any external dependencies, i. eg. multithreading support don't contain any parallel execution +but emit jobs with delegate and array of dependencies. + +BubelECS was tested on Linux, Windows, Android and WASM. + +**Currently library is in beta stage so some significant API changes can appear.** + +## Design + +For core information about Entity-Component-System architectural pattern I recommend to read definition described at [Wikipedia](https://en.wikipedia.org/wiki/Entity_component_system). + +Main design principles are: + + * **Data oriented design** - components memory is packed into tight block so iterating over entity components is cache friendly + * **Fast and safe EntityID** - every entity is referenced by its unique ID. If entity was destroyed EntityManager will return null pointer for given EntityID. Access to entity from ID is linear operation. + * **Multithreading support** - whole library was developed with multithreading in mind. Adding components is thread-friendly so you get usable EntityID as early as possible. Operations like adding or removing components are deferred to end of frame. Dependencies between systems update are generated automatically. + * **Good logic separation** - system needs information only about components which it's use, there is no relation between systems. Systems can be compiled as multiple separate libraries and used together. + * **Easy systems ordering** - systems are ordered by single priority value. Order of execution of systems with same priority is undefined but order for different priorites are always preserved. + * **Flexible entity to system assignment** - system iterate over any entity that has chosen components. Components can be marked as optional so isn't required but can be used by system. Additionaly system can contain list of components which makes entity excluded from calculation. + * **Builtin events handling** - along with EntityManager library contain EventsManager which makes easier to communicate between multiple entities. + * **Hot-reload** - hot-reloading for systems should be as easy as possible. **Currently not achived yet (WIP!)**. + +Currently library is incredibly fast to iterate over entities and fast enought in direct access to entity component if it's needed. \ +There are some assumptions that should be considered when developing application: + + * Iterating over same components is incredibly fast so it's should be main way of making calculations. + * Using of direct access and events should be used very wisely and not too much. + * Direct component access is faster than events, because events must buffer memory and call multiple system handler callbacks. + * Components can be used to marking entities, assingment to systems and changing logic of entity in runtime. But due to memory fragmentation there sould by many of entities with same type. In other words, sometimes making to many components can lead to performence drop even if adding or removing components is fast enough. + * Systems give great opporunity to separate game logic. Systems can be enabled and disabled easly in runtime. It's can be used to enabling some debug systems if needed. Additionaly this concept makes game logic changes easier to deal with. If you develop your appliactiona wisely it should be trivial to change some core logic by changing only one system, or adding new system. Every entity can easily takes some behaviour from different entity type by adding several components. + +### Features + + * ECS architectural pattern + * Data oriented design + * Safe identifiers (EntityID) + * EntityTemplates - used to add entities, contain list of components and it's data + * Basic events handling + * Easy systems ordering + * Automatic multithreaded jobs generating + * Runtime and fast components adding and removing + * Listeners for adding and removing entity components inside systems + * Passes - systems are grouped to passes. Pass update call update callback of assigned systems. + * Calling custom callbacks for system entity groups + * betterC compatibility + * Emscripten compatibility + +### Planned + + * Worlds - every world works as separate environment. Entities don't with entities from different world. Systems and components should be registered for every world separately. + * Hot-reload support - currently only reloading systems (their functions) works and only if code changes apperas only inside functions. There is possibility to serialize every entity and system, but it's should be provided by library itself with special callbacks and helpers. Additionaly planned is system which helps with taking new EntityID from serialized identifiers. + * External dependencies - ability to provide dependencies between system which isn't related to components. + * Static components - this components will have different memory model and can be accessed only directly. It will be slower with access but don't trigger memory copy when component is added or some different entity was destroyed. It should fix problem with big components which isn't needed by systems iteration callbacks or is required rarely. + * Better EventManager - currently implementy event handling system isn't it what I wanted. I'm not sure exacly what I can improve but multithreaded event execution is one of things which I considered and it probably will work. + * More demos and examples - demo appliaction is very basic now, but in future I planned more minigames and sanbox mode (opportunity to mix many components and systems). I planed some examples to show how to use basic functionality. + * C API - this is currenly in consideration. Everything is dependent on my free time and amount of work required to create good C API. + * More smaller improvement in draft stage... + +For more information about design and usage I recommend to read [documentation](https://mergul.gitlab.io/bubel-ecs/ecs.html)**(WIP)**. + +## Build Instructions + +To build library you needs recent D compiler and optionally Emscripten (with python) to build web version. Currenlty tested are: LDC, DMD and GDC. \ +Supported build systems are DUB and Meson. + +##### DUB +```shell +#available configurations: library, dynlib, library-betterC, dynlib-betterC +dub build -c library -b release +``` + +##### Meson +```shell +#use '-DbetterC=true ' to build betterC code +meson build . #add '--buildtype=release' to build release code +cd build +ninja +``` + +##### Emscripten +```shell +python compile_wasm.py -opt +``` + +For more detailed build options please check documentation for used build system. + +## Demos + +Repository contain demo application. You can check demo [online](https://mergul.gitlab.io/bubel-ecs/ecs_demo.html) or build it form source code using DUB. \ +Online demo support multithreading and page tries to check if client support WASM multithreading or not and loads properly JS and WASM code. It was tested on Chrome, Firefox, Opera, Brave on Linux and Android. On firefox there is problem with multithreaded version so if demo don't works please try to disable shared_memory in browser flags. + +## Code example + +```d + +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; +} + +struct StaticFlag +{ + mixin ECS.Components; +} + +struct UpdateSystem +{ + mixin ECS.System; //makes struct system + + ECS.ExcludedComponents!(StaticFlag); //prevents static entities from update + + struct EntitiesData + { + int length; //entities count + @readonly Entity[] entities; //entities arrays, entity contain ID only + Position[] positions; //positions array + @readonly Velocity[] velocities; //veocities array, readonly (Multithreading tag) + } + + void onUpdate(EntitiesData data) //update callback, called multiple times per frame for every entities types + { + foreach(i; 0..data.length) //iterate over entities + { + data.positions[i].x += data.velocities[i].x * dt; + data.positions[i].y += data.velocities[i].y * dt; + } + } +} + +void main() +{ + manager.beginRegister(); + //register components + manager.registerComponent!Position; + manager.registerComponent!Velocity; + manager.registerComponent!StaticFlag; + //register system with priority 0 + manager.registerSystem!UpdateSystem(0); + manager.endRegister(); + + //allocate template + EntityTemplate* tmpl = manager.allocateEmplate([Velocity.component_id, Position.component_id].staticArray); + scope (exit) manager.freeTemplate(tmpl); + + //gets pointer to template component data + Position* position = tmpl.getComponent!Position; + foreach(i; 0 .. 100) + { + position.x = i % 10; + position.y = i / 10; + manager.addEntity(tmpl); + } + + manager.begin(); //start frame + manager.update(); //update all systems, there onUpdate callbacks are called + manager.end(); //end frame +} + +``` + +## Links + +Documentation: https://mergul.gitlab.io/bubel-ecs/ecs.html \ +Online demo: https://mergul.gitlab.io/bubel-ecs/ecs_demo.html From 109775af871e05f8f7c814e380a900d341c44f20 Mon Sep 17 00:00:00 2001 From: Dawid Masiukiewicz Date: Mon, 4 May 2020 10:33:54 +0000 Subject: [PATCH 04/58] Update README.md --- README.md | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index abc9709..400b0a1 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,9 @@ [![pipeline status](https://gitlab.com/Mergul/bubel-ecs/badges/master/pipeline.svg)](https://gitlab.com/Mergul/bubel-ecs/-/commits/master) [![codecov](https://codecov.io/gl/Mergul/bubel-ecs/branch/master/graph/badge.svg?token=Unm0TJhFoW)](https://codecov.io/gl/Mergul/bubel-ecs) -BubelECS is Entity-Component-System architecture implementation in D language. -Library aims to delivery fast and flexible architecture for developing games. Library is @nogc and betterC compatible. Even Emscripten build works very well. -Important goal is to keep code without any external dependencies, i. eg. multithreading support don't contain any parallel execution -but emit jobs with delegate and array of dependencies. +BubelECS is Entity-Component-System architectural pattern implementation in D language. +Library aims to delivery fast and flexible architecture for developing games. Library is **@nogc** and **betterC** compatible. WASM is supported thorugh Emscripten. +Project haven't any external dependencies. BubelECS was tested on Linux, Windows, Android and WASM. @@ -13,40 +12,38 @@ BubelECS was tested on Linux, Windows, Android and WASM. ## Design -For core information about Entity-Component-System architectural pattern I recommend to read definition described at [Wikipedia](https://en.wikipedia.org/wiki/Entity_component_system). +For core information about Entity-Component-System architectural pattern please read definition described at [Wikipedia](https://en.wikipedia.org/wiki/Entity_component_system). Main design principles are: * **Data oriented design** - components memory is packed into tight block so iterating over entity components is cache friendly - * **Fast and safe EntityID** - every entity is referenced by its unique ID. If entity was destroyed EntityManager will return null pointer for given EntityID. Access to entity from ID is linear operation. - * **Multithreading support** - whole library was developed with multithreading in mind. Adding components is thread-friendly so you get usable EntityID as early as possible. Operations like adding or removing components are deferred to end of frame. Dependencies between systems update are generated automatically. + * **Fast and safe EntityID** - every entity is referenced by its unique ID. Accessing by ID is safe even if entity don'y exist. Access by ID is constant time operation. + * **Multithreading support** - whole library was developed with multithreading in mind. Adding components is thread-friendly so you get usable EntityID as early as possible. Operations like adding or removing components are deferred to end of frame. Dependencies between systems parallel execution are generated automatically. * **Good logic separation** - system needs information only about components which it's use, there is no relation between systems. Systems can be compiled as multiple separate libraries and used together. - * **Easy systems ordering** - systems are ordered by single priority value. Order of execution of systems with same priority is undefined but order for different priorites are always preserved. - * **Flexible entity to system assignment** - system iterate over any entity that has chosen components. Components can be marked as optional so isn't required but can be used by system. Additionaly system can contain list of components which makes entity excluded from calculation. - * **Builtin events handling** - along with EntityManager library contain EventsManager which makes easier to communicate between multiple entities. - * **Hot-reload** - hot-reloading for systems should be as easy as possible. **Currently not achived yet (WIP!)**. + * **Flexible execution model** - system iterate over entities which meet specified conditions. Components can be marked as required, optional or excluded. Systems are exectued in specific order determined by system priority. + * **Builtin events handling** - library has builtin support for event handlig to makes easier communication between different entities. + * **Hot-reload** - hot-reloading for systems should be as easy as possible. In other words library should give functionality to support hot-reload of systems and components with minimal work. **(WIP!)**. -Currently library is incredibly fast to iterate over entities and fast enought in direct access to entity component if it's needed. \ There are some assumptions that should be considered when developing application: - * Iterating over same components is incredibly fast so it's should be main way of making calculations. - * Using of direct access and events should be used very wisely and not too much. + * Iterating over components is fastest way of access data so it's should be main way of making calculations. + * Using of direct access and events should be used very wisely and minimized. * Direct component access is faster than events, because events must buffer memory and call multiple system handler callbacks. - * Components can be used to marking entities, assingment to systems and changing logic of entity in runtime. But due to memory fragmentation there sould by many of entities with same type. In other words, sometimes making to many components can lead to performence drop even if adding or removing components is fast enough. - * Systems give great opporunity to separate game logic. Systems can be enabled and disabled easly in runtime. It's can be used to enabling some debug systems if needed. Additionaly this concept makes game logic changes easier to deal with. If you develop your appliactiona wisely it should be trivial to change some core logic by changing only one system, or adding new system. Every entity can easily takes some behaviour from different entity type by adding several components. + * Components can be used to marking entities, assingment to systems and changing logic of entity in runtime. Using too much component based marking can lead to memory fragmentation and performence drop. + * Systems give great opporunity to separate game logic. Systems can be enabled and disabled easly in runtime. It's can be used to enabling some debug systems if needed. Additionaly this concept makes game logic changes easier to deal with. If you develop your application wisely it should be trivial to change some core logic by changing only several systems or adding some new systems. Every entity can easily takes some behaviour from different entity type by adding several components. ### Features * ECS architectural pattern * Data oriented design * Safe identifiers (EntityID) - * EntityTemplates - used to add entities, contain list of components and it's data + * EntityTemplates * Basic events handling * Easy systems ordering * Automatic multithreaded jobs generating * Runtime and fast components adding and removing * Listeners for adding and removing entity components inside systems - * Passes - systems are grouped to passes. Pass update call update callback of assigned systems. + * Update passes * Calling custom callbacks for system entity groups * betterC compatibility * Emscripten compatibility @@ -54,15 +51,16 @@ There are some assumptions that should be considered when developing application ### Planned * Worlds - every world works as separate environment. Entities don't with entities from different world. Systems and components should be registered for every world separately. - * Hot-reload support - currently only reloading systems (their functions) works and only if code changes apperas only inside functions. There is possibility to serialize every entity and system, but it's should be provided by library itself with special callbacks and helpers. Additionaly planned is system which helps with taking new EntityID from serialized identifiers. + * Hot-reload support - currently only reloading systems (their functions) works. There is possibility to serialize every entity and system, but it's should be provided by library itself with special callbacks and helpers. Additionaly planned is system which helps with taking new EntityID from serialized identifiers. * External dependencies - ability to provide dependencies between system which isn't related to components. - * Static components - this components will have different memory model and can be accessed only directly. It will be slower with access but don't trigger memory copy when component is added or some different entity was destroyed. It should fix problem with big components which isn't needed by systems iteration callbacks or is required rarely. - * Better EventManager - currently implementy event handling system isn't it what I wanted. I'm not sure exacly what I can improve but multithreaded event execution is one of things which I considered and it probably will work. - * More demos and examples - demo appliaction is very basic now, but in future I planned more minigames and sanbox mode (opportunity to mix many components and systems). I planed some examples to show how to use basic functionality. - * C API - this is currenly in consideration. Everything is dependent on my free time and amount of work required to create good C API. - * More smaller improvement in draft stage... + * Static components - this components will have different memory model and can be accessed only directly. It will be slower to access but won't trigger memory copy when component is added. It should fix problem with big components which isn't needed by systems iteration callbacks or is required rarely. + * 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 I recommend to read [documentation](https://mergul.gitlab.io/bubel-ecs/ecs.html)**(WIP)**. +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). ## Build Instructions From 167ad5437ab6b5e49ab14ea33ef8ab3a064a05d3 Mon Sep 17 00:00:00 2001 From: Mergul Date: Mon, 4 May 2020 16:17:40 +0200 Subject: [PATCH 05/58] CI changes --- .gitlab-ci.yml | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 14ba23c..1710e4a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,25 +9,18 @@ build_code: stage: build image: "registry.gitlab.com/mergul/bubel-ecs:latest" script: - - mkdir build - /bin/bash /compile_ecs.sh - - cp artifacts/* build/ - - cp -r public build/ artifacts: expire_in: 1h paths: - - build - rules: - - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"' - when: always - - when: always + - binaries allow_failure: true test_dmd_debug: stage: test image: frolvlad/alpine-glibc script: - - build/dmd_debug_unittest + - binaries/dmd_debug_unittest artifacts: reports: junit: test_report.xml @@ -35,7 +28,7 @@ test_dmd: stage: test image: frolvlad/alpine-glibc script: - - build/dmd_release_unittest + - binaries/dmd_release_unittest artifacts: reports: junit: test_report.xml @@ -43,7 +36,7 @@ test_dmd_betterC: stage: test image: frolvlad/alpine-glibc script: - - build/dmd_release_unittest_bc + - binaries/dmd_release_unittest_bc artifacts: reports: junit: test_report.xml @@ -56,10 +49,25 @@ coverage_test_dmd: - build_code script: - mkdir reports - - build/dmd_unittest_cov + - binaries/dmd_unittest_cov after_script: - bash <(curl -s https://codecov.io/bash) -s reports -t 1a0c0169-a721-4085-8252-fed4755dcd8c +build_wasm: + stage: build + image: "registry.gitlab.com/mergul/bubel-ecs:latest" + script: + - /bin/bash /compile_wasm.sh + - /bin/bash /gen_doc.sh + artifacts: + expire_in: 1h + paths: + - build + rules: + - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"' + when: always + allow_failure: true + emscripten: stage: build_emscripten image: "registry.gitlab.com/mergul/bubel-ecs/emscripten:latest" From 5411e97cb1b65a0f4dac8544b83ec5e1147f8c5a Mon Sep 17 00:00:00 2001 From: Mergul Date: Tue, 5 May 2020 16:56:51 +0200 Subject: [PATCH 06/58] Move ECS to Bubel module --- .gitlab-ci.yml | 4 +++ README.md | 5 ++++ demos/external/sources/mmutils/thread_pool.d | 4 +-- demos/source/app.d | 6 ++-- demos/source/demos/bullet_madnes.d | 10 +++---- demos/source/demos/chipmunk2d.d | 10 +++---- demos/source/demos/events.d | 10 +++---- demos/source/demos/flag_component.d | 10 +++---- demos/source/demos/physics.d | 10 +++---- demos/source/demos/simple.d | 10 +++---- demos/source/demos/snake.d | 12 ++++---- demos/source/demos/space_invaders.d | 10 +++---- demos/source/game_core/job_updater.d | 8 +++--- demos/source/gui/manager.d | 8 +++--- demos/source/gui/system.d | 2 +- demos/source/gui/template_.d | 2 +- demos/utils/source/ecs_utils/gfx/buffer.d | 2 +- demos/utils/source/ecs_utils/gfx/config.d | 4 +-- demos/utils/source/ecs_utils/gfx/material.d | 2 +- demos/utils/source/ecs_utils/gfx/mesh.d | 2 +- demos/utils/source/ecs_utils/gfx/renderer.d | 2 +- demos/utils/source/ecs_utils/gfx/shader.d | 2 +- demos/utils/source/ecs_utils/gfx/texture.d | 2 +- demos/utils/source/ecs_utils/gfx/vertex.d | 2 +- meson.build | 30 ++++++++++---------- source/{ => bubel}/ecs/atomic.d | 2 +- source/{ => bubel}/ecs/attributes.d | 2 +- source/{ => bubel}/ecs/block_allocator.d | 6 ++-- source/{ => bubel}/ecs/core.d | 6 ++-- source/{ => bubel}/ecs/entity.d | 6 ++-- source/{ => bubel}/ecs/events.d | 10 +++---- source/{ => bubel}/ecs/hash_map.d | 6 ++-- source/{ => bubel}/ecs/id_manager.d | 10 +++---- source/{ => bubel}/ecs/manager.d | 26 ++++++++--------- source/bubel/ecs/package.d | 10 +++++++ source/{ => bubel}/ecs/simple_vector.d | 4 +-- source/{ => bubel}/ecs/std.d | 2 +- source/{ => bubel}/ecs/system.d | 6 ++-- source/{ => bubel}/ecs/traits.d | 2 +- source/{ => bubel}/ecs/vector.d | 4 +-- source/ecs/package.d | 10 ------- tests/basic.d | 8 +++--- tests/id_manager.d | 4 +-- tests/runner.d | 6 ++-- tests/tests.d | 14 ++++----- tests/vector.d | 4 +-- 46 files changed, 163 insertions(+), 154 deletions(-) rename source/{ => bubel}/ecs/atomic.d (99%) rename source/{ => bubel}/ecs/attributes.d (97%) rename source/{ => bubel}/ecs/block_allocator.d (97%) rename source/{ => bubel}/ecs/core.d (96%) rename source/{ => bubel}/ecs/entity.d (97%) rename source/{ => bubel}/ecs/events.d (97%) rename source/{ => bubel}/ecs/hash_map.d (98%) rename source/{ => bubel}/ecs/id_manager.d (98%) rename source/{ => bubel}/ecs/manager.d (99%) create mode 100644 source/bubel/ecs/package.d rename source/{ => bubel}/ecs/simple_vector.d (95%) rename source/{ => bubel}/ecs/std.d (99%) rename source/{ => bubel}/ecs/system.d (98%) rename source/{ => bubel}/ecs/traits.d (97%) rename source/{ => bubel}/ecs/vector.d (99%) delete mode 100644 source/ecs/package.d diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1710e4a..a2d26ff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,7 @@ +default: + artifacts: + expire_in: 1 day + stages: - build - test diff --git a/README.md b/README.md index 400b0a1..b223f72 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,11 @@ ninja python compile_wasm.py -opt ``` +##### Documentation +```shell +adrdox -i source/bubel/ecs/ -o docs/ -s skeleton.html +``` + For more detailed build options please check documentation for used build system. ## Demos diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 374fbc1..161eb22 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -1,6 +1,6 @@ module mmutils.thread_pool; -import ecs.atomic; +import bubel.ecs.atomic; //import core.stdc.stdio; //import core.stdc.stdlib : free, malloc, realloc; @@ -32,7 +32,7 @@ else version (D_BetterC) { - import ecs.std; + import bubel.ecs.std; extern (C) __gshared int _d_eh_personality(int, int, size_t, void*, void*) { return 0; diff --git a/demos/source/app.d b/demos/source/app.d index 150d653..acdc385 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -6,9 +6,9 @@ import cimgui.cimgui; import game_core.job_updater; -import ecs.manager; -import ecs.core; -import ecs.std; +import bubel.ecs.manager; +import bubel.ecs.core; +import bubel.ecs.std; import ecs_utils.gfx.renderer; import ecs_utils.imgui_bind; diff --git a/demos/source/demos/bullet_madnes.d b/demos/source/demos/bullet_madnes.d index 0996e2e..420d6a3 100644 --- a/demos/source/demos/bullet_madnes.d +++ b/demos/source/demos/bullet_madnes.d @@ -6,11 +6,11 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/demos/chipmunk2d.d b/demos/source/demos/chipmunk2d.d index 25b9c66..96e5fa6 100644 --- a/demos/source/demos/chipmunk2d.d +++ b/demos/source/demos/chipmunk2d.d @@ -6,11 +6,11 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/demos/events.d b/demos/source/demos/events.d index 620ff4d..6215160 100644 --- a/demos/source/demos/events.d +++ b/demos/source/demos/events.d @@ -6,11 +6,11 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/demos/flag_component.d b/demos/source/demos/flag_component.d index a1863b9..392164e 100644 --- a/demos/source/demos/flag_component.d +++ b/demos/source/demos/flag_component.d @@ -6,11 +6,11 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/demos/physics.d b/demos/source/demos/physics.d index 6e9ba4a..5fccc0b 100644 --- a/demos/source/demos/physics.d +++ b/demos/source/demos/physics.d @@ -6,11 +6,11 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index edd20c6..89fe801 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -6,11 +6,11 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 6bb8cef..c4123ba 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -6,12 +6,12 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; -import ecs.vector; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; +import bubel.ecs.vector; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index bddf53c..92c4e15 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -6,11 +6,11 @@ import bindbc.sdl; import cimgui.cimgui; -import ecs.attributes; -import ecs.core; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import ecs_utils.gfx.texture; import ecs_utils.math.vector; diff --git a/demos/source/game_core/job_updater.d b/demos/source/game_core/job_updater.d index 46cd609..6c20a83 100644 --- a/demos/source/game_core/job_updater.d +++ b/demos/source/game_core/job_updater.d @@ -1,13 +1,13 @@ module game_core.job_updater; -import ecs.std; -import ecs.vector; -import ecs.atomic; +import bubel.ecs.std; +import bubel.ecs.vector; +import bubel.ecs.atomic; import ecs_utils.utils; //import core.time; -import ecs.manager; +import bubel.ecs.manager; import mmutils.thread_pool; version(LDC) diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index 8a46a92..185fcd1 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -4,10 +4,10 @@ import app; import cimgui.cimgui; -import ecs.std; -import ecs.system; -import ecs.vector; -import ecs.entity; +import bubel.ecs.std; +import bubel.ecs.system; +import bubel.ecs.vector; +import bubel.ecs.entity; import gui.system; import gui.template_; diff --git a/demos/source/gui/system.d b/demos/source/gui/system.d index bbee409..112bed3 100644 --- a/demos/source/gui/system.d +++ b/demos/source/gui/system.d @@ -1,6 +1,6 @@ module gui.system; -import ecs.system; +import bubel.ecs.system; struct SystemGUI { diff --git a/demos/source/gui/template_.d b/demos/source/gui/template_.d index 2aa1833..4d3de11 100644 --- a/demos/source/gui/template_.d +++ b/demos/source/gui/template_.d @@ -1,6 +1,6 @@ module gui.template_; -import ecs.entity; +import bubel.ecs.entity; struct TemplateGUI { diff --git a/demos/utils/source/ecs_utils/gfx/buffer.d b/demos/utils/source/ecs_utils/gfx/buffer.d index 2c25324..b11cb85 100644 --- a/demos/utils/source/ecs_utils/gfx/buffer.d +++ b/demos/utils/source/ecs_utils/gfx/buffer.d @@ -1,6 +1,6 @@ module ecs_utils.gfx.buffer; -import ecs.std; +import bubel.ecs.std; import glad.gl.gl; import glad.gl.gles2; diff --git a/demos/utils/source/ecs_utils/gfx/config.d b/demos/utils/source/ecs_utils/gfx/config.d index de5528a..0683647 100644 --- a/demos/utils/source/ecs_utils/gfx/config.d +++ b/demos/utils/source/ecs_utils/gfx/config.d @@ -2,7 +2,7 @@ module ecs_utils.gfx.config; import bindbc.sdl; -import ecs.std; +import bubel.ecs.std; import ecs_utils.gfx.material; import ecs_utils.gfx.mesh; @@ -18,7 +18,7 @@ enum LayerType sorted } -import ecs.vector; +import bubel.ecs.vector; static struct GfxConfig { diff --git a/demos/utils/source/ecs_utils/gfx/material.d b/demos/utils/source/ecs_utils/gfx/material.d index b697992..fbd88b9 100644 --- a/demos/utils/source/ecs_utils/gfx/material.d +++ b/demos/utils/source/ecs_utils/gfx/material.d @@ -2,7 +2,7 @@ module ecs_utils.gfx.material; import bindbc.sdl; -import ecs.std; +import bubel.ecs.std; import ecs_utils.gfx.shader; diff --git a/demos/utils/source/ecs_utils/gfx/mesh.d b/demos/utils/source/ecs_utils/gfx/mesh.d index 346226f..20d5855 100644 --- a/demos/utils/source/ecs_utils/gfx/mesh.d +++ b/demos/utils/source/ecs_utils/gfx/mesh.d @@ -2,7 +2,7 @@ module ecs_utils.gfx.mesh; import bindbc.sdl; -import ecs.std; +import bubel.ecs.std; import ecs_utils.gfx.buffer; diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index 2a04c57..d56b5c8 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -2,7 +2,7 @@ module ecs_utils.gfx.renderer; import bindbc.sdl; -import ecs.std; +import bubel.ecs.std; //import ecs_utils.core : Backend; import ecs_utils.gfx.buffer; diff --git a/demos/utils/source/ecs_utils/gfx/shader.d b/demos/utils/source/ecs_utils/gfx/shader.d index 7749013..5e24d9a 100644 --- a/demos/utils/source/ecs_utils/gfx/shader.d +++ b/demos/utils/source/ecs_utils/gfx/shader.d @@ -2,7 +2,7 @@ module ecs_utils.gfx.shader; import bindbc.sdl; -import ecs.std; +import bubel.ecs.std; import glad.gl.gl; diff --git a/demos/utils/source/ecs_utils/gfx/texture.d b/demos/utils/source/ecs_utils/gfx/texture.d index bb4c62a..05e2fd9 100644 --- a/demos/utils/source/ecs_utils/gfx/texture.d +++ b/demos/utils/source/ecs_utils/gfx/texture.d @@ -2,7 +2,7 @@ module ecs_utils.gfx.texture; import bindbc.sdl; -import ecs.std; +import bubel.ecs.std; import ecs_utils.math.vector; diff --git a/demos/utils/source/ecs_utils/gfx/vertex.d b/demos/utils/source/ecs_utils/gfx/vertex.d index 1d11fdd..b63803c 100644 --- a/demos/utils/source/ecs_utils/gfx/vertex.d +++ b/demos/utils/source/ecs_utils/gfx/vertex.d @@ -1,6 +1,6 @@ module ecs_utils.gfx.vertex; -import ecs.std; +import bubel.ecs.std; struct Vertex { diff --git a/meson.build b/meson.build index 3317d5c..c31b93a 100644 --- a/meson.build +++ b/meson.build @@ -1,21 +1,21 @@ project('DECS', 'd') src = [ - 'source/ecs/atomic.d', - 'source/ecs/attributes.d', - 'source/ecs/block_allocator.d', - 'source/ecs/core.d', - 'source/ecs/entity.d', - 'source/ecs/events.d', - 'source/ecs/hash_map.d', - 'source/ecs/id_manager.d', - 'source/ecs/manager.d', - 'source/ecs/package.d', - 'source/ecs/simple_vector.d', - 'source/ecs/std.d', - 'source/ecs/system.d', - 'source/ecs/traits.d', - 'source/ecs/vector.d' + '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 = [ diff --git a/source/ecs/atomic.d b/source/bubel/ecs/atomic.d similarity index 99% rename from source/ecs/atomic.d rename to source/bubel/ecs/atomic.d index 5e5f447..9155c8f 100644 --- a/source/ecs/atomic.d +++ b/source/bubel/ecs/atomic.d @@ -7,7 +7,7 @@ Emscripten functions are contained in API similar to druntime. Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.atomic; +module bubel.ecs.atomic; version(Emscripten)version = ECSEmscripten; diff --git a/source/ecs/attributes.d b/source/bubel/ecs/attributes.d similarity index 97% rename from source/ecs/attributes.d rename to source/bubel/ecs/attributes.d index 20d0f60..2bc0aec 100644 --- a/source/ecs/attributes.d +++ b/source/bubel/ecs/attributes.d @@ -20,7 +20,7 @@ Struct EntitiesData Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.attributes; +module bubel.ecs.attributes; ///Used to mark optional components for system. enum optional = "optional"; diff --git a/source/ecs/block_allocator.d b/source/bubel/ecs/block_allocator.d similarity index 97% rename from source/ecs/block_allocator.d rename to source/bubel/ecs/block_allocator.d index d9f08ca..740b762 100644 --- a/source/ecs/block_allocator.d +++ b/source/bubel/ecs/block_allocator.d @@ -6,10 +6,10 @@ Module contain memory allocator. Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.block_allocator; +module bubel.ecs.block_allocator; -import ecs.manager; -import ecs.std; +import bubel.ecs.manager; +import bubel.ecs.std; /************************************************************************************************************************ Allocator allocate large blocks and return smaller blocks. When there is no more blocks then next large block is allocated. diff --git a/source/ecs/core.d b/source/bubel/ecs/core.d similarity index 96% rename from source/ecs/core.d rename to source/bubel/ecs/core.d index c346c9f..ccdf3e2 100644 --- a/source/ecs/core.d +++ b/source/bubel/ecs/core.d @@ -49,10 +49,10 @@ Struct System1 Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.core; +module bubel.ecs.core; -public import ecs.manager; -public import ecs.entity; +public import bubel.ecs.manager; +public import bubel.ecs.entity; /************************************************************************************************************************ Main struct used as namespace for templates. diff --git a/source/ecs/entity.d b/source/bubel/ecs/entity.d similarity index 97% rename from source/ecs/entity.d rename to source/bubel/ecs/entity.d index 0bd2dea..441f412 100644 --- a/source/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -4,10 +4,10 @@ Entity module. Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.entity; +module bubel.ecs.entity; -import ecs.system; -import ecs.manager; +import bubel.ecs.system; +import bubel.ecs.manager; /************************************************************************************************************************ Entity ID structure. Used as reference to Entity. Pointer to entity should be ever used to store entity reference! diff --git a/source/ecs/events.d b/source/bubel/ecs/events.d similarity index 97% rename from source/ecs/events.d rename to source/bubel/ecs/events.d index ac7e185..772d5b5 100644 --- a/source/ecs/events.d +++ b/source/bubel/ecs/events.d @@ -1,9 +1,9 @@ -module ecs.events; +module bubel.ecs.events; -import ecs.block_allocator; -import ecs.entity; -import ecs.manager; -import ecs.std; +import bubel.ecs.block_allocator; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; import std.algorithm.comparison : max; diff --git a/source/ecs/hash_map.d b/source/bubel/ecs/hash_map.d similarity index 98% rename from source/ecs/hash_map.d rename to source/bubel/ecs/hash_map.d index 5a8b253..1f7a1f8 100755 --- a/source/ecs/hash_map.d +++ b/source/bubel/ecs/hash_map.d @@ -1,9 +1,9 @@ -module ecs.hash_map; +module bubel.ecs.hash_map; import std.traits; -import ecs.vector; -import ecs.traits; +import bubel.ecs.vector; +import bubel.ecs.traits; enum doNotInline = "version(DigitalMars)pragma(inline,false);version(LDC)pragma(LDC_never_inline);"; diff --git a/source/ecs/id_manager.d b/source/bubel/ecs/id_manager.d similarity index 98% rename from source/ecs/id_manager.d rename to source/bubel/ecs/id_manager.d index 1ab8465..c8eadec 100644 --- a/source/ecs/id_manager.d +++ b/source/bubel/ecs/id_manager.d @@ -1,10 +1,10 @@ -module ecs.id_manager; +module bubel.ecs.id_manager; -import ecs.entity; -import ecs.std; -import ecs.vector; +import bubel.ecs.entity; +import bubel.ecs.std; +import bubel.ecs.vector; -import ecs.atomic; +import bubel.ecs.atomic; import core.stdc.string : memcpy; /************************************************************************************************************************ diff --git a/source/ecs/manager.d b/source/bubel/ecs/manager.d similarity index 99% rename from source/ecs/manager.d rename to source/bubel/ecs/manager.d index aca7f53..be4f37a 100644 --- a/source/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -4,7 +4,7 @@ Most important module. Almost every function is called from EntityManager. Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.manager; +module bubel.ecs.manager; import std.algorithm : max; import std.conv : to; @@ -14,21 +14,21 @@ import std.traits; //import core.stdc.stdlib : qsort; //import core.stdc.string; -import ecs.system; //not ordered as forward reference bug workaround -import ecs.block_allocator; -import ecs.entity; -import ecs.events; -import ecs.hash_map; -import ecs.id_manager; -import ecs.simple_vector; -import ecs.std; -import ecs.traits; -import ecs.vector; -import ecs.atomic; +import bubel.ecs.system; //not ordered as forward reference bug workaround +import bubel.ecs.block_allocator; +import bubel.ecs.entity; +import bubel.ecs.events; +import bubel.ecs.hash_map; +import bubel.ecs.id_manager; +import bubel.ecs.simple_vector; +import bubel.ecs.std; +import bubel.ecs.traits; +import bubel.ecs.vector; +import bubel.ecs.atomic; export alias gEM = EntityManager.instance; export alias gEntityManager = EntityManager.instance; -alias SerializeVector = ecs.vector.Vector!ubyte; +alias SerializeVector = bubel.ecs.vector.Vector!ubyte; /************************************************************************************************************************ Entity manager is responsible for everything. diff --git a/source/bubel/ecs/package.d b/source/bubel/ecs/package.d new file mode 100644 index 0000000..ee3f62b --- /dev/null +++ b/source/bubel/ecs/package.d @@ -0,0 +1,10 @@ +module ecs; + +public import bubel.ecs.core; +public import bubel.ecs.entity; +public import bubel.ecs.manager; +public import bubel.ecs.system; + +import bubel.ecs.events; +import bubel.ecs.id_manager; +import bubel.ecs.std; \ No newline at end of file diff --git a/source/ecs/simple_vector.d b/source/bubel/ecs/simple_vector.d similarity index 95% rename from source/ecs/simple_vector.d rename to source/bubel/ecs/simple_vector.d index 175c015..28d4707 100644 --- a/source/ecs/simple_vector.d +++ b/source/bubel/ecs/simple_vector.d @@ -1,6 +1,6 @@ -module ecs.simple_vector; +module bubel.ecs.simple_vector; -import ecs.std; +import bubel.ecs.std; //import core.stdc.string; diff --git a/source/ecs/std.d b/source/bubel/ecs/std.d similarity index 99% rename from source/ecs/std.d rename to source/bubel/ecs/std.d index c027fd5..4cec197 100644 --- a/source/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -5,7 +5,7 @@ This module contain implementation of standard functionality. Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.std; +module bubel.ecs.std; version(Emscripten)version = ECSEmscripten; diff --git a/source/ecs/system.d b/source/bubel/ecs/system.d similarity index 98% rename from source/ecs/system.d rename to source/bubel/ecs/system.d index 22a3955..6452e6c 100644 --- a/source/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -4,10 +4,10 @@ System module. Copyright: Copyright © 2018-2019, Dawid Masiukiewicz, Michał Masiukiewicz License: BSD 3-clause, see LICENSE file in project root folder. */ -module ecs.system; +module bubel.ecs.system; -import ecs.entity; -import ecs.manager; +import bubel.ecs.entity; +import bubel.ecs.manager; /************************************************************************************************************************ System contain data required to proper glue EntityManager with Systems. diff --git a/source/ecs/traits.d b/source/bubel/ecs/traits.d similarity index 97% rename from source/ecs/traits.d rename to source/bubel/ecs/traits.d index d19259f..7043b2e 100644 --- a/source/ecs/traits.d +++ b/source/bubel/ecs/traits.d @@ -1,4 +1,4 @@ -module ecs.traits; +module bubel.ecs.traits; import std.traits; diff --git a/source/ecs/vector.d b/source/bubel/ecs/vector.d similarity index 99% rename from source/ecs/vector.d rename to source/bubel/ecs/vector.d index 84ecc51..3334be2 100644 --- a/source/ecs/vector.d +++ b/source/bubel/ecs/vector.d @@ -1,8 +1,8 @@ -module ecs.vector; +module bubel.ecs.vector; import core.bitop; //import core.stdc.stdlib : free, malloc; -import ecs.std; +import bubel.ecs.std; //import core.stdc.string : memcpy, memset; //import std.algorithm : swap; import std.conv : emplace; diff --git a/source/ecs/package.d b/source/ecs/package.d deleted file mode 100644 index eda440d..0000000 --- a/source/ecs/package.d +++ /dev/null @@ -1,10 +0,0 @@ -module ecs; - -public import ecs.core; -public import ecs.entity; -public import ecs.manager; -public import ecs.system; - -import ecs.events; -import ecs.id_manager; -import ecs.std; \ No newline at end of file diff --git a/tests/basic.d b/tests/basic.d index f3f2832..653575f 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -1,9 +1,9 @@ module tests.basic; -import ecs.core; -import ecs.manager; -import ecs.system; -import ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.system; +import bubel.ecs.attributes; import std.array : staticArray; diff --git a/tests/id_manager.d b/tests/id_manager.d index afaafe5..b0f97d5 100644 --- a/tests/id_manager.d +++ b/tests/id_manager.d @@ -1,7 +1,7 @@ module tests.id_manager; -import ecs.id_manager; -import ecs.entity; +import bubel.ecs.id_manager; +import bubel.ecs.entity; unittest { diff --git a/tests/runner.d b/tests/runner.d index 5eaf99b..7b8f6b5 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -5,9 +5,9 @@ import core.stdc.stdio; import core.stdc.string; import core.sys.posix.setjmp; -import ecs.vector; -import ecs.simple_vector; -import ecs.std; +import bubel.ecs.vector; +import bubel.ecs.simple_vector; +import bubel.ecs.std; enum int ASSERTED = 123; enum string OUT_FILE = "test_report.xml"; diff --git a/tests/tests.d b/tests/tests.d index ea554d1..d923116 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -3,12 +3,12 @@ module tests.tests; import std.experimental.allocator; import std.experimental.allocator.mallocator;*/ -import ecs.entity; -import ecs.events; -import ecs.manager; -import ecs.system; -import ecs.attributes; -import ecs.core; +import bubel.ecs.entity; +import bubel.ecs.events; +import bubel.ecs.manager; +import bubel.ecs.system; +import bubel.ecs.attributes; +import bubel.ecs.core; version (WebAssembly) { @@ -714,7 +714,7 @@ else: //foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id); - import ecs.std; + import bubel.ecs.std; EntityID[] idss = Mallocator.makeArray!EntityID(5000); //[5000] //scope(exit)Mallocator.dispose(idss); diff --git a/tests/vector.d b/tests/vector.d index 4b2ad5b..d733f0f 100644 --- a/tests/vector.d +++ b/tests/vector.d @@ -1,7 +1,7 @@ module tests.vector; -import ecs.simple_vector; -//import ecs.vector; +import bubel.ecs.simple_vector; +//import bubel.ecs.vector; @("simple-vector") unittest From 46aba822d0a3024d7177261b18844e130a2ff65a Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 6 May 2020 10:55:40 +0200 Subject: [PATCH 07/58] Improved documentation and removed some old code --- source/bubel/ecs/id_manager.d | 27 --------------------------- source/bubel/ecs/simple_vector.d | 8 ++++++++ source/bubel/ecs/system.d | 26 +++++++++++++------------- 3 files changed, 21 insertions(+), 40 deletions(-) diff --git a/source/bubel/ecs/id_manager.d b/source/bubel/ecs/id_manager.d index c8eadec..4c3a2c3 100644 --- a/source/bubel/ecs/id_manager.d +++ b/source/bubel/ecs/id_manager.d @@ -17,10 +17,6 @@ struct IDManager */ pragma(inline, false) EntityID getNewID() nothrow @nogc { - //uint current = m_next_id; - //uint next;// = m_ids_array[m_next_id].next_id; -//begin: - //if (current == uint.max)//> m_last_id) int current = m_stack_top.atomicOp!"-="(1) + 1; if(current < 0) { @@ -48,29 +44,11 @@ struct IDManager return id; } - - //current += 1; uint index = m_free_stack[current]; EntityID id; id.id = index; id.counter = m_ids_array[index].counter; - //current = m_ids_array[index].next_id; return id; - - /*next = m_ids_array[current].next_id; - if(cas(&m_next_id,current,next)) - { - EntityID id; - id.id = current; - id.counter = m_ids_array[current].counter; - m_next_id = m_ids_array[current].next_id; - return id; - } - else - { - current = next; - goto begin; - }*/ } /************************************************************************************************************************ @@ -82,9 +60,7 @@ struct IDManager if (data.counter != id.counter) return; data.counter++; - //data.next_id = m_next_id; data.entity = null; - ///m_next_id = id.id; m_stack_top.atomicOp!"+="(1); m_free_stack[m_stack_top] = id.id; @@ -241,13 +217,10 @@ struct IDManager private: Mutex* add_mutex; - //shared uint m_next_id = 0; - //shared uint m_last_id = 0; Data[] m_ids_array = null; uint m_blocks_count = 0; Block[] m_blocks; - //shared int m_stack_top = -1; uint[] m_free_stack = null; align(64) shared uint m_last_id = 0; diff --git a/source/bubel/ecs/simple_vector.d b/source/bubel/ecs/simple_vector.d index 28d4707..1de026e 100644 --- a/source/bubel/ecs/simple_vector.d +++ b/source/bubel/ecs/simple_vector.d @@ -4,11 +4,16 @@ import bubel.ecs.std; //import core.stdc.string; +/************************************************************************************************************************ +Vector for byte data. Simpler than standard template-based implementation designed for better performance. \ +Rellocates 1024 elements at once instead of doubling size. +*/ struct SimpleVector { @disable this(this); + ///Add element to vector void add(ubyte el) nothrow @nogc { while(used >= data.length) @@ -19,6 +24,7 @@ struct SimpleVector data[used++] = el; } + ///Add array of elements to vector void add(ubyte[] el) nothrow @nogc { while(used + el.length >= data.length) @@ -30,6 +36,7 @@ struct SimpleVector used += el.length; } + ///Return vector length size_t length() nothrow @nogc { return used; @@ -55,6 +62,7 @@ struct SimpleVector return used; } + ///set vector length to 0 void clear() nothrow @nogc { used = 0; diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index 6452e6c..7343831 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -14,16 +14,16 @@ System contain data required to proper glue EntityManager with Systems. System callbacks: $(LIST * void onUpdate(EntitesData); - * void onEnable() - * void onDisable(); - * bool onBegin(); - * void onEnd(); - * void onCreate() - * void onDestroy(); - * void onAddEntity(EntitesData); - * void onRemoveEntity(EntitiesData); - * void onChangeEntity(EntitiesData); - * void handleEvent(Entity*, Event); + * void onEnable() - called inside system.enable() function + * void onDisable() - called inside system.disable() function + * bool onBegin() - called inside manager.begin() + * void onEnd() - called inside manager.end() + * void onCreate() - called after registration inside registerSystem function + * void onDestroy() - called during re-registration and inside manager destructor + * void onAddEntity(EntitesData) - called for every entity which are assigned to system (by adding new entity or changing its components) + * void onRemoveEntity(EntitiesData) - called for every entity removed from system update process + * void onChangeEntity(EntitiesData) - called for every entity which components are changed but it was previously assigned to system + * void handleEvent(Entity*, Event) - called for every event supported by system ) */ struct System @@ -66,15 +66,15 @@ struct System } /************************************************************************************************************************ - Get system priority. + Get if system will be executed during current frame. Should be checked after manager.begin(). Its value is setted as result of manager.onBegin() callback. */ - export bool execute() nothrow @nogc + export bool willExecute() nothrow @nogc { return m_execute; } /************************************************************************************************************************ - Get system priority. + Get system id. */ export ushort id() nothrow @nogc { From 4bd5a37b5d51be1d9ed088c6461d0f2ab369c3e9 Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 7 May 2020 14:07:07 +0200 Subject: [PATCH 08/58] Demo update and start counting tests times -Fixed performance issue with multithreading and rendering -start making better shaders (by using many macros) -speed up rendeing when maximum objects count was reached -remove map rendering form Snake demo, and render entities by themself -start adding depth and color rendering parameters -added properly names to jobs (for debugging purpses) -starts adding multithreaded rendering -added some math to vectors -changes execute() to willExecute(). Probably should have different name. --- demos/assets/shaders/base.fp | 45 ++- demos/assets/shaders/base.vp | 57 +++- demos/external/sources/mmutils/thread_pool.d | 26 +- demos/source/app.d | 2 +- demos/source/demos/simple.d | 1 + demos/source/demos/snake.d | 319 ++++++++++--------- demos/source/demos/space_invaders.d | 11 +- demos/source/game_core/job_updater.d | 7 +- demos/utils/source/ecs_utils/gfx/renderer.d | 66 +++- demos/utils/source/ecs_utils/math/vector.d | 9 + source/bubel/ecs/manager.d | 4 +- tests/runner.d | 14 + tests/time.d | 66 ++++ 13 files changed, 429 insertions(+), 198 deletions(-) create mode 100644 tests/time.d diff --git a/demos/assets/shaders/base.fp b/demos/assets/shaders/base.fp index 043fa58..ca38c30 100644 --- a/demos/assets/shaders/base.fp +++ b/demos/assets/shaders/base.fp @@ -3,6 +3,31 @@ precision mediump float; precision lowp sampler2D; precision lowp samplerCube; + +#ifdef GLES + #define TEX(x,y) texture2D(x,y) + #if __VERSION__ >290 + #define M_IN in mediump + #define L_IN in lowp + #else + #define M_IN varying mediump + #define L_IN varying lowp + #endif +#else + #define TEX(x,y) texture(x,y) + #if __VERSION__ > 320 + #define M_IN in + #define L_IN in + #else + #define M_IN varying + #define L_IN varying + #endif +#endif + + +M_IN vec2 uv; +M_IN vec4 color; +/* #ifdef GLES #if __VERSION__ >290 in mediump vec2 uv; @@ -15,7 +40,7 @@ precision lowp samplerCube; #else varying vec2 uv; #endif -#endif +#endif*/ //layout(binding = 0)uniform sampler2D tex; @@ -23,20 +48,8 @@ uniform sampler2D tex; //layout(location = 0) out vec4 outColor; -void main() { - - #ifdef GLES - #if __VERSION__ >290 - gl_FragColor = texture(tex,uv); - #else - gl_FragColor = texture2D(tex,uv); - #endif - #else - #if __VERSION__ > 320 - gl_FragColor = texture(tex,uv); - #else - gl_FragColor = texture2D(tex,uv); - #endif - #endif +void main() +{ + gl_FragColor = TEX(tex,uv);// * color; if(gl_FragColor.a < 0.01)discard; } diff --git a/demos/assets/shaders/base.vp b/demos/assets/shaders/base.vp index 42ed4a7..d2d1af8 100644 --- a/demos/assets/shaders/base.vp +++ b/demos/assets/shaders/base.vp @@ -2,12 +2,37 @@ precision highp float; precision highp int; precision lowp sampler2D; precision lowp samplerCube; - #ifdef GLES #if __VERSION__ >290 - layout(location = 0) uniform vec4 matrix_1; - layout(location = 1) uniform vec4 matrix_2; - layout(location = 2) uniform vec4 uv_transform; + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out mediump + #define L_OUT out lowp + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying mediump + #define L_OUT varying lowp + #endif +#else + #if __VERSION__ > 320 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out + #define L_OUT out + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying + #define L_OUT varying + #endif +#endif +/* +#ifdef GLES + #if __VERSION__ >290 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; layout(location = 0) in vec2 positions; layout(location = 1) in vec2 tex_coords; @@ -43,13 +68,35 @@ precision lowp samplerCube; varying vec2 uv; #endif +#endif*/ + + + +M_OUT vec2 uv; +L_OUT vec4 color; + +LOC(0) ATT vec2 positions; +LOC(1) ATT vec2 tex_coords; + +#ifdef VBO_BATCH + LOC(2) ATT float depth; + LOC(3) ATT vec4 vcolor; +#else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + uniform vec4 vcolor; + + float depth = matrix_2.z; #endif void main() { vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1) * vec3(positions,1.0); + position.z = depth; uv = tex_coords * uv_transform.zw + uv_transform.xy; - + color = vcolor; + gl_Position = vec4(position.xy,0,1.0); } diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 161eb22..20491ef 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -9,7 +9,7 @@ import bubel.ecs.atomic; //import std.stdio; import std.algorithm : map; -version = MM_NO_LOGS; // Disable log creation +//version = MM_NO_LOGS; // Disable log creation //version = MM_USE_POSIX_THREADS; // Use posix threads insted of standard library, required for betterC version (Posix)version = MM_USE_POSIX_THREADS; @@ -1141,17 +1141,19 @@ public: foreach (ref log; logs) { - size += log.name.length; // size of name + size += log.name.length + 1; // size of name } char* buffer = cast(char*) malloc(size); foreach (ref log; logs) { - + char[100] name_buffer; + name_buffer[0 .. log.name.length] = log.name; + name_buffer[log.name.length] = 0; size_t charWritten = snprintf(buffer + used, size - used, `{"name":"%s", "pid":1, "tid":%lld, "ph":"X", "ts":%lld, "dur":%lld }, %s`, - log.name.ptr, threadData.threadId + 1, log.time, log.duration, "\n".ptr); + name_buffer.ptr, threadData.threadId + 1, log.time, log.duration, "\n".ptr); used += charWritten; } @@ -1447,7 +1449,21 @@ private void threadFunc(ThreadData* threadData) if (data is null) { // Thread does not have own job and can not steal it, so wait for a job - bool ok = threadData.semaphore.timedWait(1_000 + !acceptJobs * 10_000); + int tryWait = 0; + //bool ok = threadData.semaphore.timedWait(1_000 + !acceptJobs * 10_000); + bool ok = true; + while(!threadData.semaphore.tryWait()) + { + tryWait++; + if(tryWait>5000) + { + ok = false; + break; + } + static foreach(i;0..10)instructionPause(); + } + if(!ok)ok = threadData.semaphore.timedWait(1_000 + !acceptJobs * 10_000); + if (ok) { diff --git a/demos/source/app.d b/demos/source/app.d index acdc385..27c706d 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -253,7 +253,7 @@ void mainLoop(void* arg) if(launcher.tool && launcher.tool_repeat != 0 && launcher.mouse.left && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) { float range = 500.0 / cast(float)launcher.tool_repeat; - launcher.repeat_time += launcher.delta_time; + launcher.repeat_time += launcher.delta_time*100; while(launcher.repeat_time > range) { launcher.repeat_time -= range; diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 89fe801..8d6b0f2 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -58,6 +58,7 @@ struct DrawSystem void onUpdate(EntitiesData data) { + if(launcher.renderer.item_id >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached foreach(i; 0..data.length) { launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0 , 0); diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index c4123ba..2606fd9 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -30,8 +30,9 @@ struct MapElement empty = 0, apple = 1, wall = 2, + snake = 3, - snake_head_up = 5, + /* snake_head_up = 5, snake_head_down = 6, snake_head_left = 7, snake_head_right = 8, @@ -44,13 +45,31 @@ struct MapElement snake_turn_rd = 15, snake_turn_ru = 16, snake_vertical = 17, - snake_horizontal = 18 + snake_horizontal = 18*/ } Type type; EntityID id; } +enum SnakePart : ubyte +{ + head_up = 0, + head_down = 1, + head_left = 2, + head_right = 3, + tail_up = 4, + tail_down = 5, + tail_left = 6, + tail_right = 7, + turn_ld = 8, + turn_lu = 9, + turn_rd = 10, + turn_ru = 11, + vertical = 12, + horizontal = 13 +} + struct Snake { __gshared const (char)* tips = "Use \"WASD\" keys to move."; @@ -104,39 +123,6 @@ struct Snake *location = random_pos; Entity* apple = launcher.manager.addEntity(apple_tmpl); } - - void drawMap() - { - foreach(x; 0 .. map_size) - { - foreach(y; 0 .. map_size) - { - switch(element(ivec2(x,y)).type) - { - case MapElement.Type.apple:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0 , 0);break; - - case MapElement.Type.snake_head_up:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(48*px,112*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_head_down:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(48*px,144*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_head_left:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,128*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_head_right:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(32*px,128*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_tail_up:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(16*px,112*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_tail_down:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,112*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_tail_left:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(32*px,112*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_tail_right:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,144*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_turn_ld:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(64*px,128*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_turn_lu:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(32*px,144*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_turn_rd:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(16*px,144*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_turn_ru:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(64*px,112*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_vertical:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(16*px,128*px,16*px,16*px), 0, 0 , 0);break; - case MapElement.Type.snake_horizontal:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(48*px,128*px,16*px,16*px), 0, 0 , 0);break; - - case MapElement.Type.wall:launcher.renderer.draw(texture, vec2(x*16,y*16), vec2(16,16), vec4(0,0,1,1), 0, 0 , 0);break; - default:break; - } - } - } - } - } struct Animation @@ -184,6 +170,7 @@ struct CSnake mixin ECS.Component; + struct Parts { uint length = 0; @@ -217,6 +204,7 @@ struct CSnake } Parts parts; + CMovement.Direction direction; } struct CApple @@ -424,81 +412,19 @@ struct MoveSystem else .snake.element(MapElement(),location); } - static CMovement.Direction getDirection(ivec2 p1, ivec2 p2) - { - if(p1.x - p2.x == -1)return CMovement.direction.right; - else if(p1.x - p2.x == 1)return CMovement.direction.left; - else if(p1.y - p2.y == -1)return CMovement.direction.up; - else if(p1.y - p2.y == 1)return CMovement.direction.down; - else if(p1.x - p2.x > 1)return CMovement.direction.right; - else if(p1.x - p2.x < -1)return CMovement.direction.left; - else if(p1.y - p2.y > 1)return CMovement.direction.up; - else return CMovement.direction.down; - } - - static MapElement.Type snakePart(ivec2 p1, ivec2 p2, ivec2 p3) - { - CMovement.Direction direction = getDirection(p1, p2); - CMovement.Direction direction2 = getDirection(p1, p3); - uint case_ = direction*4 + direction2; - final switch(case_) - { - case 0:return MapElement.Type.snake_horizontal; - case 1:return MapElement.Type.snake_horizontal; - case 2:return MapElement.Type.snake_turn_lu; - case 3:return MapElement.Type.snake_turn_ru; - case 4:return MapElement.Type.snake_horizontal; - case 5:return MapElement.Type.snake_horizontal; - case 6:return MapElement.Type.snake_turn_ld; - case 7:return MapElement.Type.snake_turn_rd; - case 8:return MapElement.Type.snake_turn_lu; - case 9:return MapElement.Type.snake_turn_ld; - case 10:return MapElement.Type.snake_vertical; - case 11:return MapElement.Type.snake_vertical; - case 12:return MapElement.Type.snake_turn_ru; - case 13:return MapElement.Type.snake_turn_rd; - case 14:return MapElement.Type.snake_vertical; - case 15:return MapElement.Type.snake_vertical; - } - } - - static MapElement.Type snakeTail(ivec2 p1, ivec2 p2) - { - CMovement.Direction direction = getDirection(p1, p2); - final switch(direction) - { - case CMovement.Direction.up:return MapElement.Type.snake_tail_up; - case CMovement.Direction.down:return MapElement.Type.snake_tail_down; - case CMovement.Direction.left:return MapElement.Type.snake_tail_left; - case CMovement.Direction.right:return MapElement.Type.snake_tail_right; - } - } - void onUpdate(EntitiesData data) { if(data.snakes) { foreach(i; 0..data.length) { + data.snakes[i].direction = data.movement[i].direction; ivec2 new_location = data.location[i]; moveLocation(data.location[i], data.movement[i].direction); final switch(snake.element(data.location[i].location).type) { - case MapElement.Type.snake_head_up:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_head_down:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_head_left:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_head_right:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_tail_up:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_tail_down:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_tail_left:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_tail_right:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_turn_ld:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_turn_lu:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_turn_rd:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_turn_ru:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_vertical:goto case(MapElement.Type.snake_horizontal); - case MapElement.Type.snake_horizontal: - foreach(ivec2 loc; data.snakes[i].parts) + case MapElement.Type.snake: + foreach(loc; data.snakes[i].parts) { destroy_location.x = loc.x * 16; destroy_location.y = loc.y * 16; @@ -520,37 +446,20 @@ struct MoveSystem launcher.manager.addEntity(snake.snake_destroy_particle); launcher.manager.removeEntity(data.entities[i].id); break; + case MapElement.Type.wall:break; - //launcher.manager.removeEntity(data.entities[i].id); - //break; + case MapElement.Type.empty: moveSnake(data.snakes[i], new_location); - final switch(data.movement[i].direction) - { - case CMovement.Direction.up: - snake.element(MapElement(MapElement.Type.snake_head_up, data.entities[i].id),data.location[i].location); - break; - case CMovement.Direction.right: - snake.element(MapElement(MapElement.Type.snake_head_right, data.entities[i].id),data.location[i].location); - break; - case CMovement.Direction.down: - snake.element(MapElement(MapElement.Type.snake_head_down, data.entities[i].id),data.location[i].location); - break; - case CMovement.Direction.left: - snake.element(MapElement(MapElement.Type.snake_head_left, data.entities[i].id),data.location[i].location); - break; - } + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.location[i].location); if(data.snakes[i].parts.length > 1) { - MapElement.Type elem_type = snakePart(data.snakes[i].parts[$-1],data.location[i],data.snakes[i].parts[$-2]); - snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[$-1]); - elem_type = snakeTail(data.snakes[i].parts[1], data.snakes[i].parts[0]); - snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[0]); + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[$-1]); + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[0]); } else if(data.snakes[i].parts.length == 1) { - MapElement.Type elem_type = snakeTail(data.location[i], data.snakes[i].parts[0]); - snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[0]); + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[0]); } break; case MapElement.Type.apple: @@ -559,29 +468,13 @@ struct MoveSystem if(data.snakes[i].parts.length > 1) { - MapElement.Type elem_type = snakePart(data.snakes[i].parts[$-1],data.location[i],data.snakes[i].parts[$-2]); - snake.element(MapElement(elem_type, data.entities[i].id),data.snakes[i].parts[$-1]); + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.snakes[i].parts[$-1]); } else if(data.snakes[i].parts.length == 1) { - MapElement.Type elem_type = snakeTail(data.location[i], new_location); - snake.element(MapElement(elem_type, data.entities[i].id),new_location); - } - final switch(data.movement[i].direction) - { - case CMovement.Direction.up: - snake.element(MapElement(MapElement.Type.snake_head_up, data.entities[i].id),data.location[i].location); - break; - case CMovement.Direction.right: - snake.element(MapElement(MapElement.Type.snake_head_right, data.entities[i].id),data.location[i].location); - break; - case CMovement.Direction.down: - snake.element(MapElement(MapElement.Type.snake_head_down, data.entities[i].id),data.location[i].location); - break; - case CMovement.Direction.left: - snake.element(MapElement(MapElement.Type.snake_head_left, data.entities[i].id),data.location[i].location); - break; + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),new_location); } + snake.element(MapElement(MapElement.Type.snake, data.entities[i].id),data.location[i].location); snake.addApple(); break; } @@ -593,10 +486,10 @@ struct MoveSystem { final switch(data.movement[i].direction) { - case CMovement.Direction.down:data.location[i].location.y -= 1;break; - case CMovement.Direction.up:data.location[i].location.y += 1;break; - case CMovement.Direction.left:data.location[i].location.x -= 1;break; - case CMovement.Direction.right:data.location[i].location.x += 1;break; + case CMovement.Direction.down:data.location[i].y -= 1;break; + case CMovement.Direction.up:data.location[i].y += 1;break; + case CMovement.Direction.left:data.location[i].x -= 1;break; + case CMovement.Direction.right:data.location[i].x += 1;break; } } } @@ -699,6 +592,132 @@ struct FixSnakeDirectionSystem } } +struct DrawAppleSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CILocation[] location; + const (CApple)[] apple; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.location.length) + { + launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0 , 0); + } + } +} + +struct DrawSnakeSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CILocation[] location; + const (CSnake)[] snake; + } + + static CMovement.Direction getDirection(ivec2 p1, ivec2 p2) + { + if(p1.x - p2.x == -1)return CMovement.direction.right; + else if(p1.x - p2.x == 1)return CMovement.direction.left; + else if(p1.y - p2.y == -1)return CMovement.direction.up; + else if(p1.y - p2.y == 1)return CMovement.direction.down; + else if(p1.x - p2.x > 1)return CMovement.direction.right; + else if(p1.x - p2.x < -1)return CMovement.direction.left; + else if(p1.y - p2.y > 1)return CMovement.direction.up; + else return CMovement.direction.down; + } + + static SnakePart snakePart(ivec2 p1, ivec2 p2, ivec2 p3) + { + CMovement.Direction direction = getDirection(p1, p2); + CMovement.Direction direction2 = getDirection(p1, p3); + uint case_ = direction*4 + direction2; + final switch(case_) + { + case 0:return SnakePart.horizontal; + case 1:return SnakePart.horizontal; + case 2:return SnakePart.turn_lu; + case 3:return SnakePart.turn_ru; + case 4:return SnakePart.horizontal; + case 5:return SnakePart.horizontal; + case 6:return SnakePart.turn_ld; + case 7:return SnakePart.turn_rd; + case 8:return SnakePart.turn_lu; + case 9:return SnakePart.turn_ld; + case 10:return SnakePart.vertical; + case 11:return SnakePart.vertical; + case 12:return SnakePart.turn_ru; + case 13:return SnakePart.turn_rd; + case 14:return SnakePart.vertical; + case 15:return SnakePart.vertical; + } + } + + static SnakePart snakeTail(ivec2 p1, ivec2 p2) + { + CMovement.Direction direction = getDirection(p1, p2); + final switch(direction) + { + case CMovement.Direction.up:return SnakePart.tail_up; + case CMovement.Direction.down:return SnakePart.tail_down; + case CMovement.Direction.left:return SnakePart.tail_left; + case CMovement.Direction.right:return SnakePart.tail_right; + } + } + + static void drawElement(ivec2 loc, SnakePart part) + { + final switch(cast(ubyte)part) + { + case SnakePart.tail_up:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,112,16,16)*px, 0, 0, 0);break; + case SnakePart.tail_down:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,112,16,16)*px, 0, 0, 0);break; + case SnakePart.tail_left:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,112,16,16)*px, 0, 0, 0);break; + case SnakePart.tail_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, 0, 0);break; + case SnakePart.turn_ld:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,128,16,16)*px, 0, 0, 0);break; + case SnakePart.turn_lu:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,144,16,16)*px, 0, 0, 0);break; + case SnakePart.turn_rd:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,144,16,16)*px, 0, 0, 0);break; + case SnakePart.turn_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, 0, 0);break; + case SnakePart.vertical:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,128,16,16)*px, 0, 0, 0);break; + case SnakePart.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,16,16)*px, 0, 0, 0);break; + } + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + const (CSnake)* snake = &data.snake[i]; + scope vec2 loc = cast(vec2)(data.location[i].location * 16); + final switch(snake.direction) + { + case CMovement.Direction.up:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,112,16,16)*px, 0, 0 , 0);break; + case CMovement.Direction.down:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,144,16,16)*px, 0, 0 , 0);break; + case CMovement.Direction.left:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,128,16,16)*px, 0, 0 , 0);break; + case CMovement.Direction.right:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(32,128,16,16)*px, 0, 0 , 0);break; + } + if(snake.parts.length >1) + { + foreach(j;1..snake.parts.length - 1)drawElement(snake.parts[j]*16, snakePart(snake.parts[j], snake.parts[j+1], snake.parts[j-1])); + drawElement(snake.parts[$-1]*16, snakePart(snake.parts[$-1], data.location[i], snake.parts[$-2])); + drawElement(snake.parts[0]*16, snakeTail(snake.parts[1], snake.parts[0])); + } + else if(snake.parts.length == 1) + { + drawElement(snake.parts[0]*16, snakeTail(data.location[i], snake.parts[0])); + } + + } + } +} + struct CleanSystem { mixin ECS.System!64; @@ -749,6 +768,8 @@ void snakeStart() launcher.manager.registerSystem!AnimationSystem(-1); launcher.manager.registerSystem!ParticleSystem(-1); launcher.manager.registerSystem!ParticleMovementSystem(-1); + launcher.manager.registerSystem!DrawAppleSystem(99); + launcher.manager.registerSystem!DrawSnakeSystem(101); launcher.manager.endRegister(); @@ -766,7 +787,7 @@ void snakeStart() ushort[4] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id]; snake.snake_tmpl = launcher.manager.allocateTemplate(components); CILocation* loc_comp = snake.snake_tmpl.getComponent!CILocation; - loc_comp.location = ivec2(2,2); + *loc_comp = ivec2(2,2); launcher.manager.addEntity(snake.snake_tmpl); } @@ -794,7 +815,7 @@ void snakeStart() /*foreach(i; 0..10) foreach(j; 0..10) { - loc_comp.location = vec2(i*32+64,j*32+64); + loc_compation = vec2(i*32+64,j*32+64); launcher.manager.addEntity(simple.tmpl); }*/ } @@ -878,7 +899,7 @@ bool snakeLoop() launcher.manager.end(); - snake.drawMap(); + //snake.drawMap(); return true; } \ No newline at end of file diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 92c4e15..6d86113 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -179,6 +179,13 @@ struct CSideMove byte group = -1; } +struct CDepth +{ + mixin ECS.Component; + + short depth; +} + /*####################################################################################################################### ------------------------------------------------ Events ------------------------------------------------------------------ #######################################################################################################################*/ @@ -620,7 +627,7 @@ struct InputMovementSystem return true; } //don't call system update because no key pressed - return true; + return false; } /** @@ -637,7 +644,7 @@ struct InputMovementSystem { data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); } - return; + //return; } //move every entity using movement vector foreach(i; 0..data.length) diff --git a/demos/source/game_core/job_updater.d b/demos/source/game_core/job_updater.d index 6c20a83..47d2423 100644 --- a/demos/source/game_core/job_updater.d +++ b/demos/source/game_core/job_updater.d @@ -63,6 +63,7 @@ struct ECSJobUpdater JobData[1024] jobs; JobCaller[1024] callers; uint count = 0; + string name; void dependantOn(Group* dependency) { @@ -89,7 +90,7 @@ struct ECSJobUpdater void add(JobCaller caller) { callers[count] = caller; - jobs[count] = JobData(&callers[count].callJob,"hmm"); + jobs[count] = JobData(&callers[count].callJob,name); count++; } } @@ -216,6 +217,8 @@ struct ECSJobUpdater return; } + jobs[group.id].name = cast(string)group.caller.system.name; + foreach(ref job;group.jobs) { uint index = 0; @@ -233,7 +236,7 @@ struct ECSJobUpdater foreach(dep;group.dependencies) { - if(jobs[dep.id].count && dep.caller.system.execute && dep.caller.system.enabled)jobs[group.id].dependantOn(&jobs[dep.id]); + if(jobs[dep.id].count && dep.caller.system.willExecute && dep.caller.system.enabled)jobs[group.id].dependantOn(&jobs[dep.id]); else deps--; } diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index d56b5c8..8735d98 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -9,6 +9,9 @@ import ecs_utils.gfx.buffer; import ecs_utils.gfx.texture; import ecs_utils.math.vector; +import bubel.ecs.block_allocator; +import bubel.ecs.vector; + import glad.gl.gl; version = ver1; @@ -41,9 +44,10 @@ enum RenderTechnique struct Renderer { //static SDL_Renderer* main_sdl_renderer; + BlockAllocator allocator; enum MaxObjects = 1024 * 64 * 4; - enum BufferUsage = GL_STATIC_DRAW; + enum BufferUsage = GL_DYNAMIC_DRAW; //SDL_Window* sdl_window; //SDL_Renderer* sdl_renderer; @@ -53,8 +57,35 @@ struct Renderer vec2 view_pos = vec2(-1,-1); vec2 view_size = vec2(1,1); + const uint batch_size = 16_384; //uint[2] time_queries; + struct VertexBlock + { + float[] batch_vertices; + ushort[] batch_indices; + void* memory; + uint itmes = 0; + } + + VertexBlock getBlock() + { + VertexBlock block; + block.memory = allocator.getBlock(); + block.batch_vertices = (cast(float*)block.memory)[0 .. 1]; + return block; + } + + + struct Thread + { + + Vector!VertexBlock block; + RenderData[] render_list; + } + Thread[] threads; + + Buffer[2] ubos; int block_alignment = 1; int block_max_size = 16384; @@ -253,6 +284,8 @@ struct Renderer SDL_Log("Uniform block alignment: %u",block_alignment); SDL_Log("Uniform block max size: %u",block_max_size); SDL_Log("Data offset: %u",data_offset); + + allocator = BlockAllocator(1245184, 32); } } @@ -261,12 +294,13 @@ struct Renderer } - void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, float angle = 0, uint material_id = 0, uint mesh_id = 0) + void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0) { - __draw(this,tex,pos,size,coords,angle,material_id,mesh_id); + if(item_id >= MaxObjects)return; + __draw(this,tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id); } - private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, float angle, uint material_id, uint mesh_id) + private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) { /*with(this_) { @@ -286,7 +320,7 @@ struct Renderer }*/ } - private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, float angle, uint material_id, uint mesh_id) + private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) { //import core.stdc.string; with(this_) @@ -333,13 +367,13 @@ struct Renderer } } - private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, float angle, uint material_id, uint mesh_id) + private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0) { import ecs_utils.gfx.config; //import core.stdc.string; with(this_) { - if(item_id >= MaxObjects)return; + //if(item_id >= MaxObjects)return; //pos += view_pos; size.x *= view_size.x; size.y *= view_size.y; @@ -400,7 +434,7 @@ struct Renderer batch_vertices[item_id*16+14] = GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x; batch_vertices[item_id*16+15] = GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y; - uint ind_id = item_id % 16_384; + uint ind_id = item_id % batch_size; batch_indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id*4); batch_indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id*4); @@ -575,7 +609,7 @@ struct Renderer //glBeginQuery(GL_TIME_ELAPSED, time_queries[0]); if(technique == Technique.vbo_batch) { - uint items = item_id/16_384+1; + uint items = item_id/batch_size+1; foreach(i; 0..items) { if(material_id != render_list[i].material_id) @@ -591,16 +625,16 @@ struct Renderer render_list[i].texture.bind(); } - uint instance_count = 16_384; - if((i+1)*16_384 > item_id) + uint instance_count = batch_size; + if((i+1)*batch_size > item_id) { - instance_count = item_id%16_384; + instance_count = item_id%batch_size; } - glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*16_384*4*16)); - glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)(i*16_384*4*16+8)); + glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16)); + glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16+8)); - glDrawElements(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2)); + glDrawElements(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*batch_size*6*2)); //glDrawElementsBaseVertex(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2),i*16_384*4); } @@ -803,7 +837,7 @@ struct Renderer view_pos = (pos - size * 0.5) * view_size; } - __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, float angle, uint material_id, uint mesh_id) __draw; + __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) __draw; __gshared void function(ref Renderer this_) __present; __gshared void function(ref Renderer this_) __clear; __gshared void function(ref Renderer this_) __initialize; diff --git a/demos/utils/source/ecs_utils/math/vector.d b/demos/utils/source/ecs_utils/math/vector.d index 4b9f3af..a74b6db 100644 --- a/demos/utils/source/ecs_utils/math/vector.d +++ b/demos/utils/source/ecs_utils/math/vector.d @@ -97,6 +97,15 @@ struct ivec2 int[2] data; } + ivec2 opBinary(string op, T)(T v) + { + static if (op == "+") return ivec2(x + v, y + v); + else static if (op == "-") return ivec2(x - v, y - v); + else static if (op == "*") return ivec2(x * v, y * v); + else static if (op == "/") return ivec2(x / v, y / v); + else static assert(0, "Operator "~op~" not implemented"); + } + vec2 opCast() { return vec2(x,y); diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index be4f37a..1b896db 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -1253,7 +1253,7 @@ export struct EntityManager foreach (caller; passes[pass].system_callers) { System* sys = &systems[caller.system_id]; - if (sys.enabled && sys.execute) + if (sys.enabled && sys.willExecute) { if (sys.m_empty) { @@ -1293,7 +1293,7 @@ export struct EntityManager foreach (caller; passes[pass].system_callers) { System* sys = &systems[caller.system_id]; - if (sys.enabled && sys.execute) + if (sys.enabled && sys.willExecute) { uint job_id = 0; void nextJob() diff --git a/tests/runner.d b/tests/runner.d index 7b8f6b5..4aa9bcb 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -9,6 +9,8 @@ import bubel.ecs.vector; import bubel.ecs.simple_vector; import bubel.ecs.std; +import tests.time; + enum int ASSERTED = 123; enum string OUT_FILE = "test_report.xml"; @@ -95,6 +97,8 @@ struct TestRunner(Args...) write(test.name); write("\" classname=\""); write(suite.name); + write("\" time=\""); + write(cast(double)test.time*0.000001); write("\">"); if (test.msg) { @@ -189,8 +193,10 @@ struct TestRunner(Args...) } else { + long time = Time.getUSecTime(); unittest_(); test.passed = true; + test.time = cast(int)(Time.getUSecTime() - time); } } else @@ -281,6 +287,14 @@ struct TestRunner(Args...) junit.add(cast(ubyte[]) txt); } + void write(double num) + { + ubyte[40] buffer; + int len; + len = sprintf(cast(char*) buffer.ptr, "%2.8lf", num); + junit.add(buffer[0 .. len]); + } + void write(uint num) { ubyte[20] buffer; diff --git a/tests/time.d b/tests/time.d new file mode 100644 index 0000000..e91b76e --- /dev/null +++ b/tests/time.d @@ -0,0 +1,66 @@ +module tests.time; + + +version (WebAssembly) +{ + alias int time_t; + alias int clockid_t; + enum CLOCK_REALTIME = 0; + + struct timespec + { + time_t tv_sec; + int tv_nsec; + } + + extern (C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system; + + struct Time + { + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000; + } + } +} +else version (Windows) +{ + import core.stdc.stdio : printf; + import core.sys.windows.windows; + + struct Time + { + static long getUSecTime() + { + LARGE_INTEGER time, freq; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&time); + return time.QuadPart / (freq.QuadPart / 1000_000); + } + } +} +else version (Posix) +{ + import core.stdc.stdio : printf; + import core.sys.posix.time; + + struct Time + { + static long getUSecTime() + { + time_t time; + timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000; //time / 1000_000; + } + } +} \ No newline at end of file From f6e7af10148d7fb47ac7b58f44f6551c6b46640b Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 7 May 2020 21:58:34 +0200 Subject: [PATCH 09/58] Some preformance tests and added EntityMeta structure --- source/bubel/ecs/entity.d | 22 +++++ tests/access_perf.d | 128 +++++++++++++++++++++++++++ tests/perf.d | 178 ++++++++++++++++++++++++++++++++++++++ tests/runner.d | 77 ++++++++++++----- 4 files changed, 385 insertions(+), 20 deletions(-) create mode 100644 tests/access_perf.d create mode 100644 tests/perf.d diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index 441f412..10720a2 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -45,6 +45,28 @@ struct Entity uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof()); return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof); } + + EntityMeta getMeta() + { + EntityMeta meta; + meta.block = gEM.getMetaData(&this); + static if (EntityID.sizeof == 8) + meta.index = cast(ushort)((cast(void*)&this - meta.block.dataBegin()) >> 3); + else + meta.index = cast(ushort)((cast(void*)&this - meta.block.dataBegin()) / EntityID.sizeof()); + return meta; + } +} + +struct EntityMeta +{ + EntityManager.EntitiesBlock* block; + ushort index; + + T* getComponent(T)() const + { + return cast(T*)(cast(void*)block + block.type_info.deltas[T.component_id] + index * T.sizeof); + } } /************************************************************************************************************************ diff --git a/tests/access_perf.d b/tests/access_perf.d new file mode 100644 index 0000000..141a2e6 --- /dev/null +++ b/tests/access_perf.d @@ -0,0 +1,128 @@ +module tests.access_perf; + +import tests.runner; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.entity; + +import std.array : staticArray; + +import core.stdc.stdio; + +struct CLong +{ + mixin ECS.Component; + + alias value this; + + long value = 10; +} + +struct CInt +{ + mixin ECS.Component; + + alias value this; + + int value = 10; +} + +struct CUInt +{ + mixin ECS.Component; + + alias value this; + + uint value = 12; +} + +struct CBig +{ + mixin ECS.Component; + uint[32] data; +} + +EntityTemplate* tmpl; + +void beforeEveryTest() +{ + gEM.initialize(0); + + gEM.beginRegister(); + + gEM.registerComponent!CLong; + gEM.registerComponent!CInt; + gEM.registerComponent!CUInt; + gEM.registerComponent!CBig; + + gEM.endRegister(); + + tmpl = gEM.allocateTemplate([CLong.component_id, CInt.component_id, CUInt.component_id, CBig.component_id].staticArray); + foreach(i; 0 .. 100_000)gEM.addEntity(tmpl); +} + +void afterEveryTest() +{ + if(tmpl)gEM.freeTemplate(tmpl); + tmpl = null; + gEM.destroy(); +} + +@("DirectAccess100k1comp") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEM.getEntity(EntityID(i*4+1,0)); + CUInt* comp1 = entity.getComponent!CUInt; + comp1.value = 4; + } +} + +@("DirectAccess100k4comp") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEM.getEntity(EntityID(i*4+1,0)); + CUInt* comp1 = entity.getComponent!CUInt; + comp1.value = 4; + CInt* comp2 = entity.getComponent!CInt; + comp2.value = 3; + CLong* comp3 = entity.getComponent!CLong; + comp3.value = 1; + CBig* comp4 = entity.getComponent!CBig; + comp4.data[0] = 2; + } +} + +@("DirectAccess100k1compWithMeta") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEM.getEntity(EntityID(i*4+1,0)); + EntityMeta meta = entity.getMeta(); + CUInt* comp1 = meta.getComponent!CUInt; + comp1.value = 4; + } +} + +@("DirectAccess100k4compWithMeta") +unittest +{ + foreach(i;0..25000) + { + Entity* entity = gEM.getEntity(EntityID(i*4+1,0)); + EntityMeta meta = entity.getMeta(); + CUInt* comp1 = meta.getComponent!CUInt; + comp1.value = 4; + CInt* comp2 = meta.getComponent!CInt; + comp2.value = 3; + CLong* comp3 = meta.getComponent!CLong; + comp3.value = 1; + CBig* comp4 = meta.getComponent!CBig; + comp4.data[0] = 2; + } +} \ No newline at end of file diff --git a/tests/perf.d b/tests/perf.d new file mode 100644 index 0000000..135dc54 --- /dev/null +++ b/tests/perf.d @@ -0,0 +1,178 @@ +module tests.perf; + +import tests.runner; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.entity; + +import std.array : staticArray; + +import core.stdc.stdio; + +struct CLong +{ + mixin ECS.Component; + + alias value this; + + long value = 10; +} + +struct CShort +{ + mixin ECS.Component; + + alias value this; + + short value = 12; +} + +struct CInt +{ + mixin ECS.Component; + + alias value this; + + int value = 10; +} + +struct CUInt +{ + mixin ECS.Component; + + alias value this; + + uint value = 12; +} + +struct CBig +{ + mixin ECS.Component; + uint[32] data; +} + +EntityTemplate* tmpl; + +void beforeEveryTest() +{ + gEM.initialize(0); + + gEM.beginRegister(); + + gEM.registerComponent!CLong; + gEM.registerComponent!CShort; + gEM.registerComponent!CInt; + gEM.registerComponent!CUInt; + gEM.registerComponent!CBig; + + gEM.endRegister(); + tmpl = null; +} + +void afterEveryTest() +{ + if(tmpl)gEM.freeTemplate(tmpl); + tmpl = null; + gEM.destroy(); +} + +void smallTmpl() +{ + tmpl = gEM.allocateTemplate([CShort.component_id].staticArray); +} + +void bigTmpl() +{ + tmpl = gEM.allocateTemplate([CBig.component_id].staticArray); +} + +void multiSmallTmpl() +{ + tmpl = gEM.allocateTemplate([CShort.component_id, CLong.component_id, CInt.component_id, CUInt.component_id].staticArray); +} + +void multiBigTmpl() +{ + tmpl = gEM.allocateTemplate([CLong.component_id, CInt.component_id, CUInt.component_id, CBig.component_id].staticArray); +} + +@("AddEntities100k1comp2b") @(before, &smallTmpl) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} + +@("AddEntities100k1comp128b") @(before, &bigTmpl) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} + +@("AddEntities100k4comp18b") @(before, &multiSmallTmpl) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} + +@("AddEntities100k4comp144b") @(before, &multiBigTmpl) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} + +void allocDealloc100k() +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); + gEM.commit(); + foreach(i; 0..100_000)gEM.removeEntity(EntityID(i + 1,0)); + gEM.commit(); +} + +void smallTmplPreAlloc() +{ + tmpl = gEM.allocateTemplate([CShort.component_id].staticArray); + allocDealloc100k(); +} + +void bigTmplPreAlloc() +{ + tmpl = gEM.allocateTemplate([CBig.component_id].staticArray); + allocDealloc100k(); +} + +void multiSmallTmplPreAlloc() +{ + tmpl = gEM.allocateTemplate([CShort.component_id, CLong.component_id, CInt.component_id, CUInt.component_id].staticArray); + allocDealloc100k(); +} + +void multiBigTmplPreAlloc() +{ + tmpl = gEM.allocateTemplate([CLong.component_id, CInt.component_id, CUInt.component_id, CBig.component_id].staticArray); + allocDealloc100k(); +} + +@("AddEntities100k1comp2bPreAlloc") @(before, &smallTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} + +@("AddEntities100k1comp128bPreAlloc") @(before, &bigTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} + +@("AddEntities100k4comp18bPreAlloc") @(before, &multiSmallTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} + +@("AddEntities100k4comp144bPreAlloc") @(before, &multiBigTmplPreAlloc) +unittest +{ + foreach(i; 0..100_000)gEM.addEntity(tmpl); +} \ No newline at end of file diff --git a/tests/runner.d b/tests/runner.d index 4aa9bcb..f299664 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -9,8 +9,19 @@ import bubel.ecs.vector; import bubel.ecs.simple_vector; import bubel.ecs.std; +import std.traits; + import tests.time; +version (LDC) +{ + import ldc.attributes; +} +else +{ + enum optStrategy = 0; +} + enum int ASSERTED = 123; enum string OUT_FILE = "test_report.xml"; @@ -124,42 +135,65 @@ struct TestRunner(Args...) write(""); } + @(optStrategy,"none") void runTests(string[] include = null, string[] exclude = null) { foreach (i, module_; Args) { TestSuite* suite = &suites[i]; suite.name = module_.stringof; + + void function() before; + void function() after; + foreach (index, unittest_; __traits(getUnitTests, module_)) { enum attributes = __traits(getAttributes, unittest_); + static if (attributes.length != 0) { - if (include.length > 0) + foreach(attr_id, attr; attributes) { - bool matched = false; - foreach (str; include) + static if(isFunctionPointer!(attr)){} + else static if(attr == "_tr_before") { - if (match(str, attributes[0])) - { - matched = true; - break; - } + static assert(attr_id+1 < attributes.length); + enum attr2 = attributes[attr_id + 1]; + //static assert(__traits(hasMember, module_, attr2)); + //alias func = __traits(getMember, module_, attr2); + //attr2(); + before = attr2; + //static assert(is(typeof(__traits(getMember, module_, attr2)) == void function())); } - - foreach (str; exclude) + else { - if (match(str, attributes[0])) + if (include.length > 0) { - matched = false; - break; - } - } + bool matched = false; + foreach (str; include) + { + if (match(str, attr)) + { + matched = true; + break; + } + } - if (!matched) - { - suite.skipped++; - continue; + foreach (str; exclude) + { + if (match(str, attr)) + { + matched = false; + break; + } + } + + if (!matched) + { + suite.skipped++; + continue; + } + } } } } @@ -178,6 +212,7 @@ struct TestRunner(Args...) static if (__traits(hasMember, module_, "beforeEveryTest")) module_.beforeEveryTest(); + if(before)before(); version(D_BetterC) { @@ -318,6 +353,8 @@ version (notBetterC) version (D_Coverage) extern (C) void dmd_coverDestPath(string path); } +enum before = "_tr_before"; + void extractStrings(ref Vector!string container, string str) { uint s = 0; @@ -383,7 +420,7 @@ extern (C) int main(int argc, char** args) } } - TestRunner!(tests.runner, tests.id_manager, tests.vector, tests.basic) runner; + TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf) runner; runner.runTests(include[], exclude[]); From c94510a487f3c85ce216b28a88602158aa4f3381 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 9 May 2020 19:41:00 +0200 Subject: [PATCH 10/58] Improved Demo and multithreading rendering: -added support for multithreaded rendering (fast) -improved shaders -added support for rendering depth -added rendering color support -improved DeptThreadPool (dynamics setting number of tryWait counts before TryWait. Low cpu usage with high responivity) -added possibility to change number of threads --- demos/assets/shaders/base.fp | 2 +- demos/assets/shaders/base.vp | 14 +- demos/external/sources/mmutils/thread_pool.d | 6 +- demos/source/app.d | 23 +- demos/source/demos/simple.d | 8 +- demos/source/demos/snake.d | 30 +- demos/source/demos/space_invaders.d | 24 +- demos/utils/source/ecs_utils/gfx/renderer.d | 309 ++++++++++++++----- 8 files changed, 311 insertions(+), 105 deletions(-) diff --git a/demos/assets/shaders/base.fp b/demos/assets/shaders/base.fp index ca38c30..d86e92e 100644 --- a/demos/assets/shaders/base.fp +++ b/demos/assets/shaders/base.fp @@ -50,6 +50,6 @@ uniform sampler2D tex; void main() { - gl_FragColor = TEX(tex,uv);// * color; + gl_FragColor = TEX(tex,uv) * color; if(gl_FragColor.a < 0.01)discard; } diff --git a/demos/assets/shaders/base.vp b/demos/assets/shaders/base.vp index d2d1af8..7be086b 100644 --- a/demos/assets/shaders/base.vp +++ b/demos/assets/shaders/base.vp @@ -70,7 +70,7 @@ precision lowp samplerCube; #endif #endif*/ - +#define VBO_BATCH 1 M_OUT vec2 uv; L_OUT vec4 color; @@ -91,12 +91,16 @@ LOC(1) ATT vec2 tex_coords; #endif void main() { + #ifdef VBO_BATCH + vec3 position = vec3(positions*4,1.0); + uv = tex_coords; + #else + vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1) * vec3(positions,1.0); + uv = tex_coords * uv_transform.zw + uv_transform.xy; + #endif - vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1) * vec3(positions,1.0); - position.z = depth; - uv = tex_coords * uv_transform.zw + uv_transform.xy; color = vcolor; - gl_Position = vec4(position.xy,0,1.0); + gl_Position = vec4(position.xy,depth,1.0); } diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 20491ef..143960c 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -9,13 +9,14 @@ import bubel.ecs.atomic; //import std.stdio; import std.algorithm : map; -//version = MM_NO_LOGS; // Disable log creation +version = MM_NO_LOGS; // Disable log creation //version = MM_USE_POSIX_THREADS; // Use posix threads insted of standard library, required for betterC version (Posix)version = MM_USE_POSIX_THREADS; version (WebAssembly) { + version = MM_NO_LOGS; extern(C) struct FILE { @@ -799,6 +800,7 @@ struct ThreadPool alias FlushLogsDelegaste = void delegate(ThreadData* threadData, JobLog[] logs); /// Type of delegate to flush logs FlushLogsDelegaste onFlushLogs; /// User custom delegate to flush logs, if overriden defaultFlushLogs will be used. Can be sset after initialize() call int logsCacheNum; /// Number of log cache entries. Should be set before setThreadsNum is called + int tryWaitCount = 2000; ///Number of times which tryWait are called before timedWait call. Higher value sets better response but takes CPU time even if there are no jobs. private: ThreadData*[gMaxThreadsNum] threadsData; /// Data for threads align(64) shared int threadsNum; /// Number of threads currentlu accepting jobs @@ -1455,7 +1457,7 @@ private void threadFunc(ThreadData* threadData) while(!threadData.semaphore.tryWait()) { tryWait++; - if(tryWait>5000) + if(tryWait>threadPool.tryWaitCount) { ok = false; break; diff --git a/demos/source/app.d b/demos/source/app.d index 27c706d..af4b331 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -58,6 +58,7 @@ struct Launcher uint style = 3; uint entities_count; bool multithreading; + int threads; ulong timer_freq; double delta_time; uint fps; @@ -253,13 +254,12 @@ void mainLoop(void* arg) if(launcher.tool && launcher.tool_repeat != 0 && launcher.mouse.left && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) { float range = 500.0 / cast(float)launcher.tool_repeat; - launcher.repeat_time += launcher.delta_time*100; + launcher.repeat_time += launcher.delta_time; while(launcher.repeat_time > range) { launcher.repeat_time -= range; launcher.tool((launcher.mouse.position*launcher.scalling)-launcher.render_position, launcher.used_tool, launcher.tool_size); } - } version(WebAssembly) @@ -317,6 +317,14 @@ void mainLoop(void* arg) { launcher.multithreading = !launcher.multithreading; } + igSetNextItemWidth(0); + igLabelText("Threads:",null); + igSameLine(0,4); + if(igSliderInt("##Threads",&launcher.threads, 1, 12, null))//"Multithreading", null, launcher.multithreading, true)) + { + launcher.job_updater.pool.setThreadsNum(launcher.threads); + //launcher.threads = !launcher.multithreading; + } if(igBeginMenu("Show",true)) { if(igMenuItemBool("Statistics",null,launcher.show_stat_wnd,true)) @@ -539,11 +547,14 @@ void mainLoop(void* arg) launcher.renderer.clear(); double loop_time = launcher.getTime(); + launcher.job_updater.pool.tryWaitCount = 5000; if(launcher.loop && !launcher.loop()) { quit(); *cast(bool*)arg = false; } + launcher.job_updater.pool.tryWaitCount = 10; + loop_time = launcher.getTime() - loop_time; double draw_time = launcher.getTime(); @@ -785,7 +796,15 @@ void loadGFX() GfxConfig.materials[0].compile(); GfxConfig.materials[0].bindAttribLocation("positions",0); GfxConfig.materials[0].bindAttribLocation("tex_coords",1); + GfxConfig.materials[0].bindAttribLocation("depth",2); + GfxConfig.materials[0].bindAttribLocation("vcolor",3); GfxConfig.materials[0].link(); + + /* import std.stdio; + writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); + writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); + writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); + writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ GfxConfig.materials[0].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3); GfxConfig.materials[0].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0); diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 8d6b0f2..686f9be 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -47,23 +47,25 @@ struct CTexture struct DrawSystem { - mixin ECS.System!1; + mixin ECS.System!32; struct EntitiesData { uint length; + uint thread_id; @readonly CTexture[] textures; @readonly CLocation[] locations; } void onUpdate(EntitiesData data) { - if(launcher.renderer.item_id >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached foreach(i; 0..data.length) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0 , 0); + launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y*64+data.locations[i].x), uint.max, 0, 0, 0, data.thread_id); //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); } + if(data.thread_id == 0)launcher.renderer.pushData(); } } diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 2606fd9..94f2654 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -607,7 +607,7 @@ struct DrawAppleSystem { foreach(i; 0..data.location.length) { - launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0 , 0); + launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, uint.max, 0); } } } @@ -677,16 +677,16 @@ struct DrawSnakeSystem { final switch(cast(ubyte)part) { - case SnakePart.tail_up:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,112,16,16)*px, 0, 0, 0);break; - case SnakePart.tail_down:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,112,16,16)*px, 0, 0, 0);break; - case SnakePart.tail_left:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,112,16,16)*px, 0, 0, 0);break; - case SnakePart.tail_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, 0, 0);break; - case SnakePart.turn_ld:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,128,16,16)*px, 0, 0, 0);break; - case SnakePart.turn_lu:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,144,16,16)*px, 0, 0, 0);break; - case SnakePart.turn_rd:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,144,16,16)*px, 0, 0, 0);break; - case SnakePart.turn_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, 0, 0);break; - case SnakePart.vertical:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,128,16,16)*px, 0, 0, 0);break; - case SnakePart.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,16,16)*px, 0, 0, 0);break; + case SnakePart.tail_up:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,112,16,16)*px, 0, uint.max, 0);break; + case SnakePart.tail_down:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,112,16,16)*px, 0, uint.max, 0);break; + case SnakePart.tail_left:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,112,16,16)*px, 0, uint.max, 0);break; + case SnakePart.tail_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, uint.max, 0);break; + case SnakePart.turn_ld:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,128,16,16)*px, 0, uint.max, 0);break; + case SnakePart.turn_lu:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,144,16,16)*px, 0, uint.max, 0);break; + case SnakePart.turn_rd:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,144,16,16)*px, 0, uint.max, 0);break; + case SnakePart.turn_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, uint.max, 0);break; + case SnakePart.vertical:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,128,16,16)*px, 0, uint.max, 0);break; + case SnakePart.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,16,16)*px, 0, uint.max, 0);break; } } @@ -698,10 +698,10 @@ struct DrawSnakeSystem scope vec2 loc = cast(vec2)(data.location[i].location * 16); final switch(snake.direction) { - case CMovement.Direction.up:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,112,16,16)*px, 0, 0 , 0);break; - case CMovement.Direction.down:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,144,16,16)*px, 0, 0 , 0);break; - case CMovement.Direction.left:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,128,16,16)*px, 0, 0 , 0);break; - case CMovement.Direction.right:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(32,128,16,16)*px, 0, 0 , 0);break; + case CMovement.Direction.up:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,112,16,16)*px, 0, uint.max, 0);break; + case CMovement.Direction.down:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,144,16,16)*px, 0, uint.max, 0);break; + case CMovement.Direction.left:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,128,16,16)*px, 0, uint.max, 0);break; + case CMovement.Direction.right:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(32,128,16,16)*px, 0, uint.max, 0);break; } if(snake.parts.length >1) { diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 6d86113..30891c8 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -183,6 +183,8 @@ struct CDepth { mixin ECS.Component; + alias depth this; + short depth; } @@ -208,23 +210,33 @@ struct EChangeDirection struct DrawSystem { - mixin ECS.System!1; + mixin ECS.System!32; struct EntitiesData { uint length; + uint thread_id; @readonly CTexture[] textures; @readonly CLocation[] locations; @readonly CScale[] scale; + @readonly @optional CDepth[] depth; } void onUpdate(EntitiesData data) { - foreach(i; 0..data.length) - { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, 0, 0 , 0); - //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); - } + if(!data.depth) + foreach(i; 0..data.length) + { + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)data.locations[i].y, uint.max, 0, 0, 0, data.thread_id); + //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); + } + else + foreach(i; 0..data.length) + { + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 64 + data.locations[i].y), uint.max, 0, 0, 0, data.thread_id); + //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); + } + if(data.thread_id == 0)launcher.renderer.pushData(); } } diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index 8735d98..ba42cf6 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -11,8 +11,8 @@ import ecs_utils.math.vector; import bubel.ecs.block_allocator; import bubel.ecs.vector; - -import glad.gl.gl; +version(WebAssembly)import glad.gl.gles2; +else import glad.gl.gl; version = ver1; /*version(ver5)version = vv2; @@ -57,31 +57,105 @@ struct Renderer vec2 view_pos = vec2(-1,-1); vec2 view_size = vec2(1,1); - const uint batch_size = 16_384; + enum block_size = 2^^16; + enum batch_size = block_size/68;//963;//16_384; //uint[2] time_queries; struct VertexBlock { - float[] batch_vertices; + enum max_items = batch_size;//963; + byte[] batch_vertices; ushort[] batch_indices; void* memory; - uint itmes = 0; + uint items = 0; } + Mutex* get_block_mutex; + Mutex* block_stack_mutex; + VertexBlock getBlock() { VertexBlock block; + get_block_mutex.lock(); block.memory = allocator.getBlock(); - block.batch_vertices = (cast(float*)block.memory)[0 .. 1]; + get_block_mutex.unlock(); + block.batch_vertices = (cast(byte*)block.memory)[0 .. VertexBlock.max_items * 4 * 14]; + block.batch_indices = (cast(ushort*)block.memory)[VertexBlock.max_items * 4 * 7 .. VertexBlock.max_items * (4 * 7 + 6)]; return block; } + Vector!VertexBlock blocks; + uint current_block = 0; + uint render_blocks = 0; + + void pushBlock(VertexBlock block) + { + block_stack_mutex.lock(); + prepared_items += block.items; + blocks.add(block); + render_blocks++; + block_stack_mutex.unlock(); + } + + bool isRemainingBlocks() + { + if(render_blocks <= current_block)return false; + return true; + } + + VertexBlock fetchBlock() + { + block_stack_mutex.lock(); + VertexBlock block = blocks[current_block]; + current_block++; + block_stack_mutex.unlock(); + return block; + } + + void freeBlocks() + { + block_stack_mutex.lock(); + render_blocks = 0; + current_block = 0; + foreach(VertexBlock block; blocks) + { + allocator.freeBlock(block.memory); + } + blocks.clear; + prepared_items=0; + draw_list.clear(); + block_stack_mutex.unlock(); + } + + void pushData() + { + //if(!isRemainingBlocks())return; + while(isRemainingBlocks()) + { + VertexBlock block = fetchBlock(); + uint items = block.items; + if(items + item_id >= MaxObjects)items = MaxObjects - item_id; + batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr); + batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); + draw_list.add(DrawCall(item_id,items)); + item_id += items; + } + } + + void pushThreadsBlocks() + { + foreach(i, ref Thread thread; threads) + { + pushBlock(thread.block); + thread.block = getBlock(); + } + } struct Thread { - - Vector!VertexBlock block; + //Vector!VertexBlock block; RenderData[] render_list; + VertexBlock block; } Thread[] threads; @@ -102,7 +176,7 @@ struct Renderer Buffer[2] batch_vbo; Buffer[2] batch_ibo; - float[] batch_vertices; + ubyte[] batch_vertices; ushort[] batch_indices; Buffer indirect_buffer; @@ -121,8 +195,17 @@ struct Renderer uint mesh_id; } + struct DrawCall + { + uint start; + uint count; + } + + Vector!DrawCall draw_list; + RenderData[] render_list; uint item_id; + uint prepared_items; uint[] multi_count; uint[] multi_offset; @@ -140,6 +223,18 @@ struct Renderer { //this.technique = __ecs_used_technique; __initialize(this); + + get_block_mutex = Mallocator.make!Mutex(); + block_stack_mutex = Mallocator.make!Mutex(); + get_block_mutex.initialize(); + block_stack_mutex.initialize(); + + + threads = Mallocator.makeArray!Thread(12); + foreach(ref Thread thread;threads) + { + thread.block = getBlock(); + } } private static void __initialize_gl(ref Renderer this_) @@ -172,16 +267,16 @@ struct Renderer case Technique.vbo_batch: batch_vbo[0].create(); batch_ibo[0].create(); - batch_vbo[0].bufferData(Buffer.BindTarget.array,16,4*MaxObjects,BufferUsage,null); + batch_vbo[0].bufferData(Buffer.BindTarget.array,14,4*MaxObjects,BufferUsage,null); batch_ibo[0].bufferData(Buffer.BindTarget.element_array,2,6*MaxObjects,BufferUsage,null); batch_vbo[1].create(); batch_ibo[1].create(); - batch_vbo[1].bufferData(Buffer.BindTarget.array,16,4*MaxObjects,BufferUsage,null); + batch_vbo[1].bufferData(Buffer.BindTarget.array,14,4*MaxObjects,BufferUsage,null); batch_ibo[1].bufferData(Buffer.BindTarget.element_array,2,6*MaxObjects,BufferUsage,null); - batch_vertices = Mallocator.makeArray!float(16*MaxObjects); - batch_indices = Mallocator.makeArray!ushort(6*MaxObjects); + //batch_vertices = Mallocator.makeArray!ubyte(14*4*MaxObjects); + //batch_indices = Mallocator.makeArray!ushort(6*MaxObjects); break; case Technique.instanced_attrib_divisor: goto case(Technique.uniform_buffer_indexed); @@ -285,7 +380,7 @@ struct Renderer SDL_Log("Uniform block max size: %u",block_max_size); SDL_Log("Data offset: %u",data_offset); - allocator = BlockAllocator(1245184, 32); + allocator = BlockAllocator(block_size, 32); } } @@ -296,7 +391,7 @@ struct Renderer void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0) { - if(item_id >= MaxObjects)return; + if(prepared_items >= MaxObjects)return; __draw(this,tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id); } @@ -364,12 +459,14 @@ struct Renderer data_index += data_offset; item_id++; + prepared_items++; } } private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0) { import ecs_utils.gfx.config; + short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)]; //import core.stdc.string; with(this_) { @@ -389,16 +486,37 @@ struct Renderer memcpy(ptr+16,pos.data.ptr,8); memcpy(ptr+32,coords.data.ptr,16);*/ + short[] verts = cast(short[])threads[thread_id].block.batch_vertices; + uint item_id = threads[thread_id].block.items; + if(angle == 0) { - batch_vertices[item_id*16] = GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x; - batch_vertices[item_id*16+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y; - batch_vertices[item_id*16+4] = GfxConfig.meshes[mesh_id].vertices[4] * size.x + pos.x; - batch_vertices[item_id*16+5] = GfxConfig.meshes[mesh_id].vertices[5] * size.y + pos.y; - batch_vertices[item_id*16+8] = GfxConfig.meshes[mesh_id].vertices[8] * size.x + pos.x; - batch_vertices[item_id*16+9] = GfxConfig.meshes[mesh_id].vertices[9] * size.y + pos.y; - batch_vertices[item_id*16+12] = GfxConfig.meshes[mesh_id].vertices[12] * size.x + pos.x; - batch_vertices[item_id*16+13] = GfxConfig.meshes[mesh_id].vertices[13] * size.y + pos.y; + verts[item_id*28] = cast(short)((GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x) * 8191); + verts[item_id*28+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191); + verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); + verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+4,mem.ptr,6); + + + verts[item_id*28+7] = cast(short)((GfxConfig.meshes[mesh_id].vertices[4] * size.x + pos.x) * 8191); + verts[item_id*28+8] = cast(short)((GfxConfig.meshes[mesh_id].vertices[5] * size.y + pos.y) * 8191); + verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); + verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+11,mem.ptr,6); + + + verts[item_id*28+14] = cast(short)((GfxConfig.meshes[mesh_id].vertices[8] * size.x + pos.x) * 8191); + verts[item_id*28+15] = cast(short)((GfxConfig.meshes[mesh_id].vertices[9] * size.y + pos.y) * 8191); + verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); + verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+18,mem.ptr,6); + + + verts[item_id*28+21] = cast(short)((GfxConfig.meshes[mesh_id].vertices[12] * size.x + pos.x) * 8191); + verts[item_id*28+22] = cast(short)((GfxConfig.meshes[mesh_id].vertices[13] * size.y + pos.y) * 8191); + verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); + verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+25,mem.ptr,6); } else { @@ -406,50 +524,72 @@ struct Renderer float sinn = sinf(angle); float coss = cosf(angle); - /*batch_vertices[item_id*16] = GfxConfig.meshes[mesh_id].vertices[0] * size.x; - batch_vertices[item_id*16+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y; - batch_vertices[item_id*16+4] = GfxConfig.meshes[mesh_id].vertices[4] * size.x; - batch_vertices[item_id*16+5] = GfxConfig.meshes[mesh_id].vertices[5] * size.y; - batch_vertices[item_id*16+8] = GfxConfig.meshes[mesh_id].vertices[8] * size.x; - batch_vertices[item_id*16+9] = GfxConfig.meshes[mesh_id].vertices[9] * size.y; - batch_vertices[item_id*16+12] = GfxConfig.meshes[mesh_id].vertices[12] * size.x; - batch_vertices[item_id*16+13] = GfxConfig.meshes[mesh_id].vertices[13] * size.y;*/ + /*batch_vertices[item_id*28] = GfxConfig.meshes[mesh_id].vertices[0] * size.x; + batch_vertices[item_id*28+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y; + batch_vertices[item_id*28+4] = GfxConfig.meshes[mesh_id].vertices[4] * size.x; + batch_vertices[item_id*28+5] = GfxConfig.meshes[mesh_id].vertices[5] * size.y; + batch_vertices[item_id*28+8] = GfxConfig.meshes[mesh_id].vertices[8] * size.x; + batch_vertices[item_id*28+9] = GfxConfig.meshes[mesh_id].vertices[9] * size.y; + batch_vertices[item_id*28+12] = GfxConfig.meshes[mesh_id].vertices[12] * size.x; + batch_vertices[item_id*28+13] = GfxConfig.meshes[mesh_id].vertices[13] * size.y;*/ - batch_vertices[item_id*16] = (GfxConfig.meshes[mesh_id].vertices[0] * coss + GfxConfig.meshes[mesh_id].vertices[1] * sinn) * size.x + pos.x; - batch_vertices[item_id*16+1] = (GfxConfig.meshes[mesh_id].vertices[1] * coss - GfxConfig.meshes[mesh_id].vertices[0] * sinn) * size.y + pos.y; - batch_vertices[item_id*16+4] = (GfxConfig.meshes[mesh_id].vertices[4] * coss + GfxConfig.meshes[mesh_id].vertices[5] * sinn) * size.x + pos.x; - batch_vertices[item_id*16+5] = (GfxConfig.meshes[mesh_id].vertices[5] * coss - GfxConfig.meshes[mesh_id].vertices[4] * sinn) * size.y + pos.y; - batch_vertices[item_id*16+8] = (GfxConfig.meshes[mesh_id].vertices[8] * coss + GfxConfig.meshes[mesh_id].vertices[9] * sinn) * size.x + pos.x; - batch_vertices[item_id*16+9] = (GfxConfig.meshes[mesh_id].vertices[9] * coss - GfxConfig.meshes[mesh_id].vertices[8] * sinn) * size.y + pos.y; - batch_vertices[item_id*16+12] = (GfxConfig.meshes[mesh_id].vertices[12] * coss + GfxConfig.meshes[mesh_id].vertices[13] * sinn) * size.x + pos.x; - batch_vertices[item_id*16+13] = (GfxConfig.meshes[mesh_id].vertices[13] * coss - GfxConfig.meshes[mesh_id].vertices[12] * sinn) * size.y + pos.y; + verts[item_id*28] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[0] * coss + GfxConfig.meshes[mesh_id].vertices[1] * sinn) * size.x + pos.x) * 8191); + verts[item_id*28+1] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[1] * coss - GfxConfig.meshes[mesh_id].vertices[0] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+7] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[4] * coss + GfxConfig.meshes[mesh_id].vertices[5] * sinn) * size.x + pos.x) * 8191); + verts[item_id*28+8] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[5] * coss - GfxConfig.meshes[mesh_id].vertices[4] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+14] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[8] * coss + GfxConfig.meshes[mesh_id].vertices[9] * sinn) * size.x + pos.x) * 8191); + verts[item_id*28+15] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[9] * coss - GfxConfig.meshes[mesh_id].vertices[8] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+21] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[12] * coss + GfxConfig.meshes[mesh_id].vertices[13] * sinn) * size.x + pos.x) * 8191); + verts[item_id*28+22] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[13] * coss - GfxConfig.meshes[mesh_id].vertices[12] * sinn) * size.y + pos.y) * 8191); } - batch_vertices[item_id*16+2] = GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x; - batch_vertices[item_id*16+3] = GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y; - batch_vertices[item_id*16+6] = GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x; - batch_vertices[item_id*16+7] = GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y; - batch_vertices[item_id*16+10] = GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x; - batch_vertices[item_id*16+11] = GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y; - batch_vertices[item_id*16+14] = GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x; - batch_vertices[item_id*16+15] = GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y; + /*verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); + verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); + verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); + verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); + verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); + verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); + verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); + verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767);*/ - uint ind_id = item_id % batch_size; + /*verts[item_id*28+4] = depth; + verts[item_id*28+11] = depth; + verts[item_id*28+18] = depth; + verts[item_id*28+25] = depth; - batch_indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id*4); - batch_indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id*4); - batch_indices[item_id*6+2] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[2] + ind_id*4); - batch_indices[item_id*6+3] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[3] + ind_id*4); - batch_indices[item_id*6+4] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[4] + ind_id*4); - batch_indices[item_id*6+5] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[5] + ind_id*4); + *cast(uint*)&verts[item_id*28+5] = color; + *cast(uint*)&verts[item_id*28+12] = color; + *cast(uint*)&verts[item_id*28+19] = color; + *cast(uint*)&verts[item_id*28+26] = color; + + memcpy(verts.ptr+item_id*28+4,mem.ptr,6); + memcpy(verts.ptr+item_id*28+11,mem.ptr,6); + memcpy(verts.ptr+item_id*28+18,mem.ptr,6); + memcpy(verts.ptr+item_id*28+25,mem.ptr,6);*/ + + uint ind_id = (item_id % batch_size)*4; + + ushort[] indices = threads[thread_id].block.batch_indices; + + indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id); + indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id); + indices[item_id*6+2] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[2] + ind_id); + indices[item_id*6+3] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[3] + ind_id); + indices[item_id*6+4] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[4] + ind_id); + indices[item_id*6+5] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[5] + ind_id); //render_list[item_id] = RenderData(tex,material_id,mesh_id); - render_list[item_id].texture = tex; - render_list[item_id].material_id = material_id; - render_list[item_id].mesh_id = mesh_id; + //render_list[item_id].texture = tex; + //render_list[item_id].material_id = material_id; + //render_list[item_id].mesh_id = mesh_id; //data_index += 1;//data_offset; - item_id++; + threads[thread_id].block.items++; + if(threads[thread_id].block.items >= VertexBlock.max_items) + { + pushBlock(threads[thread_id].block); + threads[thread_id].block = getBlock(); + } } } @@ -467,9 +607,22 @@ struct Renderer { glClearColor(0,0,0,0); glViewport(0,0,this_.resolution.x,this_.resolution.y); - glClear(GL_COLOR_BUFFER_BIT);// | GL_DEPTH_BUFFER_BIT); - glDisable(GL_DEPTH_TEST); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //glDisable(GL_DEPTH_TEST); + glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); + glDepthFunc(GL_LESS); + + version(WebAssembly) + { + glDepthRangef(0,1); + } + else + { + glDepthRange(0,1); + } + //glDepthRange(0,1); + //glClearDepth(1); } void present() @@ -484,6 +637,10 @@ struct Renderer private static void __present_gl(ref Renderer this_) { + + this_.pushThreadsBlocks(); + this_.pushData(); + glViewport(0,0,this_.resolution.x,this_.resolution.y); //glEnable(GL_ALPHA_TEST); //glAlphaFunc(GL_GREATER, 0.01); @@ -505,14 +662,17 @@ struct Renderer break; case Technique.vbo_batch: //if(data_index){ - batch_vbo[0].bufferSubData(Buffer.BindTarget.array,item_id*4*16,0,batch_vertices.ptr); - batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,item_id*6*2,0,batch_indices.ptr); + //batch_vbo[0].bufferSubData(Buffer.BindTarget.array,item_id*4*14,0,batch_vertices.ptr); + //batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,item_id*6*2,0,batch_indices.ptr); batch_vbo[0].bind(Buffer.BindTarget.array); batch_ibo[0].bind(Buffer.BindTarget.element_array); - glVertexAttribPointer(0,2,GL_FLOAT,false,16,null); - glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)8);//} + //glVertexAttribPointer(0,2,GL_SHORT,true,14,null); + //glVertexAttribPointer(1,2,GL_SHORT,true,14,cast(void*)4);//} + glEnableVertexAttribArray(2); + glEnableVertexAttribArray(3); + //glVertexAttribPointer(2,1,GL_SHORT,true,14,cast(void*)6);//} break; case Technique.instanced_attrib_divisor: ubos[0].bufferSubData(Buffer.BindTarget.uniform,data_index,0,uniform_block.ptr); @@ -609,8 +769,8 @@ struct Renderer //glBeginQuery(GL_TIME_ELAPSED, time_queries[0]); if(technique == Technique.vbo_batch) { - uint items = item_id/batch_size+1; - foreach(i; 0..items) + //uint items = item_id/batch_size+1; + foreach(i; 0..draw_list.length) { if(material_id != render_list[i].material_id) { @@ -625,16 +785,20 @@ struct Renderer render_list[i].texture.bind(); } - uint instance_count = batch_size; + /*uint instance_count = batch_size; if((i+1)*batch_size > item_id) { instance_count = item_id%batch_size; - } + }*/ - glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16)); - glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16+8)); + // glVertexAttribPointer(0,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16)); + // glVertexAttribPointer(1,2,GL_FLOAT,false,16,cast(void*)(i*batch_size*4*16+8)); + glVertexAttribPointer(0,2,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14)); + glVertexAttribPointer(1,2,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14+4)); + glVertexAttribPointer(2,1,GL_SHORT,true,14,cast(void*)(draw_list[i].start*4*14+8)); + glVertexAttribPointer(3,4,GL_UNSIGNED_BYTE,true,14,cast(void*)(draw_list[i].start*4*14+10)); - glDrawElements(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*batch_size*6*2)); + glDrawElements(GL_TRIANGLES,draw_list[i].count*6,GL_UNSIGNED_SHORT,cast(void*)(draw_list[i].start*6*2)); //glDrawElementsBaseVertex(GL_TRIANGLES,instance_count*6,GL_UNSIGNED_SHORT,cast(void*)(i*16_384*6*2),i*16_384*4); } @@ -817,6 +981,9 @@ struct Renderer } glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(3); + this_.freeBlocks(); /*glUseProgram(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/ From b19fbb15288555ea94db39ea4e9504e933a8011f Mon Sep 17 00:00:00 2001 From: Mergul Date: Tue, 12 May 2020 12:30:21 +0200 Subject: [PATCH 11/58] Fixed shader compilation on WebAssembly --- demos/assets/shaders/base.vp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demos/assets/shaders/base.vp b/demos/assets/shaders/base.vp index 7be086b..2777a24 100644 --- a/demos/assets/shaders/base.vp +++ b/demos/assets/shaders/base.vp @@ -92,10 +92,10 @@ LOC(1) ATT vec2 tex_coords; void main() { #ifdef VBO_BATCH - vec3 position = vec3(positions*4,1.0); + vec3 position = vec3(positions*4.0,1.0); uv = tex_coords; #else - vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1) * vec3(positions,1.0); + vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0); uv = tex_coords * uv_transform.zw + uv_transform.xy; #endif From 5e884352ba05c0bcbe2bf1db8429f5e9c11d247d Mon Sep 17 00:00:00 2001 From: Mergul Date: Tue, 12 May 2020 17:28:31 +0200 Subject: [PATCH 12/58] Add support for external depencencies --- source/bubel/ecs/core.d | 16 +++ source/bubel/ecs/manager.d | 143 ++++++++++++++++++- source/bubel/ecs/system.d | 3 + source/bubel/ecs/vector.d | 8 +- tests/basic.d | 275 +++++++++++++++++++++++++++++++++++++ 5 files changed, 440 insertions(+), 5 deletions(-) diff --git a/source/bubel/ecs/core.d b/source/bubel/ecs/core.d index ccdf3e2..0487665 100644 --- a/source/bubel/ecs/core.d +++ b/source/bubel/ecs/core.d @@ -92,4 +92,20 @@ static struct ECS { alias ExcludedComponents = T; } + + /************************************************************************************************************************ + Make list of readonly ependencies. This template get strings as arguments. Should be added inside System structure. + */ + mixin template ReadOnlyDependencies(T...) + { + alias ReadOnlyDependencies = T; + } + + /************************************************************************************************************************ + Make list of writable ependencies. This template get strings as arguments. Should be added inside System structure. + */ + mixin template WritableDependencies(T...) + { + alias WritableDependencies = T; + } } \ No newline at end of file diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 1b896db..c1eb62a 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -452,6 +452,8 @@ export struct EntityManager uint excluded = 1; uint optional = 1; uint req = 1; + uint readonly_dep = 1; + uint writable_dep = 1; } static ComponentsCounts getComponentsCounts()() @@ -532,7 +534,22 @@ export struct EntityManager { components_counts.excluded++; } + } + } + static if (__traits(hasMember, Sys, "ReadOnlyDependencies")) + { + foreach (str; Sys.ReadOnlyDependencies) + { + components_counts.readonly_dep++; + } + } + + static if (__traits(hasMember, Sys, "WritableDependencies")) + { + foreach (str; Sys.WritableDependencies) + { + components_counts.writable_dep++; } } @@ -568,6 +585,16 @@ export struct EntityManager return m_req[0 .. m_req_counter]; } + CompInfo[] readonlyDeps() + { + return m_readonly_dep[0 .. m_readonly_dep_counter]; + } + + CompInfo[] writableDeps() + { + return m_writable_dep[0 .. m_writable_dep_counter]; + } + void addReadonly(CompInfo info) { m_readonly[m_readonly_counter++] = info; @@ -593,17 +620,31 @@ export struct EntityManager m_req[m_req_counter++] = info; } + void addReadonlyDep(CompInfo info) + { + m_readonly_dep[m_readonly_dep_counter++] = info; + } + + void addWritableDep(CompInfo info) + { + m_writable_dep[m_writable_dep_counter++] = info; + } + CompInfo[counts.readonly] m_readonly; CompInfo[counts.mutable] m_mutable; CompInfo[counts.excluded] m_excluded; CompInfo[counts.optional] m_optional; CompInfo[counts.req] m_req; + CompInfo[counts.readonly_dep] m_readonly_dep; + CompInfo[counts.writable_dep] m_writable_dep; uint m_readonly_counter; uint m_mutable_counter; uint m_excluded_counter; uint m_optional_counter; uint m_req_counter; + uint m_readonly_dep_counter; + uint m_writable_dep_counter; string entites_array; } @@ -616,6 +657,8 @@ export struct EntityManager size_t excluded = components_info.excluded.length; size_t read_only = components_info.readonly.length; size_t modified = components_info.mutable.length; + size_t read_only_deps = components_info.readonlyDeps.length; + size_t writable_deps = components_info.writableDeps.length; if (req > 0) system.m_components = Mallocator.makeArray!ushort(req); @@ -627,6 +670,10 @@ export struct EntityManager system.m_read_only_components = Mallocator.makeArray!ushort(read_only); if (modified > 0) system.m_modified_components = Mallocator.makeArray!ushort(modified); + if (read_only_deps > 0) + system.m_readonly_dependencies = Mallocator.makeArray!ushort(read_only_deps); + if (writable_deps > 0) + system.m_writable_dependencies = Mallocator.makeArray!ushort(writable_deps); } @@ -714,6 +761,22 @@ export struct EntityManager } } + static if (__traits(hasMember, Sys, "ReadOnlyDependencies")) + { + foreach (str; Sys.ReadOnlyDependencies) + { + components_info.addReadonlyDep(CompInfo(str, str)); + } + } + + static if (__traits(hasMember, Sys, "WritableDependencies")) + { + foreach (str; Sys.WritableDependencies) + { + components_info.addWritableDep(CompInfo(str, str)); + } + } + return components_info; } @@ -809,7 +872,6 @@ export struct EntityManager ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); system.m_modified_components[iii] = comp; } - } static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info, @@ -1059,6 +1121,32 @@ export struct EntityManager genCompList(system, components_map); + foreach (iii, comp_info; components_info.readonlyDeps) + { + ushort comp = external_dependencies_map.get(cast(const (char)[]) comp_info.type, ushort.max); + version (D_BetterC) + assert(comp != ushort.max, + "Can't register system \"" ~ Sys.stringof + ~ "\" due to non existing dependency."); + else + assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + ~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\"."); + system.m_readonly_dependencies[iii] = comp; + } + + foreach (iii, comp_info; components_info.writableDeps) + { + ushort comp = external_dependencies_map.get(cast(char[]) comp_info.type, ushort.max); + version (D_BetterC) + assert(comp != ushort.max, + "Can't register system \"" ~ Sys.stringof + ~ "\" due to non existing dependency."); + else + assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + ~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\"."); + system.m_writable_dependencies[iii] = comp; + } + ushort sys_id = systems_map.get(cast(char[]) Sys.stringof, ushort.max); if (sys_id < systems.length) { @@ -1118,6 +1206,11 @@ export struct EntityManager return cast(ushort)(passes.length - 1); } + export void registerDependency(const(char)[] name) + { + return external_dependencies_map.add(name, cast(ushort)external_dependencies_map.length); + } + /************************************************************************************************************************ Register component into EntityManager. */ @@ -2820,10 +2913,45 @@ export struct EntityManager foreach (caller; pass.system_callers) { index = 0; + ///gets systems which are excluding each other out_for: foreach (caller2; pass.system_callers) { if (caller is caller2) continue; + + ///check for external dependencies + foreach (cmp; caller.system.m_readonly_dependencies) + { + foreach (cmp2; caller2.system.m_writable_dependencies) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + } + foreach (cmp; caller.system.m_writable_dependencies) + { + foreach (cmp2; caller2.system.m_readonly_dependencies) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + foreach (cmp2; caller2.system.m_writable_dependencies) + { + if (cmp == cmp2) + { + exclusion[index++] = caller2; + continue out_for; + } + } + } + + ///check for component dependencies foreach (cmp; caller.system.m_read_only_components) { foreach (cmp2; caller2.system.m_modified_components) @@ -2923,6 +3051,18 @@ export struct EntityManager } } + const (UpdatePass)* getPass(const (char)[] name) + { + ushort id = getPassID(name); + if(id == ushort.max)return null; + return passes[id]; + } + + ushort getPassID(const (char)[] name) + { + return passes_map.get(name, ushort.max); + } + /************************************************************************************************************************ Component info; */ @@ -3350,6 +3490,7 @@ export struct EntityManager HashMap!(char[], ushort) components_map; HashMap!(const(char)[], ushort) events_map; HashMap!(const(char)[], ushort) passes_map; + HashMap!(const(char)[], ushort) external_dependencies_map; Vector!System systems; Vector!ComponentInfo components; Vector!EventInfo events; diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index 7343831..5bf750b 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -129,6 +129,9 @@ package: ushort[] m_read_only_components; ushort[] m_modified_components; + ushort[] m_readonly_dependencies; + ushort[] m_writable_dependencies; + EntityManager.SystemCaller* m_any_system_caller; EventCaller[] m_event_callers; diff --git a/source/bubel/ecs/vector.d b/source/bubel/ecs/vector.d index 3334be2..413bbce 100644 --- a/source/bubel/ecs/vector.d +++ b/source/bubel/ecs/vector.d @@ -62,11 +62,11 @@ public: used = 0; } - export bool empty() { + export bool empty() const { return (used == 0); } - export size_t length() { + export size_t length() const { return used; } @@ -197,9 +197,9 @@ public: assert(ok, "There is no such an element in vector"); } - export ref T opIndex(size_t elemNum) { + export ref T opIndex(size_t elemNum) const { //debug assert(elemNum < used, "Range violation [index]"); - return array.ptr[elemNum]; + return *cast(T*)&array.ptr[elemNum]; } export auto opSlice() { diff --git a/tests/basic.d b/tests/basic.d index 653575f..10d79b8 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -1220,4 +1220,279 @@ unittest assert(*entity2.getComponent!CInt == 13); gEM.end(); +} + +@("SystemDependencies") +unittest +{ + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem2 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem3 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem4 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + CInt[] int_; + CLong[] long_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem5 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @readonly CLong[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + void func1(TestSystem.EntitiesData entities) + { + foreach(i;0 .. entities.length) + { + entities.int_[i] += entities.int_[i] / 2; + } + } + + void func2(TestSystem.EntitiesData entities) + { + foreach(i;0 .. entities.length) + { + entities.int_[i] += 8; + } + } + + gEM.beginRegister(); + + gEM.registerSystem!TestSystem(0); + gEM.registerSystem!TestSystem2(1); + gEM.registerSystem!TestSystem3(2); + gEM.registerSystem!TestSystem4(3); + gEM.registerSystem!TestSystem5(4); + + gEM.endRegister(); + + const (EntityManager.UpdatePass)* pass = gEM.getPass("update"); + assert(pass != null); + assert(pass.system_callers.length == 5); + assert(pass.system_callers[0].system_id == TestSystem.system_id); + assert(pass.system_callers[1].system_id == TestSystem2.system_id); + assert(pass.system_callers[2].system_id == TestSystem3.system_id); + assert(pass.system_callers[3].system_id == TestSystem4.system_id); + assert(pass.system_callers[4].system_id == TestSystem5.system_id); + assert(pass.system_callers[0].dependencies.length == 0); + assert(pass.system_callers[1].dependencies.length == 1); + assert(pass.system_callers[2].dependencies.length == 1); + assert(pass.system_callers[3].dependencies.length == 3); + assert(pass.system_callers[4].dependencies.length == 1); + assert(pass.system_callers[1].dependencies[0].system_id == TestSystem.system_id); + assert(pass.system_callers[2].dependencies[0].system_id == TestSystem2.system_id); + assert(pass.system_callers[3].dependencies[0].system_id == TestSystem.system_id); + assert(pass.system_callers[3].dependencies[1].system_id == TestSystem2.system_id); + assert(pass.system_callers[3].dependencies[2].system_id == TestSystem3.system_id); + assert(pass.system_callers[4].dependencies[0].system_id == TestSystem4.system_id); +} + +@("ExternalSystemDependencies") +unittest +{ + enum TestDependency = "TestDepencency"; + + struct TestSystem + { + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem2 + { + mixin ECS.System; + + mixin ECS.WritableDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem3 + { + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(TestDependency); + + struct EntitiesData + { + uint thread_id; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem4 + { + mixin ECS.System; + + mixin ECS.WritableDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CInt[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + struct TestSystem5 + { + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(TestDependency); + + struct EntitiesData + { + uint length; + @readonly CLong[] int_; + } + + void onUpdate(EntitiesData entities) + { + + } + } + + void func1(TestSystem.EntitiesData entities) + { + foreach(i;0 .. entities.length) + { + entities.int_[i] += entities.int_[i] / 2; + } + } + + void func2(TestSystem.EntitiesData entities) + { + foreach(i;0 .. entities.length) + { + entities.int_[i] += 8; + } + } + + gEM.beginRegister(); + + gEM.registerDependency(TestDependency); + + gEM.registerSystem!TestSystem(0); + gEM.registerSystem!TestSystem2(1); + gEM.registerSystem!TestSystem3(2); + gEM.registerSystem!TestSystem4(3); + gEM.registerSystem!TestSystem5(4); + + gEM.endRegister(); + + const (EntityManager.UpdatePass)* pass = gEM.getPass("update"); + assert(pass != null); + assert(pass.system_callers.length == 5); + assert(pass.system_callers[0].system_id == TestSystem.system_id); + assert(pass.system_callers[1].system_id == TestSystem2.system_id); + assert(pass.system_callers[2].system_id == TestSystem3.system_id); + assert(pass.system_callers[3].system_id == TestSystem4.system_id); + assert(pass.system_callers[4].system_id == TestSystem5.system_id); + assert(pass.system_callers[0].dependencies.length == 0); + assert(pass.system_callers[1].dependencies.length == 1); + assert(pass.system_callers[2].dependencies.length == 1); + assert(pass.system_callers[3].dependencies.length == 3); + assert(pass.system_callers[4].dependencies.length == 2); + assert(pass.system_callers[1].dependencies[0].system_id == TestSystem.system_id); + assert(pass.system_callers[2].dependencies[0].system_id == TestSystem2.system_id); + assert(pass.system_callers[3].dependencies[0].system_id == TestSystem.system_id); + assert(pass.system_callers[3].dependencies[1].system_id == TestSystem2.system_id); + assert(pass.system_callers[3].dependencies[2].system_id == TestSystem3.system_id); + assert(pass.system_callers[4].dependencies[0].system_id == TestSystem2.system_id); + assert(pass.system_callers[4].dependencies[1].system_id == TestSystem4.system_id); } \ No newline at end of file From 1b925b7ab190be050012262d2dffcd03188b662a Mon Sep 17 00:00:00 2001 From: Mergul Date: Tue, 12 May 2020 17:30:57 +0200 Subject: [PATCH 13/58] Change component name from "modified" to "writable" --- source/bubel/ecs/manager.d | 18 +++++++++--------- source/bubel/ecs/system.d | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index c1eb62a..15d1f6e 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -104,8 +104,8 @@ export struct EntityManager Mallocator.dispose(system.jobs); if (system.m_read_only_components) Mallocator.dispose(system.m_read_only_components); - if (system.m_modified_components) - Mallocator.dispose(system.m_modified_components); + if (system.m_writable_components) + Mallocator.dispose(system.m_writable_components); if (system.m_components) Mallocator.dispose(system.m_components); if (system.m_excluded_components) @@ -656,7 +656,7 @@ export struct EntityManager size_t opt = components_info.optional.length; size_t excluded = components_info.excluded.length; size_t read_only = components_info.readonly.length; - size_t modified = components_info.mutable.length; + size_t writable = components_info.mutable.length; size_t read_only_deps = components_info.readonlyDeps.length; size_t writable_deps = components_info.writableDeps.length; @@ -668,8 +668,8 @@ export struct EntityManager system.m_excluded_components = Mallocator.makeArray!ushort(excluded); if (read_only > 0) system.m_read_only_components = Mallocator.makeArray!ushort(read_only); - if (modified > 0) - system.m_modified_components = Mallocator.makeArray!ushort(modified); + if (writable > 0) + system.m_writable_components = Mallocator.makeArray!ushort(writable); if (read_only_deps > 0) system.m_readonly_dependencies = Mallocator.makeArray!ushort(read_only_deps); if (writable_deps > 0) @@ -870,7 +870,7 @@ export struct EntityManager else assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); - system.m_modified_components[iii] = comp; + system.m_writable_components[iii] = comp; } } @@ -2954,7 +2954,7 @@ export struct EntityManager ///check for component dependencies foreach (cmp; caller.system.m_read_only_components) { - foreach (cmp2; caller2.system.m_modified_components) + foreach (cmp2; caller2.system.m_writable_components) { if (cmp == cmp2) { @@ -2963,7 +2963,7 @@ export struct EntityManager } } } - foreach (cmp; caller.system.m_modified_components) + foreach (cmp; caller.system.m_writable_components) { foreach (cmp2; caller2.system.m_read_only_components) { @@ -2973,7 +2973,7 @@ export struct EntityManager continue out_for; } } - foreach (cmp2; caller2.system.m_modified_components) + foreach (cmp2; caller2.system.m_writable_components) { if (cmp == cmp2) { diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index 5bf750b..7bcaf01 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -127,7 +127,7 @@ package: //System*[] m_dependencies; ushort[] m_read_only_components; - ushort[] m_modified_components; + ushort[] m_writable_components; ushort[] m_readonly_dependencies; ushort[] m_writable_dependencies; From 9580ee9af9fd40b32651488e3882843f306fff7e Mon Sep 17 00:00:00 2001 From: Mergul Date: Tue, 12 May 2020 18:21:25 +0200 Subject: [PATCH 14/58] Add bullets collision system to SpaceInvaders demo --- demos/source/demos/space_invaders.d | 252 ++++++++++++++++++++++++++-- 1 file changed, 236 insertions(+), 16 deletions(-) diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 30891c8..004a3eb 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -16,10 +16,14 @@ import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; +import std.array : staticArray; + enum float px = 1.0/512.0; extern(C): +enum ShootGridDependency = "ShootGridDependency"; + /*####################################################################################################################### ------------------------------------------------ Types ------------------------------------------------------------------ #######################################################################################################################*/ @@ -33,11 +37,18 @@ struct SpaceInvaders EntityTemplate* laser_tmpl; Texture texture; + ShootGrid* shoot_grid; + bool move_system = true; bool draw_system = true; const vec2 map_size = vec2(400,300); const float cell_size = 60; + + ~this() @nogc nothrow + { + if(shoot_grid)Mallocator.dispose(shoot_grid); + } } struct SceneGrid @@ -147,7 +158,7 @@ struct CGuild { mixin ECS.Component; - int guild; + byte guild; } struct CLaser @@ -188,6 +199,11 @@ struct CDepth short depth; } +struct CShootGrid +{ + mixin ECS.Component; +} + /*####################################################################################################################### ------------------------------------------------ Events ------------------------------------------------------------------ #######################################################################################################################*/ @@ -208,6 +224,158 @@ struct EChangeDirection ------------------------------------------------ Systems ------------------------------------------------------------------ #######################################################################################################################*/ +struct ShootGrid +{ + + ~this() @nogc nothrow + { + if(nodes)Mallocator.dispose(nodes); + if(masks)Mallocator.dispose(masks); + } + + struct Node + { + alias entity this; + + EntityID entity; + } + + void create(ivec2 nodes_count, vec2 node_size) + { + this.size = nodes_count; + this.node_size = node_size; + inv_node_size = vec2(1.0/node_size.x, 1.0/node_size.y); + nodes = Mallocator.makeArray!Node(nodes_count.x * nodes_count.y); + masks = Mallocator.makeArray!ubyte(nodes.length); + } + + void mark(EntityID id, vec2 beg, vec2 end, byte mask) + { + ivec2 ibeg = cast(ivec2)(beg * inv_node_size); + ivec2 iend = cast(ivec2)((end * inv_node_size) + 0.5); + if(ibeg.x < 0)ibeg.x = 0; + if(ibeg.y < 0)ibeg.y = 0; + if(iend.x > size.x)iend.x = size.x; + if(iend.y > size.y)iend.y = size.y; + foreach(i; ibeg.y .. iend.y) + { + foreach(j; ibeg.x .. iend.x) + { + nodes[i * size.x + j] = id; + masks[i * size.x +j] = mask; + } + } + } + + void clear() + { + size_t size = nodes.length * EntityID.sizeof; + memset(nodes.ptr, 0, size); + memset(masks.ptr, 0, masks.length); + } + + bool test(out EntityID id, vec2 beg, vec2 end) + { + ivec2 ibeg = cast(ivec2)(beg * inv_node_size); + ivec2 iend = cast(ivec2)((end * inv_node_size) + 0.5); + if(ibeg.x < 0)ibeg.x = 0; + if(ibeg.y < 0)ibeg.y = 0; + if(iend.x > size.x)iend.x = size.x; + if(iend.y > size.y)iend.y = size.y; + foreach(i; ibeg.y .. iend.y) + { + foreach(j; ibeg.x .. iend.x) + { + if(nodes[i * size.x + j].id != 0) + { + id = nodes[i * size.x + j]; + return true; + } + } + } + return false; + } + + bool test(out EntityID id, vec2 pos, ubyte mask) + { + ivec2 ipos = cast(ivec2)(pos * inv_node_size - 0.5); + if(ipos.x < 0)ipos.x = 0; + if(ipos.y < 0)ipos.y = 0; + if(ipos.x >= size.x)ipos.x = size.x - 1; + if(ipos.y >= size.y)ipos.y = size.y - 1; + size_t index = ipos.y * size.x + ipos.x; + if((masks[index] & mask) == 0)return false; + if(nodes[index].id != 0) + { + id = nodes[index]; + return true; + } + return false; + } + + vec2 inv_node_size; + ivec2 size; + vec2 node_size; + Node[] nodes; + ubyte[] masks; +} + +struct ShootGridCleaner +{ + mixin ECS.System!1; + + struct EntitiesData + { + + } + + void onUpdate(EntitiesData data) + { + if(space_invaders.shoot_grid)space_invaders.shoot_grid.clear(); + } +} + +struct ShootGridManager +{ + mixin ECS.System!32; + + mixin ECS.WritableDependencies!(ShootGridDependency); + + struct EntitiesData + { + uint length; + uint thread_id; + const (Entity)[] entity; + @readonly CLocation[] locations; + @readonly CScale[] scale; + @readonly CShootGrid[] grid_flag; + @readonly CGuild[] guild; + } + + ShootGrid* grid; + + void onCreate() + { + grid = space_invaders.shoot_grid; + } + + bool onBegin() + { + if(!grid)return false; + //grid.clear(); + return true; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + vec2 half_scale = data.scale[i] * 0.5; + grid.mark(data.entity[i].id, data.locations[i] - half_scale, data.locations[i] + half_scale, cast(ubyte)(1 << data.guild[i].guild)); + } + } +} + struct DrawSystem { mixin ECS.System!32; @@ -260,10 +428,11 @@ struct LaserShootingSystem mixin ECS.System!32; bool shoot = false; - float[10] laser_shoot_times = [2000,1500,1000,700,500,300,100,50,10,1]; + static float[10] laser_shoot_times = [2000,1500,1000,700,500,300,100,50,10,1]; CLocation* laser_location; CVelocity* laser_velocity; + CGuild* laser_guild; struct EntitiesData { @@ -272,6 +441,7 @@ struct LaserShootingSystem @readonly CShootDirection[] shoot_direction; @readonly @optional CAutoShoot[] auto_shoot; @readonly CLocation[] location; + @readonly CGuild[] guild; CLaserWeapon[] laser; } @@ -285,6 +455,7 @@ struct LaserShootingSystem { laser_location = space_invaders.laser_tmpl.getComponent!CLocation; laser_velocity = space_invaders.laser_tmpl.getComponent!CVelocity; + laser_guild = space_invaders.laser_tmpl.getComponent!CGuild; if(launcher.getKeyState(SDL_SCANCODE_SPACE)) { shoot = true; @@ -307,6 +478,7 @@ struct LaserShootingSystem laser.shoot_time -= laser_shoot_times[laser.level - 1]; laser_location.value = data.location[i]; laser_velocity.value = vec2(randomf()*0.5-0.25,data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); + laser_guild.guild = data.guild[i].guild; launcher.manager.addEntity(space_invaders.laser_tmpl); } } @@ -324,6 +496,36 @@ struct LaserShootingSystem } } +struct LaserCollisionSystem +{ + mixin ECS.System!32; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + @readonly CLocation[] location; + @readonly CLaser[] laser; + @readonly CGuild[] guild; + } + + void onUpdate(EntitiesData data) + { + EntityID id; + foreach(i; 0..data.length) + { + if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(~(1 << data.guild[i].guild)))) + { + launcher.manager.removeEntity(data.entity[i].id); + } + } + } + +} + struct ChangeDirectionSystem { mixin ECS.System!32; @@ -591,6 +793,8 @@ struct MovementSystem } } +import core.stdc.math; + /** *System is responsible for movement of objects with CInput component. *In this example every entity has same speed when using movement system. @@ -620,22 +824,24 @@ struct InputMovementSystem move_vector = vec2(0,0); if(launcher.getKeyState(SDL_SCANCODE_W)) { - move_vector = vec2(0,1); - return true; + move_vector += vec2(0,1); } else if(launcher.getKeyState(SDL_SCANCODE_S)) { - move_vector = vec2(0,-1); - return true; + move_vector += vec2(0,-1); } - else if(launcher.getKeyState(SDL_SCANCODE_A)) + if(launcher.getKeyState(SDL_SCANCODE_A)) { - move_vector = vec2(-1,0); - return true; + move_vector += vec2(-1,0); } else if(launcher.getKeyState(SDL_SCANCODE_D)) { - move_vector = vec2(1,0); + move_vector += vec2(1,0); + } + + if(move_vector.x != 0 ||move_vector.y != 0) + { + move_vector = move_vector / sqrtf(move_vector.x * move_vector.x + move_vector.y * move_vector.y); return true; } //don't call system update because no key pressed @@ -682,6 +888,9 @@ void spaceInvadersStart() space_invaders.texture.create(); space_invaders.texture.load("assets/textures/atlas.png"); + space_invaders.shoot_grid = Mallocator.make!ShootGrid; + space_invaders.shoot_grid.create(ivec2(80,60), vec2(5,5)); + launcher.manager.beginRegister(); launcher.manager.registerComponent!CLocation; @@ -696,16 +905,22 @@ void spaceInvadersStart() launcher.manager.registerComponent!CVelocity; launcher.manager.registerComponent!CLaser; launcher.manager.registerComponent!CSideMove; + launcher.manager.registerComponent!CDepth; + launcher.manager.registerComponent!CShootGrid; + launcher.manager.registerComponent!CGuild; launcher.manager.registerEvent!EChangeDirection; //launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); launcher.manager.registerSystem!InputMovementSystem(-100); + launcher.manager.registerSystem!MovementSystem(-99); + launcher.manager.registerSystem!ClampPositionSystem(-90); launcher.manager.registerSystem!LaserShootingSystem(0); - launcher.manager.registerSystem!MovementSystem(0); - launcher.manager.registerSystem!ClampPositionSystem(1); launcher.manager.registerSystem!ChangeDirectionSystem(0); + launcher.manager.registerSystem!LaserCollisionSystem(-70); + launcher.manager.registerSystem!ShootGridManager(-80); + launcher.manager.registerSystem!ShootGridCleaner(-101); launcher.manager.endRegister(); @@ -718,7 +933,7 @@ void spaceInvadersStart() //launcher.manager.getSystem(CleanSystem.system_id).disable(); { - ushort[7] components = [CLocation.component_id, CTexture.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CLaserWeapon.component_id, CShootDirection.component_id]; + ushort[9] components = [CLocation.component_id, CTexture.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CLaserWeapon.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; space_invaders.ship_tmpl = launcher.manager.allocateTemplate(components); CScale* scale_comp = space_invaders.ship_tmpl.getComponent!CScale; @@ -735,7 +950,7 @@ void spaceInvadersStart() } { - ushort[5] components = [CLocation.component_id, CTexture.component_id, CVelocity.component_id, CScale.component_id, CLaser.component_id]; + ushort[6] components = [CLocation.component_id, CTexture.component_id, CVelocity.component_id, CScale.component_id, CLaser.component_id, CGuild.component_id]; space_invaders.laser_tmpl = launcher.manager.allocateTemplate(components); CTexture* tex_comp = space_invaders.laser_tmpl.getComponent!CTexture; @@ -753,7 +968,7 @@ void spaceInvadersStart() EntityID grouped_id; { - ushort[8] components = [CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CLaserWeapon.component_id, CEnemy.component_id, CShootDirection.component_id];//, CVelocity.component_id]; + ushort[10] components = [CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CLaserWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; space_invaders.enemy_tmpl = launcher.manager.allocateTemplate(components); CTexture* tex_comp = space_invaders.enemy_tmpl.getComponent!CTexture; @@ -765,6 +980,7 @@ void spaceInvadersStart() shoot_dir_comp.direction = Direction.down; CVelocity* vel_comp = space_invaders.enemy_tmpl.getComponent!CVelocity; vel_comp.value = vec2(0.1,0); + space_invaders.enemy_tmpl.getComponent!CGuild().guild = 1; Entity* current_entity; @@ -802,7 +1018,6 @@ void spaceInvadersStart() void spaceInvadersEnd() { - launcher.manager.getSystem(DrawSystem.system_id).disable(); launcher.manager.getSystem(InputMovementSystem.system_id).disable(); launcher.manager.getSystem(LaserShootingSystem.system_id).disable(); @@ -827,6 +1042,11 @@ void spaceInvadersTool(vec2 position, Tool tool, int size) position.y += (randomf - 0.5) * size; *location = position; } + CLaserWeapon* laser_weapon = tmpl.getComponent!CLaserWeapon; + if(laser_weapon) + { + laser_weapon.shoot_time = randomf * LaserShootingSystem.laser_shoot_times[laser_weapon.level - 1]; + } launcher.manager.addEntity(tmpl); } break; From dd491302afa388e86e7ad5b2a4a5af502a28431b Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 13 May 2020 15:31:26 +0200 Subject: [PATCH 15/58] Fixed system reregistration issue and added funtion to allocate EntityTEmplate as copy of different teamplte --- source/bubel/ecs/manager.d | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 15d1f6e..c6b02a1 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -1150,17 +1150,22 @@ export struct EntityManager ushort sys_id = systems_map.get(cast(char[]) Sys.stringof, ushort.max); if (sys_id < systems.length) { - system.enable(); + systems[sys_id].disable(); + if(systems[sys_id].m_destroy)(cast(void function(void*)) systems[sys_id].m_destroy)(systems[sys_id].m_system_pointer); if (system.m_create) (cast(void function(void*)) system.m_create)(system.m_system_pointer); + system.enable(); + system.m_id = sys_id; + system.m_name = systems[sys_id].m_name; systems[sys_id] = system; } else { system.m_name = Mallocator.makeArray(cast(char[]) Sys.stringof); + systems_map.add(system.m_name, cast(ushort) systems.length); system.m_id = cast(ushort)(systems.length); @@ -1723,6 +1728,20 @@ export struct EntityManager return temp; } + /************************************************************************************************************************ + Allocate EntityTemplate copy. + + Params: + copy_tmpl = template which should be copied + */ + export EntityTemplate* allocateTemplate(EntityTemplate* copy_tmpl) + { + EntityTemplate* tmpl = Mallocator.make!EntityTemplate; + tmpl.info = copy_tmpl.info; + tmpl.entity_data = Mallocator.makeArray(copy_tmpl.entity_data); + return tmpl; + } + /************************************************************************************************************************ Returns entity type info. @@ -2344,7 +2363,7 @@ export struct EntityManager Params: template_ = pointer entity template allocated by EntityManager. */ - export void freeTemplate(EntityTemplate* template_) + export void freeTemplate(EntityTemplate* template_) @nogc nothrow { Mallocator.dispose(template_.entity_data); Mallocator.dispose(template_); From 3647fa4b867ff7b4a0c0ecf5829c8b7bd23bb369 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 13 May 2020 15:34:24 +0200 Subject: [PATCH 16/58] Demos update -added functionality to detect host CPU threads count -fixed some memory leaks -now textures free memory corectly -added support for up to 32 threads --- demos/external/sources/mmutils/thread_pool.d | 40 ++++++++++++++++++++ demos/source/app.d | 34 ++++++++++++++--- demos/source/demos/snake.d | 16 ++++++-- demos/source/demos/space_invaders.d | 17 ++++++--- demos/utils/source/ecs_utils/gfx/renderer.d | 2 +- demos/utils/source/ecs_utils/gfx/texture.d | 5 ++- 6 files changed, 98 insertions(+), 16 deletions(-) diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 143960c..48d2932 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -810,6 +810,46 @@ private: JobData[4] resumeJobs; /// Dummu jobs to resume some thread public: + + static int getCPUCoresCount() + { + version(Windows) + { + import core.sys.windows.winbase : SYSTEM_INFO, GetSystemInfo; + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; + } + else version (linux) + { + version(D_BetterC) + { + import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf; + return cast(int)sysconf(_SC_NPROCESSORS_ONLN); + } + else + { + import core.sys.linux.sched : CPU_COUNT, cpu_set_t, sched_getaffinity; + import core.sys.posix.unistd : _SC_NPROCESSORS_ONLN, sysconf; + + cpu_set_t set = void; + if (sched_getaffinity(0, cpu_set_t.sizeof, &set) == 0) + { + int count = CPU_COUNT(&set); + if (count > 0) + return cast(uint) count; + } + return cast(int)sysconf(_SC_NPROCESSORS_ONLN); + } + } + else version(Posix) + { + import core.sys.posix.unistd; + return cast(int)sysconf(_SC_NPROCESSORS_ONLN); + } + else return -1; + } + int jobsDoneCount() { int sum; diff --git a/demos/source/app.d b/demos/source/app.d index af4b331..10fc80e 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -58,7 +58,7 @@ struct Launcher uint style = 3; uint entities_count; bool multithreading; - int threads; + int threads = 1; ulong timer_freq; double delta_time; uint fps; @@ -103,6 +103,14 @@ struct Launcher manager.update("clean"); manager.end(); + foreach(system; manager.systems) + { + if(system.id != CountSystem.system_id && system.id != CleanSystem.system_id)system.disable(); + } + + /*launcher.manager.getSystem(CountSystem.system_id).enable(); + launcher.manager.getSystem(CleanSystem.system_id).enable();//*/ + if(start)start(); this.loop = loop; this.end = end; @@ -316,11 +324,19 @@ void mainLoop(void* arg) if(igMenuItemBool("Multithreading", null, launcher.multithreading, true)) { launcher.multithreading = !launcher.multithreading; + if(launcher.multithreading) + { + launcher.job_updater.pool.setThreadsNum(launcher.threads); + } + else + { + launcher.job_updater.pool.setThreadsNum(1); + } } igSetNextItemWidth(0); igLabelText("Threads:",null); igSameLine(0,4); - if(igSliderInt("##Threads",&launcher.threads, 1, 12, null))//"Multithreading", null, launcher.multithreading, true)) + if(igSliderInt("##Threads",&launcher.threads, 1, 32, null))//"Multithreading", null, launcher.multithreading, true)) { launcher.job_updater.pool.setThreadsNum(launcher.threads); //launcher.threads = !launcher.multithreading; @@ -547,13 +563,13 @@ void mainLoop(void* arg) launcher.renderer.clear(); double loop_time = launcher.getTime(); - launcher.job_updater.pool.tryWaitCount = 5000; + launcher.job_updater.pool.tryWaitCount = 10000; if(launcher.loop && !launcher.loop()) { quit(); *cast(bool*)arg = false; } - launcher.job_updater.pool.tryWaitCount = 10; + launcher.job_updater.pool.tryWaitCount = 0; loop_time = launcher.getTime() - loop_time; @@ -697,10 +713,10 @@ int main(int argc, char** argv) setStyle(3); - launcher.job_updater = Mallocator.make!ECSJobUpdater(12); + launcher.job_updater = Mallocator.make!ECSJobUpdater(1); //launcher.job_updater.onCreate(); - EntityManager.initialize(12); + EntityManager.initialize(32); launcher.manager = EntityManager.instance; //launcher.manager.m_thread_id_func = &launcher.job_updater.getThreadID; @@ -720,6 +736,10 @@ int main(int argc, char** argv) launcher.renderer.initialize(); + import mmutils.thread_pool : ThreadPool; + launcher.threads = ThreadPool.getCPUCoresCount(); + if(launcher.threads < 2)launcher.threads = 2; + launcher.gui_manager = Mallocator.make!GUIManager(); { @@ -752,6 +772,8 @@ int main(int argc, char** argv) } } + EntityManager.destroy(); + return 0; } diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 94f2654..ecaefd3 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -90,6 +90,16 @@ struct Snake MapElement[map_size * map_size] map; + ~this() @nogc nothrow + { + if(snake_destroy_particle_frames)Mallocator.dispose(snake_destroy_particle_frames); + if(smoke_frames)Mallocator.dispose(smoke_frames); + if(apple_tmpl)launcher.manager.freeTemplate(apple_tmpl); + if(snake_tmpl)launcher.manager.freeTemplate(snake_tmpl); + if(snake_destroy_particle)launcher.manager.freeTemplate(snake_destroy_particle); + texture.destory(); + } + MapElement element(ivec2 pos) { uint index = pos.x + pos.y * map_size; @@ -805,9 +815,9 @@ void snakeStart() snake.addApple(); } - launcher.gui_manager.addTemplate(snake.snake_tmpl, "Snake"); - launcher.gui_manager.addTemplate(snake.apple_tmpl, "Apple"); - launcher.gui_manager.addTemplate(snake.snake_destroy_particle, "Particle"); + launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(snake.snake_tmpl), "Snake"); + launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(snake.apple_tmpl), "Apple"); + launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(snake.snake_destroy_particle), "Particle"); MoveSystem* move_system = launcher.manager.getSystem!MoveSystem(); move_system.setTemplates(); diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 004a3eb..b6fe80d 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -48,6 +48,10 @@ struct SpaceInvaders ~this() @nogc nothrow { if(shoot_grid)Mallocator.dispose(shoot_grid); + launcher.manager.freeTemplate(enemy_tmpl); + launcher.manager.freeTemplate(ship_tmpl); + launcher.manager.freeTemplate(laser_tmpl); + texture.destory(); } } @@ -337,7 +341,7 @@ struct ShootGridCleaner struct ShootGridManager { - mixin ECS.System!32; + mixin ECS.System!128; mixin ECS.WritableDependencies!(ShootGridDependency); @@ -793,7 +797,7 @@ struct MovementSystem } } -import core.stdc.math; +extern(C) float sqrtf(float x) @nogc nothrow @system; /** *System is responsible for movement of objects with CInput component. @@ -893,6 +897,8 @@ void spaceInvadersStart() launcher.manager.beginRegister(); + launcher.manager.registerDependency(ShootGridDependency); + launcher.manager.registerComponent!CLocation; launcher.manager.registerComponent!CTexture; launcher.manager.registerComponent!CInput; @@ -1009,10 +1015,10 @@ void spaceInvadersStart() enemy_tmpl = launcher.manager.allocateTemplate(enemy_id); grouped_tmpl = launcher.manager.allocateTemplate(grouped_id); - launcher.gui_manager.addTemplate(space_invaders.ship_tmpl,"Ship"); + launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.ship_tmpl),"Ship"); launcher.gui_manager.addTemplate(enemy_tmpl,"Enemy"); launcher.gui_manager.addTemplate(grouped_tmpl,"Grouped enemy"); - launcher.gui_manager.addTemplate(space_invaders.laser_tmpl,"Laser"); + launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.laser_tmpl),"Laser"); } @@ -1023,8 +1029,9 @@ void spaceInvadersEnd() launcher.manager.getSystem(LaserShootingSystem.system_id).disable(); launcher.manager.getSystem(MovementSystem.system_id).disable(); launcher.manager.getSystem(ClampPositionSystem.system_id).disable(); + launcher.manager.getSystem(ShootGridCleaner.system_id).disable(); - launcher.manager.freeTemplate(space_invaders.enemy_tmpl); + //launcher.manager.freeTemplate(space_invaders.enemy_tmpl); Mallocator.dispose(space_invaders); } diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index ba42cf6..206364f 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -230,7 +230,7 @@ struct Renderer block_stack_mutex.initialize(); - threads = Mallocator.makeArray!Thread(12); + threads = Mallocator.makeArray!Thread(32); foreach(ref Thread thread;threads) { thread.block = getBlock(); diff --git a/demos/utils/source/ecs_utils/gfx/texture.d b/demos/utils/source/ecs_utils/gfx/texture.d index 05e2fd9..d4e2089 100644 --- a/demos/utils/source/ecs_utils/gfx/texture.d +++ b/demos/utils/source/ecs_utils/gfx/texture.d @@ -54,6 +54,8 @@ struct Texture data.data = Mallocator.makeArray!ubyte(surf.w*surf.h*surf.format.BytesPerPixel); data.data[0..$] = (cast(ubyte*)surf.pixels)[0..data.data.length]; + SDL_FreeSurface(surf); + glGenTextures(1, &data.gl_handle); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,data.gl_handle); @@ -78,11 +80,12 @@ struct Texture glBindTexture(GL_TEXTURE_2D, data.gl_handle); } - void destory() + void destory() @nogc nothrow { if(data) { glDeleteTextures(1, &data.gl_handle); + if(data.data)Mallocator.dispose(data.data); Mallocator.dispose(data); data = null; } From d257a6c9f83acc660ddff5383b4ce45730663702 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 13 May 2020 16:24:32 +0200 Subject: [PATCH 17/58] Updated codecov.yml --- codecov.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index a6afdbc..f3e0d9b 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,3 +1,12 @@ ignore: - "tests/*" - - "**/traits*" \ No newline at end of file + - "**/traits*" + +coverage: + status: + project: + default: + threshold: 5 + patch: + default: + threshold: 5 \ No newline at end of file From c29ace661bde8b132248c44d810a716de741c608 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 13 May 2020 21:27:09 +0200 Subject: [PATCH 18/58] Added laser collision response to SpaceInvaders --- demos/assets/shaders/base.vp | 2 +- demos/source/demos/simple.d | 2 +- demos/source/demos/snake.d | 32 +++---- demos/source/demos/space_invaders.d | 124 +++++++++++++++++++++++++--- 4 files changed, 131 insertions(+), 29 deletions(-) diff --git a/demos/assets/shaders/base.vp b/demos/assets/shaders/base.vp index 2777a24..b054d8e 100644 --- a/demos/assets/shaders/base.vp +++ b/demos/assets/shaders/base.vp @@ -99,7 +99,7 @@ void main() { uv = tex_coords * uv_transform.zw + uv_transform.xy; #endif - color = vcolor; + color = vcolor * 2; gl_Position = vec4(position.xy,depth,1.0); diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 686f9be..1668323 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -62,7 +62,7 @@ struct DrawSystem if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached foreach(i; 0..data.length) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y*64+data.locations[i].x), uint.max, 0, 0, 0, data.thread_id); + launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y*64+data.locations[i].x), 0x80808080, 0, 0, 0, data.thread_id); //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); } if(data.thread_id == 0)launcher.renderer.pushData(); diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index ecaefd3..244e5ec 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -356,7 +356,7 @@ struct AnimationRenderSystem { foreach(i;0..data.length) { - launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i].location, vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], 0, 0 , 0); + launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i].location, vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080); } } } @@ -617,7 +617,7 @@ struct DrawAppleSystem { foreach(i; 0..data.location.length) { - launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, uint.max, 0); + launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0x80808080, 0); } } } @@ -687,16 +687,16 @@ struct DrawSnakeSystem { final switch(cast(ubyte)part) { - case SnakePart.tail_up:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,112,16,16)*px, 0, uint.max, 0);break; - case SnakePart.tail_down:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,112,16,16)*px, 0, uint.max, 0);break; - case SnakePart.tail_left:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,112,16,16)*px, 0, uint.max, 0);break; - case SnakePart.tail_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, uint.max, 0);break; - case SnakePart.turn_ld:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,128,16,16)*px, 0, uint.max, 0);break; - case SnakePart.turn_lu:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,144,16,16)*px, 0, uint.max, 0);break; - case SnakePart.turn_rd:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,144,16,16)*px, 0, uint.max, 0);break; - case SnakePart.turn_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, uint.max, 0);break; - case SnakePart.vertical:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,128,16,16)*px, 0, uint.max, 0);break; - case SnakePart.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,16,16)*px, 0, uint.max, 0);break; + case SnakePart.tail_up:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,112,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.tail_down:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,112,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.tail_left:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,112,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.tail_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.turn_ld:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,128,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.turn_lu:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,144,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.turn_rd:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,144,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.turn_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.vertical:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,128,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,16,16)*px, 0, 0x80808080, 0);break; } } @@ -708,10 +708,10 @@ struct DrawSnakeSystem scope vec2 loc = cast(vec2)(data.location[i].location * 16); final switch(snake.direction) { - case CMovement.Direction.up:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,112,16,16)*px, 0, uint.max, 0);break; - case CMovement.Direction.down:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,144,16,16)*px, 0, uint.max, 0);break; - case CMovement.Direction.left:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,128,16,16)*px, 0, uint.max, 0);break; - case CMovement.Direction.right:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(32,128,16,16)*px, 0, uint.max, 0);break; + case CMovement.Direction.up:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,112,16,16)*px, 0, 0x80808080, 0);break; + case CMovement.Direction.down:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,144,16,16)*px, 0, 0x80808080, 0);break; + case CMovement.Direction.left:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,128,16,16)*px, 0, 0x80808080, 0);break; + case CMovement.Direction.right:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(32,128,16,16)*px, 0, 0x80808080, 0);break; } if(snake.parts.length >1) { diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index b6fe80d..f4e2848 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -208,6 +208,24 @@ struct CShootGrid mixin ECS.Component; } +struct CHitPoints +{ + mixin ECS.Component; + + alias value this; + + int value = 10; +} + +struct CHitMark +{ + mixin ECS.Component; + + alias value this; + + ubyte value = 0; +} + /*####################################################################################################################### ------------------------------------------------ Events ------------------------------------------------------------------ #######################################################################################################################*/ @@ -224,6 +242,18 @@ struct EChangeDirection Direction direction; } +struct EDamage +{ + mixin ECS.Event; + + this(uint damage) + { + this.damage = damage; + } + + uint damage = 0; +} + /*####################################################################################################################### ------------------------------------------------ Systems ------------------------------------------------------------------ #######################################################################################################################*/ @@ -392,22 +422,47 @@ struct DrawSystem @readonly CLocation[] locations; @readonly CScale[] scale; @readonly @optional CDepth[] depth; + @readonly @optional CHitMark[] hit_mark; } void onUpdate(EntitiesData data) { if(!data.depth) - foreach(i; 0..data.length) + { + if(data.hit_mark) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)data.locations[i].y, uint.max, 0, 0, 0, data.thread_id); - //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); + foreach(i; 0..data.length) + { + uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)data.locations[i].y, color, 0, 0, 0, data.thread_id); + } } + else + { + foreach(i; 0..data.length) + { + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)data.locations[i].y, 0x80808080, 0, 0, 0, data.thread_id); + } + } + } else - foreach(i; 0..data.length) + { + if(data.hit_mark) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 64 + data.locations[i].y), uint.max, 0, 0, 0, data.thread_id); - //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); + foreach(i; 0..data.length) + { + uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 64 + data.locations[i].y), color, 0, 0, 0, data.thread_id); + } } + else + { + foreach(i; 0..data.length) + { + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 64 + data.locations[i].y), 0x80808080, 0, 0, 0, data.thread_id); + } + } + } if(data.thread_id == 0)launcher.renderer.pushData(); } } @@ -432,7 +487,7 @@ struct LaserShootingSystem mixin ECS.System!32; bool shoot = false; - static float[10] laser_shoot_times = [2000,1500,1000,700,500,300,100,50,10,1]; + static float[22] laser_shoot_times = [2000,1500,1000,700,500,350,250,170,130,80,50,25,15,10,5,2.5,2,1,0.8,0.5,0.3,0.1]; CLocation* laser_location; CVelocity* laser_velocity; @@ -523,6 +578,7 @@ struct LaserCollisionSystem { if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(~(1 << data.guild[i].guild)))) { + launcher.manager.sendEvent(id, EDamage(1)); launcher.manager.removeEntity(data.entity[i].id); } } @@ -666,7 +722,7 @@ struct ChangeDirectionSystem } } - void handleEvent(Entity* entity, EChangeDirection event) + /*void handleEvent(Entity* entity, EChangeDirection event) { CSideMove* side_move = entity.getComponent!CSideMove; if(side_move && side_move.group != -1) @@ -691,6 +747,46 @@ struct ChangeDirectionSystem if(velocity.value.x < 0)velocity.value.x = -velocity.value.x; break; } + }*/ +} + +struct HitMarkingSystem +{ + mixin ECS.System!16; + + struct EntitiesData + { + uint length; + CHitMark[] mark; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + //if(data.mark[i] < 10)data.mark[i] = 0; + //else data.mark[i] -= 1; + data.mark[i] = cast(ubyte)(data.mark[i] * 0.9); + } + } +} + +struct HitPointsSystem +{ + mixin ECS.System; + + struct EntitiesData + { + CHitPoints[] hp; + } + + void handleEvent(Entity* entity, EDamage event) + { + CHitPoints* hp = entity.getComponent!CHitPoints; + *hp -= event.damage; + if(*hp < 0)launcher.manager.removeEntity(entity.id); + CHitMark* hit_mark = entity.getComponent!CHitMark; + if(hit_mark)hit_mark.value = 127; } } @@ -914,8 +1010,11 @@ void spaceInvadersStart() launcher.manager.registerComponent!CDepth; launcher.manager.registerComponent!CShootGrid; launcher.manager.registerComponent!CGuild; + launcher.manager.registerComponent!CHitPoints; + launcher.manager.registerComponent!CHitMark; launcher.manager.registerEvent!EChangeDirection; + launcher.manager.registerEvent!EDamage; //launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); @@ -927,6 +1026,8 @@ void spaceInvadersStart() launcher.manager.registerSystem!LaserCollisionSystem(-70); launcher.manager.registerSystem!ShootGridManager(-80); launcher.manager.registerSystem!ShootGridCleaner(-101); + launcher.manager.registerSystem!HitPointsSystem(0); + launcher.manager.registerSystem!HitMarkingSystem(-100); launcher.manager.endRegister(); @@ -939,7 +1040,7 @@ void spaceInvadersStart() //launcher.manager.getSystem(CleanSystem.system_id).disable(); { - ushort[9] components = [CLocation.component_id, CTexture.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CLaserWeapon.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; + ushort[11] components = [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexture.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CLaserWeapon.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; space_invaders.ship_tmpl = launcher.manager.allocateTemplate(components); CScale* scale_comp = space_invaders.ship_tmpl.getComponent!CScale; @@ -950,7 +1051,8 @@ void spaceInvadersStart() CLocation* loc_comp = space_invaders.ship_tmpl.getComponent!CLocation; loc_comp.value = vec2(64,64); CLaserWeapon* weapon = space_invaders.ship_tmpl.getComponent!CLaserWeapon; - weapon.level = 10; + weapon.level = 22; + space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; launcher.manager.addEntity(space_invaders.ship_tmpl); } @@ -974,7 +1076,7 @@ void spaceInvadersStart() EntityID grouped_id; { - ushort[10] components = [CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CLaserWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; + ushort[12] components = [CHitMark.component_id, CHitPoints.component_id, CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CLaserWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; space_invaders.enemy_tmpl = launcher.manager.allocateTemplate(components); CTexture* tex_comp = space_invaders.enemy_tmpl.getComponent!CTexture; From d26c940b80608ab64cbd18413ae1b71f05c08c15 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 13 May 2020 21:30:56 +0200 Subject: [PATCH 19/58] Fixed shader compilation on GLES --- demos/assets/shaders/base.vp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demos/assets/shaders/base.vp b/demos/assets/shaders/base.vp index b054d8e..6c4c183 100644 --- a/demos/assets/shaders/base.vp +++ b/demos/assets/shaders/base.vp @@ -99,7 +99,7 @@ void main() { uv = tex_coords * uv_transform.zw + uv_transform.xy; #endif - color = vcolor * 2; + color = vcolor * 2.0; gl_Position = vec4(position.xy,depth,1.0); From f731b4cedb1f9f6b408a555312a18eed7bcae3ee Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 13 May 2020 21:51:38 +0200 Subject: [PATCH 20/58] Added Upgrade bonuses to SpaceInvaders demo --- demos/source/demos/space_invaders.d | 82 ++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index f4e2848..1c5b3e4 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -226,6 +226,11 @@ struct CHitMark ubyte value = 0; } +struct CUpgrade +{ + mixin ECS.Component; +} + /*####################################################################################################################### ------------------------------------------------ Events ------------------------------------------------------------------ #######################################################################################################################*/ @@ -242,6 +247,11 @@ struct EChangeDirection Direction direction; } +struct EUpgrade +{ + mixin ECS.Event; +} + struct EDamage { mixin ECS.Event; @@ -487,7 +497,7 @@ struct LaserShootingSystem mixin ECS.System!32; bool shoot = false; - static float[22] laser_shoot_times = [2000,1500,1000,700,500,350,250,170,130,80,50,25,15,10,5,2.5,2,1,0.8,0.5,0.3,0.1]; + static float[18] laser_shoot_times = [500,400,300,200,100,50,25,10,5,2,1,0.8,0.6,0.5,0.4,0.3,0.2,0.1]; CLocation* laser_location; CVelocity* laser_velocity; @@ -583,7 +593,55 @@ struct LaserCollisionSystem } } } +} +struct UpgradeCollisionSystem +{ + mixin ECS.System!32; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + @readonly CLocation[] location; + @readonly CUpgrade[] upgrade; + } + + void onUpdate(EntitiesData data) + { + EntityID id; + foreach(i; 0..data.length) + { + if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(0xFF))) + { + launcher.manager.sendEvent(id, EUpgrade()); + launcher.manager.removeEntity(data.entity[i].id); + } + } + } +} + +struct UpgradeSystem +{ + mixin ECS.System; + + struct EntitiesData + { + const (Entity)[] entity; + @readonly CShip[] ship; + } + + void handleEvent(Entity* entity, EUpgrade event) + { + CLaserWeapon* laser = entity.getComponent!CLaserWeapon; + if(laser) + { + if(laser.level < LaserShootingSystem.laser_shoot_times.length)laser.level++; + } + } } struct ChangeDirectionSystem @@ -893,6 +951,7 @@ struct MovementSystem } } + extern(C) float sqrtf(float x) @nogc nothrow @system; /** @@ -1012,9 +1071,11 @@ void spaceInvadersStart() launcher.manager.registerComponent!CGuild; launcher.manager.registerComponent!CHitPoints; launcher.manager.registerComponent!CHitMark; + launcher.manager.registerComponent!CUpgrade; launcher.manager.registerEvent!EChangeDirection; launcher.manager.registerEvent!EDamage; + launcher.manager.registerEvent!EUpgrade; //launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); @@ -1028,6 +1089,8 @@ void spaceInvadersStart() launcher.manager.registerSystem!ShootGridCleaner(-101); launcher.manager.registerSystem!HitPointsSystem(0); launcher.manager.registerSystem!HitMarkingSystem(-100); + launcher.manager.registerSystem!UpgradeCollisionSystem(-70); + launcher.manager.registerSystem!UpgradeSystem(-100); launcher.manager.endRegister(); @@ -1051,7 +1114,7 @@ void spaceInvadersStart() CLocation* loc_comp = space_invaders.ship_tmpl.getComponent!CLocation; loc_comp.value = vec2(64,64); CLaserWeapon* weapon = space_invaders.ship_tmpl.getComponent!CLaserWeapon; - weapon.level = 22; + weapon.level = 1; space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; launcher.manager.addEntity(space_invaders.ship_tmpl); @@ -1112,6 +1175,18 @@ void spaceInvadersStart() grouped_id = current_entity.id; //grouped_tmpl = launcher.manager.allocateTemplate(current_entity.id); } + + EntityTemplate* upgrade_tmpl; + + { + upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id].staticArray); + CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; + tex_comp.tex = space_invaders.texture;//ship_tex; + tex_comp.coords = vec4(0*px,32*px,16*px,16*px); + CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; + vel_comp.value = vec2(0,-0.1); + } + launcher.manager.commit(); enemy_tmpl = launcher.manager.allocateTemplate(enemy_id); @@ -1121,6 +1196,7 @@ void spaceInvadersStart() launcher.gui_manager.addTemplate(enemy_tmpl,"Enemy"); launcher.gui_manager.addTemplate(grouped_tmpl,"Grouped enemy"); launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.laser_tmpl),"Laser"); + launcher.gui_manager.addTemplate(upgrade_tmpl,"Upgrade"); } @@ -1149,6 +1225,8 @@ void spaceInvadersTool(vec2 position, Tool tool, int size) { position.x += (randomf - 0.5) * size; position.y += (randomf - 0.5) * size; + if(position.y < 16)position.y = 16; + else if(position.y > 299)position.y = 299; *location = position; } CLaserWeapon* laser_weapon = tmpl.getComponent!CLaserWeapon; From 9589a5cb2d051e18f32039daad4077150b72870f Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 14 May 2020 22:18:57 +0200 Subject: [PATCH 21/58] FIxed GDC compilation (basic betterC WIP) and some improvements -fixed issue with adding/removing entities inside events handling -fixed EntityMeta.getComponent() (added check if component_id is valid) -added function hasComponent to entity to check if component exists --- demos/external/sources/mmutils/thread_pool.d | 7 +- demos/source/demos/snake.d | 2 +- demos/utils/source/ecs_utils/utils.d | 14 +- dub.json | 14 +- source/bubel/ecs/entity.d | 18 ++ source/bubel/ecs/manager.d | 164 ++++++++++--------- source/bubel/ecs/std.d | 8 + source/bubel/ecs/vector.d | 14 +- tests/access_perf.d | 9 +- tests/basic.d | 9 +- tests/perf.d | 9 +- 11 files changed, 174 insertions(+), 94 deletions(-) diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 48d2932..52136d4 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -182,6 +182,12 @@ void instructionPause() __builtin_ia32_pause(); } + else version(GNU) + { + import gcc.builtins; + + __builtin_ia32_pause(); + } else version (DigitalMars) { asm @@ -189,7 +195,6 @@ void instructionPause() rep; nop; } - } else { diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 244e5ec..3c62ef6 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -17,7 +17,7 @@ import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; -import std.array : staticArray; +//import std.array : staticArray; enum float px = 1.0/512.0; diff --git a/demos/utils/source/ecs_utils/utils.d b/demos/utils/source/ecs_utils/utils.d index 4c143fd..8ce5cd1 100644 --- a/demos/utils/source/ecs_utils/utils.d +++ b/demos/utils/source/ecs_utils/utils.d @@ -21,7 +21,19 @@ float randomRangef(float min, float max) return rand()%4096; }*/ -extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; +version(GNU) +{ + public import core.stdc.stdio : printf; + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else +{ + extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; + public import std.array : staticArray; +} extern(C) int rand(); version(D_BetterC) diff --git a/dub.json b/dub.json index c23a4e6..01cf85c 100755 --- a/dub.json +++ b/dub.json @@ -74,6 +74,9 @@ "dflags": [ "-betterC", "-defaultlib=" + ], + "dflags-gdc": [ + "-fno-druntime" ] }, { @@ -88,9 +91,7 @@ ], "dflags-gdc": [ "-fno-druntime", - "-fvisibility=hidden" - ], - "lflags-gdc": [ + "-fvisibility=hidden", "-lpthread" ] }, @@ -105,9 +106,7 @@ "-betterC" ], "dflags-gdc": [ - "-fno-druntime" - ], - "lflags-gdc": [ + "-fno-druntime", "-lpthread" ] }, @@ -118,6 +117,9 @@ "-betterC", "-unittest" ], + "dflags-gdc": [ + "-fno-druntime" + ], "sourcePaths": ["source/","tests/"], "mainSourceFile":"tests/runner.d", "excludedSourceFiles":[ diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index 10720a2..1e98ff2 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -46,6 +46,14 @@ struct Entity return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof); } + bool hasComponent(ushort component_id) + { + EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); + EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false; + return true; + } + EntityMeta getMeta() { EntityMeta meta; @@ -65,8 +73,18 @@ struct EntityMeta T* getComponent(T)() const { + const (EntityManager.EntityInfo)* info = block.type_info; + if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) + return null; return cast(T*)(cast(void*)block + block.type_info.deltas[T.component_id] + index * T.sizeof); } + + bool hasComponent(ushort component_id) + { + EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false; + return true; + } } /************************************************************************************************************************ diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index c6b02a1..7b6a983 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -126,7 +126,7 @@ export struct EntityManager //if(info.components)Mallocator.dispose(info.components); Mallocator.dispose(info); - } //*/ + } foreach (UpdatePass* pass; passes) { @@ -472,50 +472,52 @@ export struct EntityManager if (member == "length" || member == "thread_id" || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) { - continue; + //continue; } - - string name; - static if (isArray!MemberType) - { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = Unqual!(ForeachType!MemberType).stringof; - } - - bool is_optional; - bool is_read_only; - - if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) + else { - is_read_only = true; - } - - foreach (att; __traits(getAttributes, __traits(getMember, - Sys.EntitiesData, member))) - { - if (att == "optional") - { - is_optional = true; + string name; + static if (isArray!MemberType) + { // Workaround. This code is never called with: not an array type, but compiler prints an error + name = Unqual!(ForeachType!MemberType).stringof; } - if (att == "readonly") + + bool is_optional; + bool is_read_only; + + if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) { is_read_only = true; } - } - if (is_read_only) - { - components_counts.readonly++; - } - else - { - components_counts.mutable++; - } - if (is_optional) - { - components_counts.optional++; - } - else - { - components_counts.req++; + + foreach (att; __traits(getAttributes, __traits(getMember, + Sys.EntitiesData, member))) + { + if (att == "optional") + { + is_optional = true; + } + if (att == "readonly") + { + is_read_only = true; + } + } + if (is_read_only) + { + components_counts.readonly++; + } + else + { + components_counts.mutable++; + } + if (is_optional) + { + components_counts.optional++; + } + else + { + components_counts.req++; + } } } @@ -695,50 +697,52 @@ export struct EntityManager { if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) components_info.entites_array = member; - continue; + //continue; } - - string name; - static if (isArray!MemberType) - { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = Unqual!(ForeachType!MemberType).stringof; - } - - bool is_optional; - bool is_read_only; - - if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) + else { - is_read_only = true; - } - - foreach (att; __traits(getAttributes, __traits(getMember, - Sys.EntitiesData, member))) - { - if (att == "optional") - { - is_optional = true; + string name; + static if (isArray!MemberType) + { // Workaround. This code is never called with: not an array type, but compiler prints an error + name = Unqual!(ForeachType!MemberType).stringof; } - if (att == "readonly") + + bool is_optional; + bool is_read_only; + + if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) { is_read_only = true; } - } - if (is_read_only) - { - components_info.addReadonly(CompInfo(member, name)); - } - else - { - components_info.addMutable(CompInfo(member, name)); - } - if (is_optional) - { - components_info.addOptional(CompInfo(member, name)); - } - else - { - components_info.addReq(CompInfo(member, name)); + + foreach (att; __traits(getAttributes, __traits(getMember, + Sys.EntitiesData, member))) + { + if (att == "optional") + { + is_optional = true; + } + if (att == "readonly") + { + is_read_only = true; + } + } + if (is_read_only) + { + components_info.addReadonly(CompInfo(member, name)); + } + else + { + components_info.addMutable(CompInfo(member, name)); + } + if (is_optional) + { + components_info.addOptional(CompInfo(member, name)); + } + else + { + components_info.addReq(CompInfo(member, name)); + } } } @@ -874,7 +878,7 @@ export struct EntityManager } } - static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info, + static void fillInputData()(ref Sys.EntitiesData input_data, EntityInfo* info, EntitiesBlock* block, uint offset, uint entities_count, System* system) { //enum ComponentsIndices components_info = getComponentsInfo(); @@ -2863,7 +2867,11 @@ export struct EntityManager id_manager.optimize(); updateBlocks(); changeEntities(); + updateEvents(); + + id_manager.optimize(); + updateBlocks(); removeEntities(); event_manager.clearEvents(); } diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d index 4cec197..6658639 100644 --- a/source/bubel/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -113,6 +113,14 @@ else version(D_BetterC) alloca_pos += length; return ret; } + + version(GNU) + { + extern(C) void __gdc_personality_v0() + { + + } + } } else { diff --git a/source/bubel/ecs/vector.d b/source/bubel/ecs/vector.d index 413bbce..1ec8a93 100644 --- a/source/bubel/ecs/vector.d +++ b/source/bubel/ecs/vector.d @@ -55,7 +55,8 @@ public: /*foreach (ref el; array[0 .. used]) { destroy(el); }*/ - freeData(cast(void[]) array); + //freeData(cast(void[]) array); + freeData((cast(void*)array.ptr)[0 .. array.length * T.sizeof]); gVectorsDestroyed++; } array = null; @@ -78,7 +79,9 @@ public: } } else { foreach (ref el; array[newLength .. used]) { - destroy(el); + //destroy(el); + static if(__traits(hasMember, T, "__xdtor"))el.__xdtor(); + else static if(__traits(hasMember, T, "__dtor"))el.__dtor(); } } used = newLength; @@ -122,7 +125,8 @@ public: T* memory = cast(T*) malloc(newSize); memcpy(cast(void*) memory, cast(void*) oldArray.ptr, oldSize); array = memory[0 .. newNumOfElements]; - return cast(void[]) oldArray; + //return cast(void[]) oldArray; + return (cast(void*)oldArray.ptr)[0 .. oldArray.length * T.sizeof]; } export Vector!T copy()() { @@ -169,7 +173,9 @@ public: } export void remove(size_t elemNum) { - destroy(array[elemNum]); + //destroy(array[elemNum]); + static if(__traits(hasMember, T, "__xdtor"))array[elemNum].__xdtor(); + else static if(__traits(hasMember, T, "__dtor"))array[elemNum].__dtor(); //swap(array[elemNum], array[used - 1]); array[elemNum] = array[used - 1]; used--; diff --git a/tests/access_perf.d b/tests/access_perf.d index 141a2e6..36da0c0 100644 --- a/tests/access_perf.d +++ b/tests/access_perf.d @@ -6,7 +6,14 @@ import bubel.ecs.core; import bubel.ecs.manager; import bubel.ecs.entity; -import std.array : staticArray; +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; import core.stdc.stdio; diff --git a/tests/basic.d b/tests/basic.d index 10d79b8..3bf2814 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -5,7 +5,14 @@ import bubel.ecs.manager; import bubel.ecs.system; import bubel.ecs.attributes; -import std.array : staticArray; +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; struct CInt { diff --git a/tests/perf.d b/tests/perf.d index 135dc54..b6a2692 100644 --- a/tests/perf.d +++ b/tests/perf.d @@ -6,7 +6,14 @@ import bubel.ecs.core; import bubel.ecs.manager; import bubel.ecs.entity; -import std.array : staticArray; +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; import core.stdc.stdio; From 6c3c803d1ea1e2c4f5916efd7da06fb27595382e Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 14 May 2020 22:20:41 +0200 Subject: [PATCH 22/58] SpaceShip demo update -fixed issue with firing lasers in multithreaded mode -fix: enies can't grab upgrade anymore -there is a change that enemy drop bonus upon death --- demos/source/demos/space_invaders.d | 124 ++++++++++++++++++++++++---- 1 file changed, 109 insertions(+), 15 deletions(-) diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 1c5b3e4..bef65fe 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -16,7 +16,7 @@ import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; -import std.array : staticArray; +//import std.array : staticArray; enum float px = 1.0/512.0; @@ -252,6 +252,11 @@ struct EUpgrade mixin ECS.Event; } +struct EDeath +{ + mixin ECS.Event; +} + struct EDamage { mixin ECS.Event; @@ -499,32 +504,72 @@ struct LaserShootingSystem bool shoot = false; static float[18] laser_shoot_times = [500,400,300,200,100,50,25,10,5,2,1,0.8,0.6,0.5,0.4,0.3,0.2,0.1]; - CLocation* laser_location; + /*CLocation* laser_location; CVelocity* laser_velocity; - CGuild* laser_guild; + CGuild* laser_guild;*/ struct EntitiesData { ///variable named "length" contain entites count uint length; + ///variable named "length" contain thread identifier + uint thread_id; @readonly CShootDirection[] shoot_direction; @readonly @optional CAutoShoot[] auto_shoot; @readonly CLocation[] location; @readonly CGuild[] guild; CLaserWeapon[] laser; } + + struct ThreadData + { + EntityTemplate* laser_tmpl; + CLocation* laser_location; + CVelocity* laser_velocity; + CGuild* laser_guild; + } + + ThreadData[] threads; ///Called inside "registerSystem" function - /*void onCreate() + void onCreate() { - laser_location = space_invaders.laser_tmpl.getComponent!CLocation; - }*/ + threads = Mallocator.makeArray!ThreadData(32); + threads[0].laser_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CTexture.component_id, CVelocity.component_id, CScale.component_id, CLaser.component_id, CGuild.component_id].staticArray); + + CTexture* tex_comp = threads[0].laser_tmpl.getComponent!CTexture; + tex_comp.tex = space_invaders.texture;//laser_tex; + tex_comp.coords = vec4(0*px,24*px,2*px,8*px); + CScale* scale_comp = threads[0].laser_tmpl.getComponent!CScale; + scale_comp.value = vec2(2,8); + threads[0].laser_location = threads[0].laser_tmpl.getComponent!CLocation; + threads[0].laser_velocity = threads[0].laser_tmpl.getComponent!CVelocity; + threads[0].laser_guild = threads[0].laser_tmpl.getComponent!CGuild; + + foreach(ref ThreadData thread;threads[1..$]) + { + thread.laser_tmpl = launcher.manager.allocateTemplate(threads[0].laser_tmpl); + thread.laser_location = thread.laser_tmpl.getComponent!CLocation; + thread.laser_velocity = thread.laser_tmpl.getComponent!CVelocity; + thread.laser_guild = thread.laser_tmpl.getComponent!CGuild; + } + //laser_location = space_invaders.laser_tmpl.getComponent!CLocation; + } + + void onDestroy() + { + foreach(ref ThreadData thread;threads[1..$]) + { + launcher.manager.freeTemplate(thread.laser_tmpl); + } + Mallocator.dispose(threads); + } bool onBegin() { - laser_location = space_invaders.laser_tmpl.getComponent!CLocation; + /*laser_location = space_invaders.laser_tmpl.getComponent!CLocation; laser_velocity = space_invaders.laser_tmpl.getComponent!CVelocity; - laser_guild = space_invaders.laser_tmpl.getComponent!CGuild; + laser_guild = space_invaders.laser_tmpl.getComponent!CGuild;*/ if(launcher.getKeyState(SDL_SCANCODE_SPACE)) { shoot = true; @@ -535,6 +580,7 @@ struct LaserShootingSystem void onUpdate(EntitiesData data) { + ThreadData* thread = &threads[data.thread_id]; //conditional branch for whole entities block if(shoot || data.auto_shoot) { @@ -545,10 +591,10 @@ struct LaserShootingSystem while(laser.shoot_time > laser_shoot_times[laser.level - 1]) { laser.shoot_time -= laser_shoot_times[laser.level - 1]; - laser_location.value = data.location[i]; - laser_velocity.value = vec2(randomf()*0.5-0.25,data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); - laser_guild.guild = data.guild[i].guild; - launcher.manager.addEntity(space_invaders.laser_tmpl); + thread.laser_location.value = data.location[i]; + thread.laser_velocity.value = vec2(randomf()*0.5-0.25,data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); + thread.laser_guild.guild = data.guild[i].guild; + launcher.manager.addEntity(thread.laser_tmpl); } } } @@ -617,8 +663,12 @@ struct UpgradeCollisionSystem { if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(0xFF))) { - launcher.manager.sendEvent(id, EUpgrade()); - launcher.manager.removeEntity(data.entity[i].id); + Entity* entity = launcher.manager.getEntity(id); + if(entity.hasComponent(CShip.component_id)) + { + launcher.manager.sendEvent(id, EUpgrade()); + launcher.manager.removeEntity(data.entity[i].id); + } } } } @@ -676,6 +726,7 @@ struct ChangeDirectionSystem if(direction != cast(Direction)-1)//return true; { has_changes = true; +INFO: Uniform block alig break; } } @@ -833,19 +884,61 @@ struct HitPointsSystem { mixin ECS.System; + EntityTemplate* upgrade_tmpl; + CLocation* upgrade_location; + struct EntitiesData { CHitPoints[] hp; } + void onCreate() + { + upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id].staticArray); + CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; + tex_comp.tex = space_invaders.texture;//ship_tex; + tex_comp.coords = vec4(0*px,32*px,16*px,16*px); + CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; + vel_comp.value = vec2(0,-0.1); + upgrade_location = upgrade_tmpl.getComponent!CLocation; + } + + void onDestroy() + { + launcher.manager.freeTemplate(upgrade_tmpl); + } + void handleEvent(Entity* entity, EDamage event) { CHitPoints* hp = entity.getComponent!CHitPoints; + if(*hp < 0)return; *hp -= event.damage; - if(*hp < 0)launcher.manager.removeEntity(entity.id); + if(*hp < 0) + { + launcher.manager.sendEvent(entity.id, EDeath()); + //launcher.manager.removeEntity(entity.id); + } CHitMark* hit_mark = entity.getComponent!CHitMark; if(hit_mark)hit_mark.value = 127; } + + void handleEvent(Entity* entity, EDeath event) + { + CEnemy* enemy = entity.getComponent!CEnemy; + if(enemy) + { + if(randomRange(0, 1000) < 5) + { + CLocation* location = entity.getComponent!CLocation; + if(location) + { + *upgrade_location = *location; + launcher.manager.addEntity(upgrade_tmpl); + } + } + } + launcher.manager.removeEntity(entity.id); + } } struct ClampPositionSystem @@ -1076,6 +1169,7 @@ void spaceInvadersStart() launcher.manager.registerEvent!EChangeDirection; launcher.manager.registerEvent!EDamage; launcher.manager.registerEvent!EUpgrade; + launcher.manager.registerEvent!EDeath; //launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); From 0b924ae77c8084d39b360f90b688a8461a04d043 Mon Sep 17 00:00:00 2001 From: Mergul Date: Tue, 19 May 2020 20:27:18 +0200 Subject: [PATCH 23/58] Demos update (SpaceInvaders demo) -added new sprites -added new functions to vectors -fixed rendering rotated sprites -small performance improvement and some bug fixes -added animations support -bullets get initial velocity from parent -added partiles for fire from gun and explosion of enemies --- demos/assets/textures/atlas.png | Bin 24668 -> 35204 bytes demos/dub.json | 3 + demos/source/app.d | 4 +- demos/source/demos/snake.d | 2 +- demos/source/demos/space_invaders.d | 362 ++++++++++++++++++-- demos/utils/source/ecs_utils/gfx/renderer.d | 18 + demos/utils/source/ecs_utils/math/vector.d | 56 +++ 7 files changed, 411 insertions(+), 34 deletions(-) diff --git a/demos/assets/textures/atlas.png b/demos/assets/textures/atlas.png index c628969c0e7149419eb62313fb5c3274457838f3..1e269e513e42c5dc797f568af05816d2562995f0 100644 GIT binary patch literal 35204 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
-U`yoWDlL!y69I7g$; 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 diff --git a/demos/dub.json b/demos/dub.json index 43d248c..1c1fe65 100644 --- a/demos/dub.json +++ b/demos/dub.json @@ -18,6 +18,9 @@ "libs-windows-x86_64": ["libs/windows/x64/SDL2","libs/windows/x64/SDL2_Image","libs/windows/x64/cimgui"], "libs-linux-x86_64": ["cimgui","SDL2","SDL2_image"], "lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"], + "dflags-ldc" : [ + "--ffast-math" + ], "configurations" : [ { "name" : "default", diff --git a/demos/source/app.d b/demos/source/app.d index 10fc80e..3af24b5 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -262,7 +262,7 @@ void mainLoop(void* arg) if(launcher.tool && launcher.tool_repeat != 0 && launcher.mouse.left && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) { float range = 500.0 / cast(float)launcher.tool_repeat; - launcher.repeat_time += launcher.delta_time; + launcher.repeat_time += launcher.delta_time * 100; while(launcher.repeat_time > range) { launcher.repeat_time -= range; @@ -716,7 +716,7 @@ int main(int argc, char** argv) launcher.job_updater = Mallocator.make!ECSJobUpdater(1); //launcher.job_updater.onCreate(); - EntityManager.initialize(32); + EntityManager.initialize(32, 1<<16); launcher.manager = EntityManager.instance; //launcher.manager.m_thread_id_func = &launcher.job_updater.getThreadID; diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 3c62ef6..50f7729 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -285,7 +285,7 @@ struct ParticleSystem { uint length; @readonly Entity[] entities; - @readonly CParticle[] particle; + CParticle[] particle; } void onUpdate(EntitiesData data) diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index bef65fe..56d891d 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -16,6 +16,8 @@ import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; +import std.math : PI; + //import std.array : staticArray; enum float px = 1.0/512.0; @@ -121,6 +123,16 @@ struct CScale vec2 value = vec2(16,16); } +struct CRotation +{ + mixin ECS.Component; + + ///use component as it value + alias value this; + + float value = 0; +} + struct CTexture { mixin ECS.Component; @@ -176,6 +188,17 @@ struct CLaserWeapon { mixin ECS.Component; + static struct Level + { + float reload_time; + float dispersion; + } + + __gshared Level[12] levels = [Level(4000,0),Level(4000,0.1), + Level(500,0),Level(350,0),Level(250,0.02),Level(175,0.03),Level(110,0.04), + Level(80,0.05),Level(50,0.08),Level(20,0.1),Level(10,0.12),Level(2,0.14)]; + + ubyte level = 1; float shoot_time = 0; } @@ -208,13 +231,30 @@ struct CShootGrid mixin ECS.Component; } +struct CTargetPartent +{ + mixin ECS.Component; + + EntityID parent; + vec2 rel_pos; +} + struct CHitPoints { mixin ECS.Component; alias value this; - int value = 10; + int value = 3; +} + +struct CMaxHitPoints +{ + mixin ECS.Component; + + alias value this; + + int value = 3; } struct CHitMark @@ -229,6 +269,47 @@ struct CHitMark struct CUpgrade { mixin ECS.Component; + + alias value this; + + enum Upgrade : ubyte + { + hit_points, + regeneration, + laser + } + + Upgrade value; +} + +struct CAnimation +{ + mixin ECS.Component; + + vec4[] frames; + float time = 0; + float speed = 1; +} + +struct CAnimationLooped +{ + mixin ECS.Component; +} + +struct CDamping +{ + mixin ECS.Component; + + alias value this; + + byte value = 0; +} + +struct CParticle +{ + mixin ECS.Component; + + float life = 0; } /*####################################################################################################################### @@ -436,6 +517,7 @@ struct DrawSystem @readonly CTexture[] textures; @readonly CLocation[] locations; @readonly CScale[] scale; + @readonly @optional CRotation[] rotation; @readonly @optional CDepth[] depth; @readonly @optional CHitMark[] hit_mark; } @@ -452,6 +534,13 @@ struct DrawSystem launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)data.locations[i].y, color, 0, 0, 0, data.thread_id); } } + else if(data.rotation) + { + foreach(i; 0..data.length) + { + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)data.locations[i].y, 0x80808080, data.rotation[i], 0, 0, data.thread_id); + } + } else { foreach(i; 0..data.length) @@ -463,18 +552,36 @@ struct DrawSystem else { if(data.hit_mark) + { + if(data.rotation) + { + foreach(i; 0..data.length) + { + uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 4 + data.locations[i].y), color, data.rotation[i], 0, 0, data.thread_id); + } + } + else + { + foreach(i; 0..data.length) + { + uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 4 + data.locations[i].y), color, 0, 0, 0, data.thread_id); + } + } + } + else if(data.rotation) { foreach(i; 0..data.length) { - uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; - launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 64 + data.locations[i].y), color, 0, 0, 0, data.thread_id); + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 4 + data.locations[i].y), 0x80808080, data.rotation[i], 0, 0, data.thread_id); } } else { foreach(i; 0..data.length) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 64 + data.locations[i].y), 0x80808080, 0, 0, 0, data.thread_id); + launcher.renderer.draw(data.textures[i].tex, data.locations[i].value, data.scale[i], data.textures[i].coords, cast(short)(data.depth[i] * 4 + data.locations[i].y), 0x80808080, 0, 0, 0, data.thread_id); } } } @@ -502,12 +609,19 @@ struct LaserShootingSystem mixin ECS.System!32; bool shoot = false; - static float[18] laser_shoot_times = [500,400,300,200,100,50,25,10,5,2,1,0.8,0.6,0.5,0.4,0.3,0.2,0.1]; + //static float[18] laser_shoot_times = [500,400,300,200,100,50,25,10,5,2,1,0.8,0.6,0.5,0.4,0.3,0.2,0.1]; + //static float[18] laser_shoot_disp = [0,0,0,0,0.05,0.06,0.08,0.1,0.14,0.18,0.2,0.25,0.26,0.27,0.28,0.29,0.3,0.4]; + + __gshared vec4[] fire_frames = [vec4(96,64,8,16)*px,vec4(104,64,8,16)*px,vec4(112,64,8,16)*px,vec4(120,64,8,16)*px,vec4(128,64,8,16)*px, + vec4(136,64,8,16)*px,vec4(144,64,8,16)*px,vec4(152,64,8,16)*px,vec4(160,64,8,16)*px]; + + // __gshared vec4[] fire_frames = [vec4(0,160,8,16)*px,vec4(16,160,16,16)*px,vec4(32,160,16,16)*px,vec4(48,160,16,16)*px,vec4(64,160,16,16)*px, + // vec4(80,160,16,16)*px,vec4(96,160,16,16)*px,vec4(112,160,16,16)*px]; /*CLocation* laser_location; CVelocity* laser_velocity; CGuild* laser_guild;*/ - + struct EntitiesData { ///variable named "length" contain entites count @@ -518,6 +632,7 @@ struct LaserShootingSystem @readonly @optional CAutoShoot[] auto_shoot; @readonly CLocation[] location; @readonly CGuild[] guild; + @optional @readonly CVelocity[] velocity; CLaserWeapon[] laser; } @@ -527,6 +642,11 @@ struct LaserShootingSystem CLocation* laser_location; CVelocity* laser_velocity; CGuild* laser_guild; + + EntityTemplate* fire_tmpl; + CLocation* fire_location; + CVelocity* fire_velocity; + CRotation* fire_rotation; } ThreadData[] threads; @@ -535,7 +655,10 @@ struct LaserShootingSystem void onCreate() { threads = Mallocator.makeArray!ThreadData(32); - threads[0].laser_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CTexture.component_id, CVelocity.component_id, CScale.component_id, CLaser.component_id, CGuild.component_id].staticArray); + threads[0].laser_tmpl = launcher.manager.allocateTemplate( + [CLocation.component_id, CTexture.component_id, CVelocity.component_id, + CScale.component_id, CLaser.component_id, CGuild.component_id].staticArray + ); CTexture* tex_comp = threads[0].laser_tmpl.getComponent!CTexture; tex_comp.tex = space_invaders.texture;//laser_tex; @@ -546,12 +669,33 @@ struct LaserShootingSystem threads[0].laser_velocity = threads[0].laser_tmpl.getComponent!CVelocity; threads[0].laser_guild = threads[0].laser_tmpl.getComponent!CGuild; + threads[0].fire_tmpl = launcher.manager.allocateTemplate( + [CLocation.component_id, CTexture.component_id, CScale.component_id, + CAnimation.component_id, CParticle.component_id, CRotation.component_id, + CVelocity.component_id, CDamping.component_id].staticArray + ); + + tex_comp = threads[0].fire_tmpl.getComponent!CTexture; + tex_comp.tex = space_invaders.texture;//laser_tex; + tex_comp.coords = vec4(96*px,64*px,8*px,16*px); + scale_comp = threads[0].fire_tmpl.getComponent!CScale; + scale_comp.value = vec2(8,16); + threads[0].fire_location = threads[0].fire_tmpl.getComponent!CLocation; + threads[0].fire_rotation = threads[0].fire_tmpl.getComponent!CRotation; + threads[0].fire_velocity = threads[0].fire_tmpl.getComponent!CVelocity; + threads[0].fire_tmpl.getComponent!(CParticle).life = 300; + *threads[0].fire_tmpl.getComponent!(CAnimation) = CAnimation(fire_frames, 0, 3); + foreach(ref ThreadData thread;threads[1..$]) { thread.laser_tmpl = launcher.manager.allocateTemplate(threads[0].laser_tmpl); thread.laser_location = thread.laser_tmpl.getComponent!CLocation; thread.laser_velocity = thread.laser_tmpl.getComponent!CVelocity; thread.laser_guild = thread.laser_tmpl.getComponent!CGuild; + thread.fire_tmpl = launcher.manager.allocateTemplate(threads[0].fire_tmpl); + thread.fire_location = thread.fire_tmpl.getComponent!CLocation; + thread.fire_rotation = thread.fire_tmpl.getComponent!CRotation; + thread.fire_velocity = thread.fire_tmpl.getComponent!CVelocity; } //laser_location = space_invaders.laser_tmpl.getComponent!CLocation; } @@ -588,13 +732,34 @@ struct LaserShootingSystem { CLaserWeapon* laser = &data.laser[i]; laser.shoot_time += launcher.delta_time; - while(laser.shoot_time > laser_shoot_times[laser.level - 1]) + while(laser.shoot_time > CLaserWeapon.levels[laser.level - 1].reload_time) { - laser.shoot_time -= laser_shoot_times[laser.level - 1]; + laser.shoot_time -= CLaserWeapon.levels[laser.level - 1].reload_time; thread.laser_location.value = data.location[i]; - thread.laser_velocity.value = vec2(randomf()*0.5-0.25,data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); + thread.laser_velocity.value = vec2((randomf()*2-1) * CLaserWeapon.levels[laser.level - 1].dispersion,data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); thread.laser_guild.guild = data.guild[i].guild; + + if(data.velocity) + { + thread.fire_velocity.value = data.velocity[i]; + //thread.laser_velocity.value += data.velocity[i] * 0.5; + } + else thread.fire_velocity.value = vec2(0,0); + launcher.manager.addEntity(thread.laser_tmpl); + + thread.fire_location.value = data.location[i]; + if(data.shoot_direction[i].direction == Direction.down) + { + thread.fire_rotation.value = PI; + thread.fire_location.value.y -= 16; + } + else + { + thread.fire_rotation.value = 0; + thread.fire_location.value.y += 24; + } + launcher.manager.addEntity(thread.fire_tmpl); } } } @@ -604,13 +769,47 @@ struct LaserShootingSystem { CLaserWeapon* laser = &data.laser[i]; laser.shoot_time += launcher.delta_time; - if(laser.shoot_time > laser_shoot_times[laser.level - 1])laser.shoot_time = laser_shoot_times[laser.level - 1]; + if(laser.shoot_time > CLaserWeapon.levels[laser.level - 1].reload_time)laser.shoot_time = CLaserWeapon.levels[laser.level - 1].reload_time; } } } } +struct DampingSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + @readonly CDamping[] damping; + CVelocity[] velocity; + } + + float[10] damp = 0; + + bool onBegin() + { + import core.stdc.math : powf; + foreach(i;0..10) + { + damp[i] = powf((0.98 - cast(float)i * 0.02),launcher.delta_time*0.1); + } + + return true; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; + } + } +} + struct LaserCollisionSystem { mixin ECS.System!32; @@ -689,7 +888,7 @@ struct UpgradeSystem CLaserWeapon* laser = entity.getComponent!CLaserWeapon; if(laser) { - if(laser.level < LaserShootingSystem.laser_shoot_times.length)laser.level++; + if(laser.level < CLaserWeapon.levels.length)laser.level++; } } } @@ -884,9 +1083,15 @@ struct HitPointsSystem { mixin ECS.System; + __gshared vec4[] upgrade_laser_frames = [vec4(96,80,16,16)*px,vec4(112,80,16,16)*px,vec4(128,80,16,16)*px,vec4(144,80,16,16)*px,vec4(128,80,16,16)*px,vec4(112,80,16,16)*px]; + __gshared vec4[] explosion_laser_frames = [vec4(80,128,16,16)*px,vec4(96,128,16,16)*px,vec4(112,128,16,16)*px,vec4(128,128,16,16)*px,vec4(144,128,16,16)*px,vec4(160,128,16,16)*px,vec4(176,128,16,16)*px,vec4(192,128,16,16)*px,vec4(208,128,16,16)*px]; + EntityTemplate* upgrade_tmpl; CLocation* upgrade_location; + EntityTemplate* explosion_tmpl; + CLocation* explosion_location; + struct EntitiesData { CHitPoints[] hp; @@ -894,13 +1099,21 @@ struct HitPointsSystem void onCreate() { - upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id].staticArray); + upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id, CAnimation.component_id, CAnimationLooped.component_id].staticArray); CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; tex_comp.tex = space_invaders.texture;//ship_tex; tex_comp.coords = vec4(0*px,32*px,16*px,16*px); + *upgrade_tmpl.getComponent!CAnimation = CAnimation(upgrade_laser_frames, 0, 1); CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; vel_comp.value = vec2(0,-0.1); upgrade_location = upgrade_tmpl.getComponent!CLocation; + + explosion_tmpl = launcher.manager.allocateTemplate([CDepth.component_id, CParticle.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CAnimation.component_id].staticArray); + explosion_tmpl.getComponent!(CTexture).tex = space_invaders.texture; + *explosion_tmpl.getComponent!CAnimation = CAnimation(explosion_laser_frames, 0, 1.333); + explosion_tmpl.getComponent!(CParticle).life = 600; + *explosion_tmpl.getComponent!CDepth = -1; + explosion_location = explosion_tmpl.getComponent!CLocation; } void onDestroy() @@ -911,9 +1124,9 @@ struct HitPointsSystem void handleEvent(Entity* entity, EDamage event) { CHitPoints* hp = entity.getComponent!CHitPoints; - if(*hp < 0)return; + if(*hp <= 0)return; *hp -= event.damage; - if(*hp < 0) + if(*hp <= 0) { launcher.manager.sendEvent(entity.id, EDeath()); //launcher.manager.removeEntity(entity.id); @@ -927,14 +1140,16 @@ struct HitPointsSystem CEnemy* enemy = entity.getComponent!CEnemy; if(enemy) { - if(randomRange(0, 1000) < 5) + CLocation* location = entity.getComponent!CLocation; + if(location) { - CLocation* location = entity.getComponent!CLocation; - if(location) + if(randomRange(0, 1000) < 5) { *upgrade_location = *location; launcher.manager.addEntity(upgrade_tmpl); } + *explosion_location = *location; + launcher.manager.addEntity(explosion_tmpl); } } launcher.manager.removeEntity(entity.id); @@ -1031,7 +1246,7 @@ struct MovementSystem //@optional const (CLaser)[] laser; const (Entity)[] entities; - @optional CSideMove[] side_move; + //@optional CSideMove[] side_move; } void onUpdate(EntitiesData data) @@ -1044,6 +1259,63 @@ struct MovementSystem } } +struct AnimationSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + CAnimation[] animation; + CTexture[] texture; + @optional @readonly CAnimationLooped[] looped; + } + + void onUpdate(EntitiesData data) + { + float dt = launcher.delta_time * 0.01; + if(data.looped) + { + foreach(i;0..data.length) + { + data.animation[i].time += dt * data.animation[i].speed; + while(data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; + data.texture[i].coords = data.animation[i].frames[cast(int)(data.animation[i].time)]; + } + } + else + { + foreach(i;0..data.length) + { + data.animation[i].time += dt * data.animation[i].speed; + if(data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time = data.animation[i].frames.length - 0.1; + data.texture[i].coords = data.animation[i].frames[cast(int)(data.animation[i].time)]; + } + } + + } +} + +struct ParticleSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + @readonly Entity[] entitiy; + CParticle[] particle; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.particle[i].life -= launcher.delta_time; + if(data.particle[i].life < 0)launcher.manager.removeEntity(data.entitiy[i].id); + } + } +} extern(C) float sqrtf(float x) @nogc nothrow @system; @@ -1063,7 +1335,8 @@ struct InputMovementSystem //read only components can be marked with @readonly attribute or with const expression instead const (CInput)[] input; //components are treated as required by default - CLocation[] locations; + //CLocation[] locations; + CVelocity[] velocity; CTexture[] textures; } @@ -1108,22 +1381,33 @@ struct InputMovementSystem */ void onUpdate(EntitiesData data) { - if(move_vector.x == 0) + /*if(move_vector.x == 0) { foreach(i; 0..data.length) { data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); } //return; - } + }*/ //move every entity using movement vector + //if(move_vector.x != 0 || move_vector.y != 0) foreach(i; 0..data.length) { - data.locations[i].x += move_vector.x * launcher.delta_time * 0.25; - data.locations[i].y += move_vector.y * launcher.delta_time * 0.25; - if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px); - else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); + data.velocity[i] += move_vector * launcher.delta_time * 0.005; + if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5; + else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5; + if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5; + else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5; + //data.locations[i].x += move_vector.x * launcher.delta_time * 0.25; + //data.locations[i].y += move_vector.y * launcher.delta_time * 0.25; + //if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px); + //else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); } + /*else + foreach(i; 0..data.length) + { + data.velocity[i] = vec2(0,0); + }*/ } } @@ -1165,6 +1449,12 @@ void spaceInvadersStart() launcher.manager.registerComponent!CHitPoints; launcher.manager.registerComponent!CHitMark; launcher.manager.registerComponent!CUpgrade; + launcher.manager.registerComponent!CParticle; + launcher.manager.registerComponent!CMaxHitPoints; + launcher.manager.registerComponent!CAnimation; + launcher.manager.registerComponent!CRotation; + launcher.manager.registerComponent!CAnimationLooped; + launcher.manager.registerComponent!CDamping; launcher.manager.registerEvent!EChangeDirection; launcher.manager.registerEvent!EDamage; @@ -1185,6 +1475,9 @@ void spaceInvadersStart() launcher.manager.registerSystem!HitMarkingSystem(-100); launcher.manager.registerSystem!UpgradeCollisionSystem(-70); launcher.manager.registerSystem!UpgradeSystem(-100); + launcher.manager.registerSystem!ParticleSystem(-100); + launcher.manager.registerSystem!AnimationSystem(-100); + launcher.manager.registerSystem!DampingSystem(-101); launcher.manager.endRegister(); @@ -1197,8 +1490,13 @@ void spaceInvadersStart() //launcher.manager.getSystem(CleanSystem.system_id).disable(); { - ushort[11] components = [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexture.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CLaserWeapon.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; - space_invaders.ship_tmpl = launcher.manager.allocateTemplate(components); + space_invaders.ship_tmpl = launcher.manager.allocateTemplate( + [CVelocity.component_id, CHitMark.component_id, CHitPoints.component_id, + CLocation.component_id, CTexture.component_id, CInput.component_id, + CShip.component_id, CScale.component_id, CLaserWeapon.component_id, + CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id, + CDamping.component_id].staticArray + ); CScale* scale_comp = space_invaders.ship_tmpl.getComponent!CScale; scale_comp.value = vec2(48,32); @@ -1208,8 +1506,9 @@ void spaceInvadersStart() CLocation* loc_comp = space_invaders.ship_tmpl.getComponent!CLocation; loc_comp.value = vec2(64,64); CLaserWeapon* weapon = space_invaders.ship_tmpl.getComponent!CLaserWeapon; - weapon.level = 1; + weapon.level = 3; space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; + space_invaders.ship_tmpl.getComponent!CDamping().value = 7; launcher.manager.addEntity(space_invaders.ship_tmpl); } @@ -1273,12 +1572,13 @@ void spaceInvadersStart() EntityTemplate* upgrade_tmpl; { - upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id].staticArray); + upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id, CAnimationLooped.component_id, CAnimation.component_id].staticArray); CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; tex_comp.tex = space_invaders.texture;//ship_tex; tex_comp.coords = vec4(0*px,32*px,16*px,16*px); CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; vel_comp.value = vec2(0,-0.1); + *upgrade_tmpl.getComponent!CAnimation = CAnimation(HitPointsSystem.upgrade_laser_frames, 0, 0.75); } launcher.manager.commit(); @@ -1326,7 +1626,7 @@ void spaceInvadersTool(vec2 position, Tool tool, int size) CLaserWeapon* laser_weapon = tmpl.getComponent!CLaserWeapon; if(laser_weapon) { - laser_weapon.shoot_time = randomf * LaserShootingSystem.laser_shoot_times[laser_weapon.level - 1]; + laser_weapon.shoot_time = randomf * CLaserWeapon.levels[laser_weapon.level - 1].reload_time; } launcher.manager.addEntity(tmpl); } diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index 206364f..95f8aa6 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -535,12 +535,30 @@ struct Renderer verts[item_id*28] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[0] * coss + GfxConfig.meshes[mesh_id].vertices[1] * sinn) * size.x + pos.x) * 8191); verts[item_id*28+1] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[1] * coss - GfxConfig.meshes[mesh_id].vertices[0] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); + verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+4,mem.ptr,6); + + verts[item_id*28+7] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[4] * coss + GfxConfig.meshes[mesh_id].vertices[5] * sinn) * size.x + pos.x) * 8191); verts[item_id*28+8] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[5] * coss - GfxConfig.meshes[mesh_id].vertices[4] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); + verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+11,mem.ptr,6); + + verts[item_id*28+14] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[8] * coss + GfxConfig.meshes[mesh_id].vertices[9] * sinn) * size.x + pos.x) * 8191); verts[item_id*28+15] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[9] * coss - GfxConfig.meshes[mesh_id].vertices[8] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); + verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+18,mem.ptr,6); + + verts[item_id*28+21] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[12] * coss + GfxConfig.meshes[mesh_id].vertices[13] * sinn) * size.x + pos.x) * 8191); verts[item_id*28+22] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[13] * coss - GfxConfig.meshes[mesh_id].vertices[12] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); + verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767); + memcpy(verts.ptr+item_id*28+25,mem.ptr,6); } /*verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); diff --git a/demos/utils/source/ecs_utils/math/vector.d b/demos/utils/source/ecs_utils/math/vector.d index a74b6db..a8f14f8 100644 --- a/demos/utils/source/ecs_utils/math/vector.d +++ b/demos/utils/source/ecs_utils/math/vector.d @@ -2,6 +2,18 @@ module ecs_utils.math.vector; struct vec2 { + this(float v) @nogc nothrow + { + x = v; + y = v; + } + + this(float x, float y) @nogc nothrow + { + this.x = x; + this.y = y; + } + union { struct @@ -75,6 +87,22 @@ struct vec4 float[4] data; } + this(float v) @nogc nothrow + { + x = v; + y = v; + z = v; + w = v; + } + + this(float x, float y, float z, float w) @nogc nothrow + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + vec4 opBinary(string op)(float v) { static if (op == "+") return vec4(x + v, y + v, z + v, w + v); @@ -96,6 +124,18 @@ struct ivec2 } int[2] data; } + + this(int v) @nogc nothrow + { + x = v; + y = v; + } + + this(int x, int y) @nogc nothrow + { + this.x = x; + this.y = y; + } ivec2 opBinary(string op, T)(T v) { @@ -125,4 +165,20 @@ struct ivec4 } int[4] data; } + + this(int v) @nogc nothrow + { + x = v; + y = v; + z = v; + w = v; + } + + this(int x, int y, int z, int w) @nogc nothrow + { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } } \ No newline at end of file From abc4d0c509765bf3d3f66cf1ad466f95bafa81ec Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 22 May 2020 15:40:53 +0200 Subject: [PATCH 24/58] Modified codecov.yml --- codecov.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/codecov.yml b/codecov.yml index f3e0d9b..5672706 100644 --- a/codecov.yml +++ b/codecov.yml @@ -7,6 +7,4 @@ coverage: project: default: threshold: 5 - patch: - default: - threshold: 5 \ No newline at end of file + patch: off \ No newline at end of file From d89df28f85309bdd5ccad7ffed828973b6636c6c Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 22 May 2020 15:41:28 +0200 Subject: [PATCH 25/58] Fixed rendering of rotated entities --- demos/utils/source/ecs_utils/gfx/renderer.d | 28 ++++++++++++--------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index 95f8aa6..1b46eaf 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -472,8 +472,7 @@ struct Renderer { //if(item_id >= MaxObjects)return; //pos += view_pos; - size.x *= view_size.x; - size.y *= view_size.y; + pos.x = pos.x * view_size.x + view_pos.x; pos.y = pos.y * view_size.y + view_pos.y;//*/ @@ -491,6 +490,9 @@ struct Renderer if(angle == 0) { + size.x *= view_size.x; + size.y *= view_size.y; + verts[item_id*28] = cast(short)((GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x) * 8191); verts[item_id*28+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191); verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); @@ -521,8 +523,10 @@ struct Renderer else { //import core.stdc.math; - float sinn = sinf(angle); - float coss = cosf(angle); + float sinx = sinf(angle) * size.x * view_size.y; + float cosx = cosf(angle) * size.x * view_size.x; + float siny = sinf(angle) * size.y * view_size.x; + float cosy = cosf(angle) * size.y * view_size.y; /*batch_vertices[item_id*28] = GfxConfig.meshes[mesh_id].vertices[0] * size.x; batch_vertices[item_id*28+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y; @@ -533,29 +537,29 @@ struct Renderer batch_vertices[item_id*28+12] = GfxConfig.meshes[mesh_id].vertices[12] * size.x; batch_vertices[item_id*28+13] = GfxConfig.meshes[mesh_id].vertices[13] * size.y;*/ - verts[item_id*28] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[0] * coss + GfxConfig.meshes[mesh_id].vertices[1] * sinn) * size.x + pos.x) * 8191); - verts[item_id*28+1] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[1] * coss - GfxConfig.meshes[mesh_id].vertices[0] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[0] * cosx + GfxConfig.meshes[mesh_id].vertices[1] * siny) + pos.x) * 8191); + verts[item_id*28+1] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[1] * cosy - GfxConfig.meshes[mesh_id].vertices[0] * sinx) + pos.y) * 8191); verts[item_id*28+2] = cast(short)((GfxConfig.meshes[mesh_id].vertices[2] * coords.z + coords.x)*32767); verts[item_id*28+3] = cast(short)((GfxConfig.meshes[mesh_id].vertices[3] * coords.w + coords.y)*32767); memcpy(verts.ptr+item_id*28+4,mem.ptr,6); - verts[item_id*28+7] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[4] * coss + GfxConfig.meshes[mesh_id].vertices[5] * sinn) * size.x + pos.x) * 8191); - verts[item_id*28+8] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[5] * coss - GfxConfig.meshes[mesh_id].vertices[4] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+7] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[4] * cosx + GfxConfig.meshes[mesh_id].vertices[5] * siny) + pos.x) * 8191); + verts[item_id*28+8] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[5] * cosy - GfxConfig.meshes[mesh_id].vertices[4] * sinx) + pos.y) * 8191); verts[item_id*28+9] = cast(short)((GfxConfig.meshes[mesh_id].vertices[6] * coords.z + coords.x)*32767); verts[item_id*28+10] = cast(short)((GfxConfig.meshes[mesh_id].vertices[7] * coords.w + coords.y)*32767); memcpy(verts.ptr+item_id*28+11,mem.ptr,6); - verts[item_id*28+14] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[8] * coss + GfxConfig.meshes[mesh_id].vertices[9] * sinn) * size.x + pos.x) * 8191); - verts[item_id*28+15] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[9] * coss - GfxConfig.meshes[mesh_id].vertices[8] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+14] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[8] * cosx + GfxConfig.meshes[mesh_id].vertices[9] * siny) + pos.x) * 8191); + verts[item_id*28+15] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[9] * cosy - GfxConfig.meshes[mesh_id].vertices[8] * sinx) + pos.y) * 8191); verts[item_id*28+16] = cast(short)((GfxConfig.meshes[mesh_id].vertices[10] * coords.z + coords.x)*32767); verts[item_id*28+17] = cast(short)((GfxConfig.meshes[mesh_id].vertices[11] * coords.w + coords.y)*32767); memcpy(verts.ptr+item_id*28+18,mem.ptr,6); - verts[item_id*28+21] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[12] * coss + GfxConfig.meshes[mesh_id].vertices[13] * sinn) * size.x + pos.x) * 8191); - verts[item_id*28+22] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[13] * coss - GfxConfig.meshes[mesh_id].vertices[12] * sinn) * size.y + pos.y) * 8191); + verts[item_id*28+21] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[12] * cosx + GfxConfig.meshes[mesh_id].vertices[13] * siny) + pos.x) * 8191); + verts[item_id*28+22] = cast(short)(((GfxConfig.meshes[mesh_id].vertices[13] * cosy - GfxConfig.meshes[mesh_id].vertices[12] * sinx) + pos.y) * 8191); verts[item_id*28+23] = cast(short)((GfxConfig.meshes[mesh_id].vertices[14] * coords.z + coords.x)*32767); verts[item_id*28+24] = cast(short)((GfxConfig.meshes[mesh_id].vertices[15] * coords.w + coords.y)*32767); memcpy(verts.ptr+item_id*28+25,mem.ptr,6); From 43f8755a39da1d795a01dc916365973ffeef4f26 Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 22 May 2020 15:44:31 +0200 Subject: [PATCH 26/58] Fixed ECS bug related to adding/removing entities inside onAdd/onRemove entity callback Now whole committing process is called in specific order: - UpdateBlocks - ChangeEntities - RemoveEntities - HandleEvents Whole process is repeated until there will be no more changes to commit --- source/bubel/ecs/manager.d | 178 +++++++++++++++++++++++++------------ 1 file changed, 123 insertions(+), 55 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 7b6a983..dc3b9f5 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -2074,10 +2074,10 @@ export struct EntityManager { ThreadData* data = &threads[threadID]; uint num = cast(uint) del_ids.length; - data.change_entities_list.add(0); - data.change_entities_list.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); - data.change_entities_list.add((cast(ubyte*)&num)[0 .. uint.sizeof]); - data.change_entities_list.add((cast(ubyte*) del_ids.ptr)[0 .. num * 2]); + data.changeEntitiesList.add(0); + data.changeEntitiesList.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); + data.changeEntitiesList.add((cast(ubyte*)&num)[0 .. uint.sizeof]); + data.changeEntitiesList.add((cast(ubyte*) del_ids.ptr)[0 .. num * 2]); } private void __removeComponents(EntityID entity_id, ushort[] del_ids) @@ -2349,13 +2349,13 @@ export struct EntityManager } ThreadData* data = &threads[threadID]; - data.change_entities_list.add(cast(ubyte) 1u); - data.change_entities_list.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); - data.change_entities_list.add((cast(ubyte*)&num)[0 .. uint.sizeof]); - data.change_entities_list.add(cast(ubyte[]) new_ids); + data.changeEntitiesList.add(cast(ubyte) 1u); + data.changeEntitiesList.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); + data.changeEntitiesList.add((cast(ubyte*)&num)[0 .. uint.sizeof]); + data.changeEntitiesList.add(cast(ubyte[]) new_ids); static foreach (i, comp; comps) { - data.change_entities_list.add((cast(ubyte*)&comp)[0 .. comp.sizeof]); + data.changeEntitiesList.add((cast(ubyte*)&comp)[0 .. comp.sizeof]); } //__addComponents(entity_id, new_ids, pointers); @@ -2416,7 +2416,7 @@ export struct EntityManager } if (new_index == 1) - threads[threadID].blocks_to_update.add(new_block); + threads[threadID].blockToUpdate.add(new_block); Entity* new_entity = cast(Entity*) start; //add_mutex.lock_nothrow(); @@ -2466,7 +2466,7 @@ export struct EntityManager } if (index == 1) - threads[threadID].blocks_to_update.add(block); + threads[threadID].blockToUpdate.add(block); Entity* entity = cast(Entity*) start; //add_mutex.lock_nothrow(); @@ -2557,7 +2557,7 @@ export struct EntityManager */ export void removeEntity(EntityID id) { - threads[threadID].entities_to_remove.add(id); + threads[threadID].entitesToRemove.add(id); } private void __removeEntity(EntityID id) nothrow @nogc @@ -2646,47 +2646,51 @@ export struct EntityManager return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(m_page_size - 1))); } - private void changeEntities() + private bool changeEntities() { - foreach (ref thread; threads) + bool has_work = false; + //foreach (ref ThreadData thread; threads)thread.swapToChange(); + foreach (ref ThreadData thread; threads) { uint index = 0; - uint len = cast(uint) thread.change_entities_list.length; + uint len = cast(uint) thread.changeEntitiesListPrev.length; + if(len)has_work = true; void*[32] pointers; // = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; while (index < len) { - if (!thread.change_entities_list[index++]) + if (!thread.changeEntitiesListPrev[index++]) { - EntityID id = *cast(EntityID*)&thread.change_entities_list[index]; + EntityID id = *cast(EntityID*)&thread.changeEntitiesListPrev[index]; index += EntityID.sizeof; - uint num = *cast(uint*)&thread.change_entities_list[index]; + uint num = *cast(uint*)&thread.changeEntitiesListPrev[index]; index += uint.sizeof; ushort[] ids; // = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; - ids = (cast(ushort*)&thread.change_entities_list[index])[0 .. num]; + ids = (cast(ushort*)&thread.changeEntitiesListPrev[index])[0 .. num]; index += ushort.sizeof * num; __removeComponents(id, ids); } else { - EntityID id = *cast(EntityID*)&thread.change_entities_list[index]; + EntityID id = *cast(EntityID*)&thread.changeEntitiesListPrev[index]; index += EntityID.sizeof; - uint num = *cast(uint*)&thread.change_entities_list[index]; + uint num = *cast(uint*)&thread.changeEntitiesListPrev[index]; index += uint.sizeof; ushort[] ids; // = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; - ids = (cast(ushort*)&thread.change_entities_list[index])[0 .. num]; + ids = (cast(ushort*)&thread.changeEntitiesListPrev[index])[0 .. num]; index += ushort.sizeof * num; //void*[] pointers = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; foreach (i; 0 .. num) { - pointers[i] = &thread.change_entities_list[index]; + pointers[i] = &thread.changeEntitiesListPrev[index]; index += components[ids[i]].size; } __addComponents(id, ids, pointers[0 .. num]); } } - thread.change_entities_list.clear(); + thread.changeEntitiesListPrev.clear(); } + return has_work; } private void callAddEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow @@ -2767,11 +2771,15 @@ export struct EntityManager (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_change_entity)(data); } - private void updateBlocks() + private bool updateBlocks() { - foreach (ref thread; threads) + bool has_work = false; + //foreach (ref ThreadData thread; threads)thread.swapToUpdate(); + foreach (ref ThreadData thread; threads) { - foreach (block; thread.blocks_to_update) + //thread.swapToUpdate(); + if(thread.blockToUpdatePrev.length)has_work = true; + foreach (block; thread.blockToUpdatePrev) { EntityInfo* info = block.type_info; ushort entities_count = block.entities_count; @@ -2786,30 +2794,35 @@ export struct EntityManager { callAddEntityListeners(info, block, entities_count, block.entities_count); } - } - thread.blocks_to_update.clear(); + thread.blockToUpdatePrev.clear(); } + return has_work; } - private void removeEntities() nothrow @nogc + private bool removeEntities() nothrow @nogc { - foreach (i, ref thread; threads) + bool has_work = false; + //foreach (ref ThreadData thread; threads)thread.swapToRemove(); + foreach (ref ThreadData thread; threads) { - foreach (id; thread.entities_to_remove) + if(thread.entitiesToRemovePrev.length)has_work = true; + foreach (id; thread.entitiesToRemovePrev) { __removeEntity(id); } - thread.entities_to_remove.clear(); + thread.entitiesToRemovePrev.clear(); } + return has_work; } - private void updateEvents() nothrow @nogc + private bool updateEvents() nothrow @nogc { - bool empty = true; - while (1) - { - event_manager.swapCurrent(); + bool has_work = false; + // bool empty = true; + //while (1) + //{ + //event_manager.swapCurrent(); uint current_index; if (event_manager.current_index == 0) current_index = cast(uint) threads.length; @@ -2821,8 +2834,11 @@ export struct EntityManager .. current_index + threads.length]) { EventManager.EventBlock* block = first_block; - if (block) - empty = false; + if (block)has_work = true; + // { + // has_work = true; + // //empty = false; + // } while (block) { EventCallData call_data; @@ -2856,23 +2872,37 @@ export struct EntityManager } } } - if (empty) - break; - empty = true; + // if (empty) + // break; + // empty = true; + //} + return has_work; + } + + private void swapData() nothrow @nogc + { + event_manager.swapCurrent(); + foreach(ref ThreadData thread; threads) + { + thread.swapData(); } } export void commit() { - id_manager.optimize(); - updateBlocks(); - changeEntities(); - - updateEvents(); + bool has_work = true; + while(has_work) + { + swapData(); - id_manager.optimize(); - updateBlocks(); - removeEntities(); + has_work = false; + id_manager.optimize(); + has_work |= updateBlocks(); + has_work |= changeEntities(); + has_work |= removeEntities(); + + has_work |= updateEvents(); + } event_manager.clearEvents(); } @@ -3445,10 +3475,48 @@ export struct EntityManager struct ThreadData { - Vector!EntityID entities_to_remove; - //Vector!ubyte change_entities_list; - SimpleVector change_entities_list; - Vector!(EntitiesBlock*) blocks_to_update; + ref Vector!EntityID entitesToRemove() @nogc nothrow + { + return entities_to_remove[data_index]; + } + + ref SimpleVector changeEntitiesList() @nogc nothrow + { + return change_entities_list[data_index]; + } + + ref Vector!(EntitiesBlock*) blockToUpdate() @nogc nothrow + { + return blocks_to_update[data_index]; + } + + ref Vector!EntityID entitiesToRemovePrev() @nogc nothrow + { + return entities_to_remove[1 - data_index]; + } + + ref SimpleVector changeEntitiesListPrev() @nogc nothrow + { + return change_entities_list[1 - data_index]; + } + + ref Vector!(EntitiesBlock*) blockToUpdatePrev() @nogc nothrow + { + return blocks_to_update[1 - data_index]; + } + + private: + + void swapData() @nogc nothrow + { + data_index = cast(ubyte)(1 - data_index); + } + + Vector!EntityID[2] entities_to_remove; + SimpleVector[2] change_entities_list; + Vector!(EntitiesBlock*)[2] blocks_to_update; + + ubyte data_index = 0; } export struct UpdatePass From bfc0da47e495e7d7e62910d8a95b3c115d01c65b Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 22 May 2020 15:58:35 +0200 Subject: [PATCH 27/58] SpaceShip demo updage -Update sprites texture atlas -added support for separate collider and graphical scale -weapon now can be located on specific sprite relative position -SpaceShip has two lasers which are separate entities -added following parent system -added Boss -parent destroy children after being destroyed -added towers (Tower consist of 3 entities, parent take damage and one is weapon) - added targeting system which rotate entity to target --- demos/assets/textures/atlas.png | Bin 35204 -> 41948 bytes demos/source/demos/space_invaders.d | 869 ++++++++++++++++++++++++---- 2 files changed, 772 insertions(+), 97 deletions(-) diff --git a/demos/assets/textures/atlas.png b/demos/assets/textures/atlas.png index 1e269e513e42c5dc797f568af05816d2562995f0..a799eb7706feddc336f6f1e6e75f780dcbea5467 100644 GIT binary patch literal 41948 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 literal 35204 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

-U`yoWDlL!y69I7g$; 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 space_invaders.map_size.x) + { + if(data.side_move[i].group == -1) + { + if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x; + } + else + { + groups_directions[data.side_move[i].group] = Direction.left; + } + } + } + } else { foreach(i;0..data.length) @@ -1024,38 +1472,9 @@ INFO: Uniform block alig groups_directions[data.side_move[i].group] = Direction.left; } } - //if(data.locations[i].y < 0) data.locations[i].y = 0; - //else if(data.locations[i].y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y; } } } - - /*void handleEvent(Entity* entity, EChangeDirection event) - { - CSideMove* side_move = entity.getComponent!CSideMove; - if(side_move && side_move.group != -1) - { - groups_directions[side_move.group] = event.direction; - return; - } - //Entity* entity = launcher.manager.getEntity(event.entity_id); - CVelocity* velocity = entity.getComponent!CVelocity; - final switch(event.direction) - { - case Direction.up: - if(velocity.value.y > 0)velocity.value.y = -velocity.value.y; - break; - case Direction.down: - if(velocity.value.y < 0)velocity.value.y = -velocity.value.y; - break; - case Direction.left: - if(velocity.value.x > 0)velocity.value.x = -velocity.value.x; - break; - case Direction.right: - if(velocity.value.x < 0)velocity.value.x = -velocity.value.x; - break; - } - }*/ } struct HitMarkingSystem @@ -1101,7 +1520,7 @@ struct HitPointsSystem { upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id, CAnimation.component_id, CAnimationLooped.component_id].staticArray); CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; - tex_comp.tex = space_invaders.texture;//ship_tex; + //tex_comp.tex = space_invaders.texture;//ship_tex; tex_comp.coords = vec4(0*px,32*px,16*px,16*px); *upgrade_tmpl.getComponent!CAnimation = CAnimation(upgrade_laser_frames, 0, 1); CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; @@ -1109,7 +1528,7 @@ struct HitPointsSystem upgrade_location = upgrade_tmpl.getComponent!CLocation; explosion_tmpl = launcher.manager.allocateTemplate([CDepth.component_id, CParticle.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CAnimation.component_id].staticArray); - explosion_tmpl.getComponent!(CTexture).tex = space_invaders.texture; + //explosion_tmpl.getComponent!(CTexture).tex = space_invaders.texture; *explosion_tmpl.getComponent!CAnimation = CAnimation(explosion_laser_frames, 0, 1.333); explosion_tmpl.getComponent!(CParticle).life = 600; *explosion_tmpl.getComponent!CDepth = -1; @@ -1156,6 +1575,47 @@ struct HitPointsSystem } } +struct ChildDestroySystem +{ + mixin ECS.System; + + struct EntitiesData + { + CTargetPartent[] parent; + } + + void handleEvent(Entity* entity, EDeath event) + { + CTargetPartent* parent = entity.getComponent!CTargetPartent; + if(parent) + { + launcher.manager.sendEvent(parent.parent, EDestroyedChild(entity.id)); + } + } +} + +struct PartsDestroySystem +{ + mixin ECS.System; + + struct EntitiesData + { + CInit[] init; + CChildren[] children; + CParts[] parts; + } + + void handleEvent(Entity* entity, EDestroyedChild event) + { + CParts* parts = entity.getComponent!CParts; + parts.count--; + if(parts.count == 0) + { + launcher.manager.addComponents(entity.id, CHitPoints(100), CShootGrid()); + } + } +} + struct ClampPositionSystem { mixin ECS.System!32; @@ -1168,7 +1628,10 @@ struct ClampPositionSystem //components are treated as required by default CLocation[] locations; + @optional @readonly CColliderScale[] collider_scale; + @optional @readonly CScale[] scale; @optional const (CLaser)[] laser; + @optional const (CUpgrade)[] upgrade; //@optional CVelocity[] velocity; //@optional const (CSideMove)[] side_move; } @@ -1177,7 +1640,7 @@ struct ClampPositionSystem void onUpdate(EntitiesData data) { - if(data.laser) + if(data.laser || data.upgrade) { foreach(i;0..data.length) { @@ -1219,6 +1682,28 @@ struct ClampPositionSystem else if(data.locations[i].y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y; } }*/ + else if(data.collider_scale) + { + foreach(i;0..data.length) + { + vec2 hscale = data.collider_scale[i] * 0.5; + if(data.locations[i].x - hscale.x < 0)data.locations[i].x = hscale.x; + else if(data.locations[i].x + hscale.x > space_invaders.map_size.x)data.locations[i].x = space_invaders.map_size.x - hscale.x; + if(data.locations[i].y - hscale.y < 0)data.locations[i].y = hscale.y; + else if(data.locations[i].y + hscale.y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y - hscale.y; + } + } + else if(data.scale) + { + foreach(i;0..data.length) + { + vec2 hscale = data.scale[i] * 0.5; + if(data.locations[i].x - hscale.x < 0)data.locations[i].x = hscale.x; + else if(data.locations[i].x + hscale.x > space_invaders.map_size.x)data.locations[i].x = space_invaders.map_size.x - hscale.x; + if(data.locations[i].y - hscale.y < 0)data.locations[i].y = hscale.y; + else if(data.locations[i].y + hscale.y > space_invaders.map_size.y)data.locations[i].y = space_invaders.map_size.y - hscale.y; + } + } else { foreach(i;0..data.length) @@ -1317,7 +1802,116 @@ struct ParticleSystem } } +struct RotateToTargetSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + int length; + @readonly CTarget[] target; + @readonly CLocation[] location; + CRotation[] rotation; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + Entity* target = launcher.manager.getEntity(data.target[i].target); + if(target) + { + CLocation* target_loc = target.getComponent!CLocation; + if(target_loc) + { + vec2 rel_pos = target_loc.value - data.location[i]; + float length = sqrtf(rel_pos.x*rel_pos.x + rel_pos.y*rel_pos.y); + if(rel_pos.x > 0)data.rotation[i] = acosf(rel_pos.y/length); + else data.rotation[i] = 2 * PI - acosf(rel_pos.y/length); + + } + } + //CLocation* target_loc = + //vec2 rel_pos = d + //data.rotation = 0; + } + } +} + +struct ShipTargetSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + int length; + @readonly CTargetPlayerShip[] target_player; + CTarget[] target; + } + + EntityID player_ship; + + void iterateShips(CShipIterator.EntitiesData data) + { + player_ship = data.entity[0].id; + } + + void onAddEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + data.target[i].target = player_ship; + } + } + + bool onBegin() + { + Entity* ship = launcher.manager.getEntity(player_ship); + if(ship is null) + { + launcher.manager.callEntitiesFunction!CShipIterator(&iterateShips); + ship = launcher.manager.getEntity(player_ship); + if(ship is null)return false; + return true; + } + return false; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.target[i].target = player_ship; + } + } +} + +struct CShipIterator +{ + mixin ECS.System!1; + + struct EntitiesData + { + @readonly Entity[] entity; + @readonly CShip[] ship; + } + + bool onBegin() + { + return false; + } + + void onUpdate(EntitiesData data) + { + + } +} + extern(C) float sqrtf(float x) @nogc nothrow @system; +extern(C) float acosf(float x) @nogc nothrow @system; +extern(C) float sinf(float x) @nogc nothrow @system; +extern(C) float cosf(float x) @nogc nothrow @system; +extern(C) float powf(float x, float y) @nogc nothrow @system; /** *System is responsible for movement of objects with CInput component. @@ -1455,11 +2049,23 @@ void spaceInvadersStart() launcher.manager.registerComponent!CRotation; launcher.manager.registerComponent!CAnimationLooped; launcher.manager.registerComponent!CDamping; + launcher.manager.registerComponent!CTargetPartent; + launcher.manager.registerComponent!CTarget; + launcher.manager.registerComponent!CTargetPlayerShip; + launcher.manager.registerComponent!CChildren; + launcher.manager.registerComponent!CWeaponLocation; + launcher.manager.registerComponent!CInit; + launcher.manager.registerComponent!CBoss; + launcher.manager.registerComponent!CParts; + launcher.manager.registerComponent!CColliderScale; + launcher.manager.registerComponent!CParticleEmitter; + launcher.manager.registerComponent!CParticleEmitterTime; launcher.manager.registerEvent!EChangeDirection; launcher.manager.registerEvent!EDamage; launcher.manager.registerEvent!EUpgrade; launcher.manager.registerEvent!EDeath; + launcher.manager.registerEvent!EDestroyedChild; //launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); @@ -1478,7 +2084,16 @@ void spaceInvadersStart() launcher.manager.registerSystem!ParticleSystem(-100); launcher.manager.registerSystem!AnimationSystem(-100); launcher.manager.registerSystem!DampingSystem(-101); - + launcher.manager.registerSystem!MoveToParentTargetSystem(99); + launcher.manager.registerSystem!ParentOwnerSystem(-101); + launcher.manager.registerSystem!ShipWeaponSystem(-100); + + launcher.manager.registerSystem!RotateToTargetSystem(-100); + launcher.manager.registerSystem!ShipTargetSystem(-110); + launcher.manager.registerSystem!CShipIterator(-100); + launcher.manager.registerSystem!PartsDestroySystem(-80); + launcher.manager.registerSystem!ChildDestroySystem(-110); + launcher.manager.endRegister(); launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System"); @@ -1487,28 +2102,38 @@ void spaceInvadersStart() launcher.gui_manager.addSystem(MovementSystem.system_id,"Movement System"); launcher.gui_manager.addSystem(ClampPositionSystem.system_id,"Clamp Position System"); launcher.gui_manager.addSystem(ChangeDirectionSystem.system_id,"Change Direction System"); + launcher.gui_manager.addSystem(LaserCollisionSystem.system_id,"Draw System"); + launcher.gui_manager.addSystem(ShootGridManager.system_id,"Shoot Grid Manager"); + launcher.gui_manager.addSystem(ShootGridCleaner.system_id,"Shoot Grid Cleaner"); + launcher.gui_manager.addSystem(HitPointsSystem.system_id,"Hit Points System"); + launcher.gui_manager.addSystem(HitMarkingSystem.system_id,"Hit Matking System"); + launcher.gui_manager.addSystem(UpgradeCollisionSystem.system_id,"Upgrade Collision System"); + launcher.gui_manager.addSystem(UpgradeSystem.system_id,"Upgrade System"); + launcher.gui_manager.addSystem(ParticleSystem.system_id,"Particle System"); + launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation System"); + launcher.gui_manager.addSystem(DampingSystem.system_id,"Damping System"); + launcher.gui_manager.addSystem(MoveToParentTargetSystem.system_id,"Move To Target System"); + launcher.gui_manager.addSystem(ParentOwnerSystem.system_id,"Parent Owner System System"); + launcher.gui_manager.addSystem(ShipWeaponSystem.system_id,"Ship Weapon System"); //launcher.manager.getSystem(CleanSystem.system_id).disable(); { space_invaders.ship_tmpl = launcher.manager.allocateTemplate( [CVelocity.component_id, CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexture.component_id, CInput.component_id, - CShip.component_id, CScale.component_id, CLaserWeapon.component_id, + CShip.component_id, CScale.component_id, CColliderScale.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id, - CDamping.component_id].staticArray + CDamping.component_id, CChildren.component_id, CInit.component_id].staticArray ); - - CScale* scale_comp = space_invaders.ship_tmpl.getComponent!CScale; - scale_comp.value = vec2(48,32); - CTexture* tex_comp = space_invaders.ship_tmpl.getComponent!CTexture; - tex_comp.tex = space_invaders.texture;//ship_tex; - tex_comp.coords = vec4(0*px,80*px,48*px,32*px); - CLocation* loc_comp = space_invaders.ship_tmpl.getComponent!CLocation; - loc_comp.value = vec2(64,64); - CLaserWeapon* weapon = space_invaders.ship_tmpl.getComponent!CLaserWeapon; - weapon.level = 3; + //CLaserWeapon* weapon = space_invaders.ship_tmpl.getComponent!CLaserWeapon; + //weapon.level = 3; + space_invaders.ship_tmpl.getComponent!CTexture().coords = vec4(0*px,80*px,48*px,32*px); + space_invaders.ship_tmpl.getComponent!CScale().value = vec2(48,32); + space_invaders.ship_tmpl.getComponent!CLocation().value = vec2(64,64); space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; space_invaders.ship_tmpl.getComponent!CDamping().value = 7; + space_invaders.ship_tmpl.getComponent!CInit().type = CInit.Type.space_ship; + space_invaders.ship_tmpl.getComponent!CColliderScale().value = vec2(26,24); launcher.manager.addEntity(space_invaders.ship_tmpl); } @@ -1518,7 +2143,7 @@ void spaceInvadersStart() space_invaders.laser_tmpl = launcher.manager.allocateTemplate(components); CTexture* tex_comp = space_invaders.laser_tmpl.getComponent!CTexture; - tex_comp.tex = space_invaders.texture;//laser_tex; + //tex_comp.tex = 0;//space_invaders.texture;//laser_tex; tex_comp.coords = vec4(0*px,24*px,2*px,8*px); CScale* scale_comp = space_invaders.laser_tmpl.getComponent!CScale; scale_comp.value = vec2(2,8); @@ -1528,15 +2153,63 @@ void spaceInvadersStart() EntityTemplate* enemy_tmpl; EntityTemplate* grouped_tmpl; + EntityTemplate* tower_tmpl; + EntityTemplate* boss_tmpl; + //EntityTemplate* tower_weapon_tmpl; EntityID enemy_id; EntityID grouped_id; { - ushort[12] components = [CHitMark.component_id, CHitPoints.component_id, CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CLaserWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id]; - space_invaders.enemy_tmpl = launcher.manager.allocateTemplate(components); + boss_tmpl = launcher.manager.allocateTemplate( + [CHitMark.component_id, CParts.component_id, CLocation.component_id, + CTexture.component_id, CScale.component_id, CEnemy.component_id, + CBoss.component_id, CGuild.component_id, CInit.component_id, + CChildren.component_id, CSideMove.component_id, CVelocity.component_id, + CDepth.component_id].staticArray + ); + + CTexture* tex_comp = boss_tmpl.getComponent!CTexture; + //tex_comp.tex = space_invaders.texture;//ship_tex; + tex_comp.coords = vec4(128*px,0*px,96*px,48*px); + CLocation* loc_comp = boss_tmpl.getComponent!CLocation; + loc_comp.value = vec2(64,space_invaders.map_size.y - 16); + boss_tmpl.getComponent!CGuild().guild = 1; + boss_tmpl.getComponent!CInit().type = CInit.Type.boss; + boss_tmpl.getComponent!CScale().value = vec2(96,48); + boss_tmpl.getComponent!CDepth().depth = -1; + boss_tmpl.getComponent!CParts().count = 4; + boss_tmpl.getComponent!CVelocity().value = vec2(0.05,0); + } + + { + tower_tmpl = launcher.manager.allocateTemplate( + [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, + CTexture.component_id, CScale.component_id, CEnemy.component_id, + CShootGrid.component_id, CGuild.component_id, CInit.component_id, + CChildren.component_id].staticArray + ); + + CTexture* tex_comp = tower_tmpl.getComponent!CTexture; + //tex_comp.tex = space_invaders.texture;//ship_tex; + tex_comp.coords = vec4(96*px,96*px,16*px,16*px); + CLocation* loc_comp = tower_tmpl.getComponent!CLocation; + loc_comp.value = vec2(64,space_invaders.map_size.y - 16); + tower_tmpl.getComponent!CGuild().guild = 1; + tower_tmpl.getComponent!CInit().type = CInit.Type.tower; + tower_tmpl.getComponent!CHitPoints().value = 10; + } + + { + space_invaders.enemy_tmpl = launcher.manager.allocateTemplate( + [CWeaponLocation.component_id, CHitMark.component_id, CHitPoints.component_id, + CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, + CTexture.component_id, CScale.component_id, CLaserWeapon.component_id, + CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, + CGuild.component_id].staticArray + ); CTexture* tex_comp = space_invaders.enemy_tmpl.getComponent!CTexture; - tex_comp.tex = space_invaders.texture;//ship_tex; + //tex_comp.tex = space_invaders.texture;//ship_tex; tex_comp.coords = vec4(32*px,32*px,16*px,16*px); CLocation* loc_comp = space_invaders.enemy_tmpl.getComponent!CLocation; loc_comp.value = vec2(64,space_invaders.map_size.y - 16); @@ -1545,6 +2218,7 @@ void spaceInvadersStart() CVelocity* vel_comp = space_invaders.enemy_tmpl.getComponent!CVelocity; vel_comp.value = vec2(0.1,0); space_invaders.enemy_tmpl.getComponent!CGuild().guild = 1; + space_invaders.enemy_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,-15); Entity* current_entity; @@ -1568,13 +2242,13 @@ void spaceInvadersStart() grouped_id = current_entity.id; //grouped_tmpl = launcher.manager.allocateTemplate(current_entity.id); } - + EntityTemplate* upgrade_tmpl; { upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id, CAnimationLooped.component_id, CAnimation.component_id].staticArray); CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; - tex_comp.tex = space_invaders.texture;//ship_tex; + //tex_comp.tex = space_invaders.texture;//ship_tex; tex_comp.coords = vec4(0*px,32*px,16*px,16*px); CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; vel_comp.value = vec2(0,-0.1); @@ -1586,22 +2260,23 @@ void spaceInvadersStart() enemy_tmpl = launcher.manager.allocateTemplate(enemy_id); grouped_tmpl = launcher.manager.allocateTemplate(grouped_id); - launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.ship_tmpl),"Ship"); launcher.gui_manager.addTemplate(enemy_tmpl,"Enemy"); launcher.gui_manager.addTemplate(grouped_tmpl,"Grouped enemy"); + launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.ship_tmpl),"Ship"); launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.laser_tmpl),"Laser"); launcher.gui_manager.addTemplate(upgrade_tmpl,"Upgrade"); - + launcher.gui_manager.addTemplate(tower_tmpl,"Tower"); + launcher.gui_manager.addTemplate(boss_tmpl,"Boss"); } void spaceInvadersEnd() { - launcher.manager.getSystem(DrawSystem.system_id).disable(); + /*launcher.manager.getSystem(DrawSystem.system_id).disable(); launcher.manager.getSystem(InputMovementSystem.system_id).disable(); launcher.manager.getSystem(LaserShootingSystem.system_id).disable(); launcher.manager.getSystem(MovementSystem.system_id).disable(); launcher.manager.getSystem(ClampPositionSystem.system_id).disable(); - launcher.manager.getSystem(ShootGridCleaner.system_id).disable(); + launcher.manager.getSystem(ShootGridCleaner.system_id).disable();*/ //launcher.manager.freeTemplate(space_invaders.enemy_tmpl); Mallocator.dispose(space_invaders); From 233f4abd47a89dccc4f86289dfedebf117f045aa Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 23 May 2020 10:53:36 +0200 Subject: [PATCH 28/58] Added job_id parameter to EntitiesData (index of currently executing job) --- source/bubel/ecs/manager.d | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index dc3b9f5..d5892bb 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -469,7 +469,7 @@ export struct EntityManager foreach (member; __traits(allMembers, Sys.EntitiesData)) { alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); - if (member == "length" || member == "thread_id" + if (member == "length" || member == "thread_id" || member == "job_id" || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) { //continue; @@ -692,7 +692,7 @@ export struct EntityManager foreach (member; __traits(allMembers, Sys.EntitiesData)) { alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); - if (member == "length" || member == "thread_id" + if (member == "length" || member == "thread_id" || member == "job_id" || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) { if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) @@ -809,6 +809,13 @@ export struct EntityManager static assert(MemberType.sizeof > 1, "EntitiesData 'thread_id' member can't be byte or ubyte."); } + else static if (member == "job_id") + { + static assert(isIntegral!(MemberType), + "EntitiesData 'job_id' member must be integral type."); + static assert(MemberType.sizeof > 1, + "EntitiesData 'job_id' member can't be byte or ubyte."); + } else static if (!(isArray!(MemberType))) static assert(0, "EntitiesData members should be arrays of elements!"); } @@ -1009,6 +1016,12 @@ export struct EntityManager .thread_id; } + static if (hasMember!(Sys.EntitiesData, "job_id")) + { + input_data.job_id = cast(typeof(input_data.job_id)) data + .job_id; + } + //s.onUpdate(input_data); (cast(typeof(&__traits(getOverloads, s, "onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data); @@ -1037,6 +1050,12 @@ export struct EntityManager input_data.thread_id = cast(typeof(input_data.thread_id)) data.thread_id; } + static if (hasMember!(Sys.EntitiesData, "job_id")) + { + input_data.job_id = cast(typeof(input_data.job_id)) data + .job_id; + } + (cast(typeof(&__traits(getOverloads, s, "onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data); } @@ -1406,6 +1425,7 @@ export struct EntityManager memcpy(callers.ptr, &tmp_datas[0], CallData.sizeof * tmp_datas.length); tmp_datas.clear(); sys.jobs[job_id].callers = callers; + sys.jobs[job_id].id = job_id; job_id++; } @@ -3415,6 +3435,8 @@ export struct EntityManager ushort end; ///current thread index uint thread_id; + //current job index + uint job_id; } struct ListenerCallData @@ -3428,6 +3450,7 @@ export struct EntityManager struct Job { CallData[] callers; + uint id; export void execute() nothrow @nogc { @@ -3435,6 +3458,7 @@ export struct EntityManager foreach (ref caller; callers) { caller.thread_id = EntityManager.instance.threadID(); + caller.job_id = id; caller.update(); } } From 3d98b0ee5eeac61a71cff1015e4d8cc59a652761 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 23 May 2020 10:55:31 +0200 Subject: [PATCH 29/58] Demos update -fixed critical bug with demos switching -change multithreaded rendering method (now draw order is keeped even witch multithreading there is no popping) -added particle emitter components and systems (WIP) -bullets (laser) now sending EBullet event insead of EDamage which gives possibility to not destroy bullet if shooted entity is already killed --- demos/source/app.d | 6 +- demos/source/demos/simple.d | 6 +- demos/source/demos/space_invaders.d | 319 +++++++++++++++----- demos/utils/source/ecs_utils/gfx/renderer.d | 40 ++- 4 files changed, 284 insertions(+), 87 deletions(-) diff --git a/demos/source/app.d b/demos/source/app.d index 3af24b5..9017f8d 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -103,7 +103,7 @@ struct Launcher manager.update("clean"); manager.end(); - foreach(system; manager.systems) + foreach(ref system; manager.systems) { if(system.id != CountSystem.system_id && system.id != CleanSystem.system_id)system.disable(); } @@ -744,7 +744,9 @@ int main(int argc, char** argv) { import demos.simple; - launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips); + import demos.space_invaders; + launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips); + // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips); } int key_num; diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 1668323..5e82d27 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -53,6 +53,7 @@ struct DrawSystem { uint length; uint thread_id; + uint job_id; @readonly CTexture[] textures; @readonly CLocation[] locations; } @@ -62,10 +63,11 @@ struct DrawSystem if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached foreach(i; 0..data.length) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y*64+data.locations[i].x), 0x80808080, 0, 0, 0, data.thread_id); + launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y), 0x80808080, 0, 0, 0, data.job_id); + // launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0x80808080, 0, 0, 0, data.job_id); //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); } - if(data.thread_id == 0)launcher.renderer.pushData(); + //if(data.thread_id == 0)launcher.renderer.pushData(); } } diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index f61df5c..c047d25 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -196,10 +196,10 @@ struct CLaser { mixin ECS.Component; - float damage = 1.0f; + int damage = 1; } -struct CLaserWeapon +struct CWeapon { mixin ECS.Component; @@ -207,15 +207,25 @@ struct CLaserWeapon { float reload_time; float dispersion; + int damage; } __gshared Level[12] levels = [Level(4000,0),Level(4000,0.1), Level(500,0),Level(350,0),Level(250,0.02),Level(175,0.03),Level(110,0.04), Level(80,0.05),Level(50,0.08),Level(20,0.1),Level(10,0.12),Level(2,0.14)]; + enum Type : ubyte + { + laser, + enemy_laser, + blaster, + canon, + plasma + } - ubyte level = 1; float shoot_time = 0; + Type type; + ubyte level = 1; } struct CWeaponLocation @@ -253,7 +263,7 @@ struct CShootGrid mixin ECS.Component; } -struct CTargetPartent +struct CTargetParent { mixin ECS.Component; @@ -386,6 +396,10 @@ struct CParticleEmitter vec2 range; vec2 time_range; + ///due to multithreading there should be separate template for every thread. + ///It can be array of tempaltes or (like in this demo) simply index of template; + uint tmpl_id; + //EntityTemplate* tmpl; } ///Due to perfarmance reason emitter time and attributes are divided into seprate components. @@ -397,6 +411,11 @@ struct CParticleEmitterTime float time; } +struct CShootWaveUponDeath +{ + mixin ECS.Component; +} + /*####################################################################################################################### ------------------------------------------------ Events ------------------------------------------------------------------ #######################################################################################################################*/ @@ -435,6 +454,20 @@ struct EDamage uint damage = 0; } +struct EBulletHit +{ + mixin ECS.Event; + + this(EntityID id, uint damage) + { + this.id = id; + this.damage = damage; + } + + EntityID id; + uint damage; +} + struct EDestroyedChild { mixin ECS.Event; @@ -652,9 +685,9 @@ struct ShipWeaponSystem CChildren* children = entity.getComponent!CChildren; if(children is null || children.childern.length != 0)return; EntityID[3] weapons; - laser1_tmpl.getComponent!CTargetPartent().parent = entity.id; - laser2_tmpl.getComponent!CTargetPartent().parent = entity.id; - main_weapon_tmpl.getComponent!CTargetPartent().parent = entity.id; + laser1_tmpl.getComponent!CTargetParent().parent = entity.id; + laser2_tmpl.getComponent!CTargetParent().parent = entity.id; + main_weapon_tmpl.getComponent!CTargetParent().parent = entity.id; weapons[0] = launcher.manager.addEntity(laser1_tmpl).id; weapons[1] = launcher.manager.addEntity(laser2_tmpl).id; weapons[2] = launcher.manager.addEntity(main_weapon_tmpl).id; @@ -663,13 +696,13 @@ struct ShipWeaponSystem void create() { - laser1_tmpl = launcher.manager.allocateTemplate([CLaserWeapon.component_id, CLocation.component_id, CShootDirection.component_id, CTargetPartent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); - main_weapon_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CShootDirection.component_id, CTargetPartent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); - *laser1_tmpl.getComponent!CLaserWeapon = CLaserWeapon(3,0.0); - laser1_tmpl.getComponent!CTargetPartent().rel_pos = vec2(10,13); - main_weapon_tmpl.getComponent!CTargetPartent().rel_pos = vec2(0,4); + laser1_tmpl = launcher.manager.allocateTemplate([CWeapon.component_id, CLocation.component_id, CShootDirection.component_id, CTargetParent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); + main_weapon_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CShootDirection.component_id, CTargetParent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); + *laser1_tmpl.getComponent!CWeapon = CWeapon(0,CWeapon.Type.laser,3); + laser1_tmpl.getComponent!CTargetParent().rel_pos = vec2(10,13); + main_weapon_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,4); laser2_tmpl = launcher.manager.allocateTemplate(laser1_tmpl); - laser2_tmpl.getComponent!CTargetPartent().rel_pos = vec2(-10,13); + laser2_tmpl.getComponent!CTargetParent().rel_pos = vec2(-10,13); } ~this() @@ -691,10 +724,10 @@ struct ShipWeaponSystem if(children is null || children.childern.length != 0)return; CDepth* depth = entity.getComponent!CDepth; EntityID[2] weapons; - weapon_tmpl.getComponent!CTargetPartent().parent = entity.id; + weapon_tmpl.getComponent!CTargetParent().parent = entity.id; if(depth)weapon_tmpl.getComponent!CDepth().depth = cast(short)(depth.depth - 1); else weapon_tmpl.getComponent!CDepth().depth = -1; - top_tmpl.getComponent!CTargetPartent().parent = entity.id; + top_tmpl.getComponent!CTargetParent().parent = entity.id; if(depth)top_tmpl.getComponent!CDepth().depth = cast(short)(depth.depth - 2); else top_tmpl.getComponent!CDepth().depth = -2; @@ -706,24 +739,24 @@ struct ShipWeaponSystem void create() { weapon_tmpl = launcher.manager.allocateTemplate( - [CLaserWeapon.component_id, CLocation.component_id, CShootDirection.component_id, - CTargetPartent.component_id, CGuild.component_id, CVelocity.component_id, + [CWeapon.component_id, CLocation.component_id, CShootDirection.component_id, + CTargetParent.component_id, CGuild.component_id, CVelocity.component_id, CAutoShoot.component_id, CTarget.component_id, CTargetPlayerShip.component_id, CRotation.component_id, CScale.component_id, CTexture.component_id, CDepth.component_id, CWeaponLocation.component_id].staticArray); - *weapon_tmpl.getComponent!CLaserWeapon = CLaserWeapon(3,0.0); - weapon_tmpl.getComponent!CTargetPartent().rel_pos = vec2(0,0); + *weapon_tmpl.getComponent!CWeapon = CWeapon(0,CWeapon.Type.laser,3); + weapon_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,0); weapon_tmpl.getComponent!CGuild().guild = 1; weapon_tmpl.getComponent!CScale().value = vec2(4,16); - weapon_tmpl.getComponent!CLaserWeapon().level = 1; + weapon_tmpl.getComponent!CWeapon().level = 1; weapon_tmpl.getComponent!CDepth().depth = -1; weapon_tmpl.getComponent!CTexture().coords = vec4(136,96,4,16)*px; weapon_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,12); top_tmpl = launcher.manager.allocateTemplate( - [CLocation.component_id, CTargetPartent.component_id, CScale.component_id, + [CLocation.component_id, CTargetParent.component_id, CScale.component_id, CTexture.component_id, CDepth.component_id].staticArray); - top_tmpl.getComponent!CTargetPartent().rel_pos = vec2(0,1); + top_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,1); top_tmpl.getComponent!CScale().value = vec2(10,11); top_tmpl.getComponent!CDepth().depth = -2; top_tmpl.getComponent!CTexture().coords = vec4(112,96,10,11)*px; @@ -751,10 +784,10 @@ struct ShipWeaponSystem CParts* parts = entity.getComponent!CParts; if(parts)parts.count = 4; EntityID[4] towers; - tower1_tmpl.getComponent!CTargetPartent().parent = entity.id; - tower2_tmpl.getComponent!CTargetPartent().parent = entity.id; - tower3_tmpl.getComponent!CTargetPartent().parent = entity.id; - tower4_tmpl.getComponent!CTargetPartent().parent = entity.id; + tower1_tmpl.getComponent!CTargetParent().parent = entity.id; + tower2_tmpl.getComponent!CTargetParent().parent = entity.id; + tower3_tmpl.getComponent!CTargetParent().parent = entity.id; + tower4_tmpl.getComponent!CTargetParent().parent = entity.id; towers[0] = launcher.manager.addEntity(tower1_tmpl).id; towers[1] = launcher.manager.addEntity(tower2_tmpl).id; towers[2] = launcher.manager.addEntity(tower3_tmpl).id; @@ -768,7 +801,7 @@ struct ShipWeaponSystem [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, - CChildren.component_id, CDepth.component_id, CTargetPartent.component_id].staticArray + CChildren.component_id, CDepth.component_id, CTargetParent.component_id].staticArray ); CTexture* tex_comp = tower1_tmpl.getComponent!CTexture; @@ -779,17 +812,19 @@ struct ShipWeaponSystem tower1_tmpl.getComponent!CGuild().guild = 1; tower1_tmpl.getComponent!CInit().type = CInit.Type.tower; tower1_tmpl.getComponent!CHitPoints().value = 10; - tower1_tmpl.getComponent!CDepth().depth = -5; - tower1_tmpl.getComponent!CTargetPartent().rel_pos = vec2(-33,2); + tower1_tmpl.getComponent!CDepth().depth = -2; + tower1_tmpl.getComponent!CTargetParent().rel_pos = vec2(-33,2); tower2_tmpl = launcher.manager.allocateTemplate(tower1_tmpl); - tower2_tmpl.getComponent!CTargetPartent().rel_pos = vec2(33,2); + tower2_tmpl.getComponent!CTargetParent().rel_pos = vec2(33,2); tower3_tmpl = launcher.manager.allocateTemplate(tower1_tmpl); - tower3_tmpl.getComponent!CTargetPartent().rel_pos = vec2(-39,-15); + tower3_tmpl.getComponent!CDepth().depth = 0; + tower3_tmpl.getComponent!CTargetParent().rel_pos = vec2(-40,-15); tower4_tmpl = launcher.manager.allocateTemplate(tower1_tmpl); - tower4_tmpl.getComponent!CTargetPartent().rel_pos = vec2(39,-15); + tower4_tmpl.getComponent!CDepth().depth = 0; + tower4_tmpl.getComponent!CTargetParent().rel_pos = vec2(40,-15); } ~this() @@ -810,13 +845,13 @@ struct ShipWeaponSystem ship.create(); tower.create(); boss.create(); - /*ship.laser1_tmpl = launcher.manager.allocateTemplate([CLaserWeapon.component_id, CLocation.component_id, CShootDirection.component_id, CTargetPartent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); - ship.main_weapon_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CShootDirection.component_id, CTargetPartent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); - *ship.laser1_tmpl.getComponent!CLaserWeapon = CLaserWeapon(3,0.0); - ship.laser1_tmpl.getComponent!CTargetPartent().rel_pos = vec2(10,13); - ship.main_weapon_tmpl.getComponent!CTargetPartent().rel_pos = vec2(0,4); + /*ship.laser1_tmpl = launcher.manager.allocateTemplate([CWeapon.component_id, CLocation.component_id, CShootDirection.component_id, CTargetParent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); + ship.main_weapon_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CShootDirection.component_id, CTargetParent.component_id, CGuild.component_id, CVelocity.component_id].staticArray); + *ship.laser1_tmpl.getComponent!CWeapon = CWeapon(3,0.0); + ship.laser1_tmpl.getComponent!CTargetParent().rel_pos = vec2(10,13); + ship.main_weapon_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,4); ship.laser2_tmpl = launcher.manager.allocateTemplate(ship.laser1_tmpl); - ship.laser2_tmpl.getComponent!CTargetPartent().rel_pos = vec2(-10,13);*/ + ship.laser2_tmpl.getComponent!CTargetParent().rel_pos = vec2(-10,13);*/ } void onDestroy() @@ -832,9 +867,9 @@ struct ShipWeaponSystem { /*if(data.children[i].childern.length != 0)continue; EntityID[3] weapons; - laser1_tmpl.getComponent!CTargetPartent().parent = data.entity[i].id; - laser2_tmpl.getComponent!CTargetPartent().parent = data.entity[i].id; - main_weapon_tmpl.getComponent!CTargetPartent().parent = data.entity[i].id; + laser1_tmpl.getComponent!CTargetParent().parent = data.entity[i].id; + laser2_tmpl.getComponent!CTargetParent().parent = data.entity[i].id; + main_weapon_tmpl.getComponent!CTargetParent().parent = data.entity[i].id; weapons[0] = launcher.manager.addEntity(laser1_tmpl).id; weapons[1] = launcher.manager.addEntity(laser2_tmpl).id; weapons[2] = launcher.manager.addEntity(main_weapon_tmpl).id; @@ -859,7 +894,7 @@ struct MoveToParentTargetSystem int length; CLocation[] location; @optional CVelocity[] velocity; - @readonly CTargetPartent[] target; + @readonly CTargetParent[] target; } void onUpdate(EntitiesData data) @@ -908,6 +943,7 @@ struct DrawSystem { uint length; uint thread_id; + uint job_id; @readonly CTexture[] textures; @readonly CLocation[] locations; @readonly CScale[] scale; @@ -925,24 +961,24 @@ struct DrawSystem foreach(i; 0..data.length) { uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; - short depth = cast(short)(data.locations[i].y*8 + data.locations[i].x); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, 0, 0, 0, data.thread_id); + short depth = cast(short)(data.locations[i].y); + launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, 0, 0, 0, data.job_id); } } else if(data.rotation) { foreach(i; 0..data.length) { - short depth = cast(short)(data.locations[i].y*8 + data.locations[i].x); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, data.rotation[i], 0, 0, data.thread_id); + short depth = cast(short)(data.locations[i].y); + launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, data.rotation[i], 0, 0, data.job_id); } } else { foreach(i; 0..data.length) { - short depth = cast(short)(data.locations[i].y*8 + data.locations[i].x); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, 0, 0, 0, data.thread_id); + short depth = cast(short)(data.locations[i].y); + launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, 0, 0, 0, data.job_id); } } } @@ -955,8 +991,8 @@ struct DrawSystem foreach(i; 0..data.length) { uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; - short depth = cast(short)(data.depth[i] * 16 + data.locations[i].y*8 + data.locations[i].x); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, data.rotation[i], 0, 0, data.thread_id); + short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, data.rotation[i], 0, 0, data.job_id); } } else @@ -964,8 +1000,8 @@ struct DrawSystem foreach(i; 0..data.length) { uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; - short depth = cast(short)(data.depth[i] * 16 + data.locations[i].y*8 + data.locations[i].x); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, 0, 0, 0, data.thread_id); + short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, 0, 0, 0, data.job_id); } } } @@ -973,20 +1009,20 @@ struct DrawSystem { foreach(i; 0..data.length) { - short depth = cast(short)(data.depth[i] * 16 + data.locations[i].y*8 + data.locations[i].x); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, data.rotation[i], 0, 0, data.thread_id); + short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, data.rotation[i], 0, 0, data.job_id); } } else { foreach(i; 0..data.length) { - short depth = cast(short)(data.depth[i] * 16 + data.locations[i].y*8 + data.locations[i].x); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, 0, 0, 0, data.thread_id); + short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, 0, 0, 0, data.job_id); } } } - if(data.thread_id == 0)launcher.renderer.pushData(); + //if(data.thread_id == 0)launcher.renderer.pushData(); } } @@ -1029,7 +1065,7 @@ struct LaserShootingSystem uint length; ///variable named "length" contain thread identifier uint thread_id; - CLaserWeapon[] laser; + CWeapon[] laser; @readonly CLocation[] location; @readonly CGuild[] guild; @@ -1134,14 +1170,14 @@ struct LaserShootingSystem { foreach(i;0..data.length) { - CLaserWeapon* laser = &data.laser[i]; + CWeapon* laser = &data.laser[i]; laser.shoot_time += launcher.delta_time; - while(laser.shoot_time > CLaserWeapon.levels[laser.level - 1].reload_time) + while(laser.shoot_time > CWeapon.levels[laser.level - 1].reload_time) { - laser.shoot_time -= CLaserWeapon.levels[laser.level - 1].reload_time; + laser.shoot_time -= CWeapon.levels[laser.level - 1].reload_time; thread.laser_location.value = data.location[i]; - thread.laser_velocity.value = vec2((randomf()*2-1) * CLaserWeapon.levels[laser.level - 1].dispersion,1);//data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); + thread.laser_velocity.value = vec2((randomf()*2-1) * CWeapon.levels[laser.level - 1].dispersion,1);//data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down)thread.laser_velocity.y = -1; thread.laser_guild.guild = data.guild[i].guild; @@ -1197,9 +1233,9 @@ struct LaserShootingSystem { foreach(i;0..data.length) { - CLaserWeapon* laser = &data.laser[i]; + CWeapon* laser = &data.laser[i]; laser.shoot_time += launcher.delta_time; - if(laser.shoot_time > CLaserWeapon.levels[laser.level - 1].reload_time)laser.shoot_time = CLaserWeapon.levels[laser.level - 1].reload_time; + if(laser.shoot_time > CWeapon.levels[laser.level - 1].reload_time)laser.shoot_time = CWeapon.levels[laser.level - 1].reload_time; } } @@ -1262,8 +1298,83 @@ struct LaserCollisionSystem { if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(~(1 << data.guild[i].guild)))) { - launcher.manager.sendEvent(id, EDamage(1)); - launcher.manager.removeEntity(data.entity[i].id); + launcher.manager.sendEvent(id, EBulletHit(data.entity[i].id,1)); + //launcher.manager.removeEntity(data.entity[i].id); + } + } + } +} + +struct ParticleEmittingSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + uint thread_id; + CParticleEmitterTime[] emit_time; + @readonly CLocation[] location; + @readonly CParticleEmitter[] emitter; + + @optional @readonly CVelocity[] velocity; + } + + struct Thread + { + EntityTemplate*[1] templates; + } + + Thread[] threads; + + void onCreate() + { + threads = Mallocator.makeArray!Thread(32); + + threads[0].templates[0] = launcher.manager.allocateTemplate( + [CLocation.component_id, CTexture.component_id, CScale.component_id, + CAnimation.component_id, CParticle.component_id, CRotation.component_id, + CVelocity.component_id, CDamping.component_id].staticArray); + + foreach(ref thread;threads[1 .. $]) + { + thread.templates[0] = launcher.manager.allocateTemplate(threads[0].templates[0]); + } + } + + void onDestroy() + { + foreach(ref thread;threads[1 .. $]) + { + foreach(tmpl; thread.templates) + { + launcher.manager.freeTemplate(tmpl); + } + } + Mallocator.dispose(threads); + } + + void onUpdate(EntitiesData data) + { + Thread* thread = &threads[data.thread_id]; + foreach(i;0..data.length) + { + data.emit_time[i].time -= launcher.delta_time; + while(data.emit_time[i].time < 0) + { + CParticleEmitter* emitter = &data.emitter[i]; + data.emit_time[i].time += emitter.time_range.x + randomf() * emitter.time_range.y; + + EntityTemplate* tmpl = thread.templates[emitter.tmpl_id]; + CLocation* location = tmpl.getComponent!CLocation; + if(location)location.value = data.location[i]; + + if(data.velocity) + { + CVelocity* velocity = tmpl.getComponent!CVelocity; + if(velocity)velocity.value = data.velocity[i]; + } + launcher.manager.addEntity(tmpl); } } } @@ -1314,10 +1425,10 @@ struct UpgradeSystem void handleEvent(Entity* entity, EUpgrade event) { - CLaserWeapon* laser = entity.getComponent!CLaserWeapon; + CWeapon* laser = entity.getComponent!CWeapon; if(laser) { - if(laser.level < CLaserWeapon.levels.length)laser.level++; + if(laser.level < CWeapon.levels.length)laser.level++; } CShip* ship = entity.getComponent!CShip; if(ship) @@ -1553,6 +1664,21 @@ struct HitPointsSystem CHitMark* hit_mark = entity.getComponent!CHitMark; if(hit_mark)hit_mark.value = 127; } + + void handleEvent(Entity* entity, EBulletHit event) + { + CHitPoints* hp = entity.getComponent!CHitPoints; + if(*hp <= 0)return; + launcher.manager.removeEntity(event.id); + *hp -= event.damage; + if(*hp <= 0) + { + launcher.manager.sendEvent(entity.id, EDeath()); + //launcher.manager.removeEntity(entity.id); + } + CHitMark* hit_mark = entity.getComponent!CHitMark; + if(hit_mark)hit_mark.value = 127; + } void handleEvent(Entity* entity, EDeath event) { @@ -1581,12 +1707,12 @@ struct ChildDestroySystem struct EntitiesData { - CTargetPartent[] parent; + CTargetParent[] parent; } void handleEvent(Entity* entity, EDeath event) { - CTargetPartent* parent = entity.getComponent!CTargetPartent; + CTargetParent* parent = entity.getComponent!CTargetParent; if(parent) { launcher.manager.sendEvent(parent.parent, EDestroyedChild(entity.id)); @@ -1605,13 +1731,50 @@ struct PartsDestroySystem CParts[] parts; } + EntityTemplate* flashes_emitter; + + void onCreate() + { + flashes_emitter = launcher.manager.allocateTemplate( + [ + CVelocity.component_id, CLocation.component_id, CParticleEmitter.component_id, + CParticleEmitterTime.component_id, CTargetParent.component_id + ].staticArray); + *flashes_emitter.getComponent!CParticleEmitter() = CParticleEmitter(vec2(0,0), vec2(400,400), 0); + } + void handleEvent(Entity* entity, EDestroyedChild event) { CParts* parts = entity.getComponent!CParts; parts.count--; + + CInit* init = entity.getComponent!CInit; + if(init.type == CInit.Type.boss) + { + CChildren* children = entity.getComponent!CChildren; + foreach(EntityID child; children.childern) + { + if(child == event.id) + { + Entity* child_entity = launcher.manager.getEntity(child); + if(child_entity) + { + CTargetParent* target_parent = child_entity.getComponent!CTargetParent; + + *flashes_emitter.getComponent!CTargetParent() = *target_parent; + launcher.manager.addEntity(flashes_emitter); + } + break; + } + } + } + if(parts.count == 0) { - launcher.manager.addComponents(entity.id, CHitPoints(100), CShootGrid()); + if(init.type == CInit.Type.boss) + { + launcher.manager.addComponents(entity.id, CHitPoints(100), CShootGrid()); + } } } } @@ -2033,7 +2196,7 @@ void spaceInvadersStart() launcher.manager.registerComponent!CScale; launcher.manager.registerComponent!CShootDirection; launcher.manager.registerComponent!CAutoShoot; - launcher.manager.registerComponent!CLaserWeapon; + launcher.manager.registerComponent!CWeapon; launcher.manager.registerComponent!CVelocity; launcher.manager.registerComponent!CLaser; launcher.manager.registerComponent!CSideMove; @@ -2049,7 +2212,7 @@ void spaceInvadersStart() launcher.manager.registerComponent!CRotation; launcher.manager.registerComponent!CAnimationLooped; launcher.manager.registerComponent!CDamping; - launcher.manager.registerComponent!CTargetPartent; + launcher.manager.registerComponent!CTargetParent; launcher.manager.registerComponent!CTarget; launcher.manager.registerComponent!CTargetPlayerShip; launcher.manager.registerComponent!CChildren; @@ -2066,6 +2229,7 @@ void spaceInvadersStart() launcher.manager.registerEvent!EUpgrade; launcher.manager.registerEvent!EDeath; launcher.manager.registerEvent!EDestroyedChild; + launcher.manager.registerEvent!EBulletHit; //launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); @@ -2087,6 +2251,7 @@ void spaceInvadersStart() launcher.manager.registerSystem!MoveToParentTargetSystem(99); launcher.manager.registerSystem!ParentOwnerSystem(-101); launcher.manager.registerSystem!ShipWeaponSystem(-100); + launcher.manager.registerSystem!ParticleEmittingSystem(-100); launcher.manager.registerSystem!RotateToTargetSystem(-100); launcher.manager.registerSystem!ShipTargetSystem(-110); @@ -2125,7 +2290,7 @@ void spaceInvadersStart() CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id, CDamping.component_id, CChildren.component_id, CInit.component_id].staticArray ); - //CLaserWeapon* weapon = space_invaders.ship_tmpl.getComponent!CLaserWeapon; + //CWeapon* weapon = space_invaders.ship_tmpl.getComponent!CWeapon; //weapon.level = 3; space_invaders.ship_tmpl.getComponent!CTexture().coords = vec4(0*px,80*px,48*px,32*px); space_invaders.ship_tmpl.getComponent!CScale().value = vec2(48,32); @@ -2203,7 +2368,7 @@ void spaceInvadersStart() space_invaders.enemy_tmpl = launcher.manager.allocateTemplate( [CWeaponLocation.component_id, CHitMark.component_id, CHitPoints.component_id, CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, - CTexture.component_id, CScale.component_id, CLaserWeapon.component_id, + CTexture.component_id, CScale.component_id, CWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id].staticArray ); @@ -2298,10 +2463,10 @@ void spaceInvadersTool(vec2 position, Tool tool, int size) else if(position.y > 299)position.y = 299; *location = position; } - CLaserWeapon* laser_weapon = tmpl.getComponent!CLaserWeapon; + CWeapon* laser_weapon = tmpl.getComponent!CWeapon; if(laser_weapon) { - laser_weapon.shoot_time = randomf * CLaserWeapon.levels[laser_weapon.level - 1].reload_time; + laser_weapon.shoot_time = randomf * CWeapon.levels[laser_weapon.level - 1].reload_time; } launcher.manager.addEntity(tmpl); } diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index 1b46eaf..fcd6a88 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -114,7 +114,7 @@ struct Renderer void freeBlocks() { - block_stack_mutex.lock(); + /*block_stack_mutex.lock(); render_blocks = 0; current_block = 0; foreach(VertexBlock block; blocks) @@ -124,13 +124,38 @@ struct Renderer blocks.clear; prepared_items=0; draw_list.clear(); - block_stack_mutex.unlock(); + block_stack_mutex.unlock();*/ + foreach(ref Thread thread; threads) + { + foreach(VertexBlock block; thread.blocks) + { + allocator.freeBlock(block.memory); + } + thread.blocks.clear(); + } + render_blocks = 0; + current_block = 0; + prepared_items = 0; + draw_list.clear(); } void pushData() { + foreach(ref Thread thread; threads) + { + foreach(VertexBlock block; thread.blocks) + { + uint items = block.items; + if(items + item_id >= MaxObjects)items = MaxObjects - item_id; + batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr); + batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); + draw_list.add(DrawCall(item_id,items)); + item_id += items; + } + //thread.blocks.clear(); + } //if(!isRemainingBlocks())return; - while(isRemainingBlocks()) + /* while(isRemainingBlocks()) { VertexBlock block = fetchBlock(); uint items = block.items; @@ -139,14 +164,15 @@ struct Renderer batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); draw_list.add(DrawCall(item_id,items)); item_id += items; - } + }*/ } void pushThreadsBlocks() { foreach(i, ref Thread thread; threads) { - pushBlock(thread.block); + //pushBlock(thread.block); + thread.blocks.add(thread.block); thread.block = getBlock(); } } @@ -156,6 +182,7 @@ struct Renderer //Vector!VertexBlock block; RenderData[] render_list; VertexBlock block; + Vector!VertexBlock blocks; } Thread[] threads; @@ -609,7 +636,8 @@ struct Renderer threads[thread_id].block.items++; if(threads[thread_id].block.items >= VertexBlock.max_items) { - pushBlock(threads[thread_id].block); + //pushBlock(threads[thread_id].block); + threads[thread_id].blocks.add(threads[thread_id].block); threads[thread_id].block = getBlock(); } } From 15cd57dbcb10cf2a5e843ba728c3cfde4bd082ca Mon Sep 17 00:00:00 2001 From: Mergul Date: Sun, 24 May 2020 21:57:48 +0200 Subject: [PATCH 30/58] Basic update, multithreading emplate support, fixed -Added possibility to add entity form template + components to replace template data -basic tests for new functionality -small performance improvement for events -added ComponentRef structure which contain data pointer and component ID -now events are called before entities removing --- source/bubel/ecs/block_allocator.d | 1 + source/bubel/ecs/core.d | 5 ++ source/bubel/ecs/entity.d | 11 +++ source/bubel/ecs/events.d | 10 +-- source/bubel/ecs/manager.d | 120 +++++++++++++++++++++++++---- tests/basic.d | 10 ++- 6 files changed, 137 insertions(+), 20 deletions(-) diff --git a/source/bubel/ecs/block_allocator.d b/source/bubel/ecs/block_allocator.d index 740b762..5a2d02c 100644 --- a/source/bubel/ecs/block_allocator.d +++ b/source/bubel/ecs/block_allocator.d @@ -62,6 +62,7 @@ private: { next_block = cast(void*) Mallocator.alignAlloc( block_size * blocks_in_allocation, block_size); + if(next_block is null)assert(0); if(pointers is null)pointers = Mallocator.make!BlockPointers; if(pointers.numberof >= 32) diff --git a/source/bubel/ecs/core.d b/source/bubel/ecs/core.d index 0487665..4a90928 100644 --- a/source/bubel/ecs/core.d +++ b/source/bubel/ecs/core.d @@ -74,6 +74,11 @@ static struct ECS mixin template Component() { __gshared ushort component_id = ushort.max; + + ComponentRef ref_() @nogc nothrow + { + return ComponentRef(&this,component_id); + } } /************************************************************************************************************************ diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index 1e98ff2..f24ddf3 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -114,3 +114,14 @@ export struct EntityTemplate return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]); } } + +/************************************************************************************************************************ +ComponentRef contain component ID and pointer to it. It used to add component data to entity. +*/ +export struct ComponentRef +{ + ///pointer to component + void* ptr; + ///component index + ushort component_id; +} diff --git a/source/bubel/ecs/events.d b/source/bubel/ecs/events.d index 772d5b5..25b864d 100644 --- a/source/bubel/ecs/events.d +++ b/source/bubel/ecs/events.d @@ -40,10 +40,9 @@ package struct EventManager if(block is null) { event_block_alloc_mutex.lock(); - scope (exit) - event_block_alloc_mutex.unlock(); - block = cast(EventBlock*) allocator.getBlock(); + event_block_alloc_mutex.unlock(); + *block = EventBlock(); data.first_blocks[block_id] = block; data.blocks[block_id] = block; @@ -52,10 +51,9 @@ package struct EventManager if(block.count >= data.max_events) { event_block_alloc_mutex.lock(); - scope (exit) - event_block_alloc_mutex.unlock(); - EventBlock* new_block = cast(EventBlock*) allocator.getBlock(); + event_block_alloc_mutex.unlock(); + *new_block = EventBlock(); block.next = new_block; block = new_block; diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index d5892bb..3ac16e8 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -2356,12 +2356,7 @@ export struct EntityManager void addComponents(Components...)(const EntityID entity_id, Components comps) nothrow @nogc { const uint num = Components.length; - //Entity* entity = id_manager.getEntityPointer(entity_id); - //EntitiesBlock* block = getMetaData(entity); - //EntityInfo* info = block.type_info; - /*ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 - .. info.components.length + num];*/ - ushort[num] new_ids; + /*ushort[num] new_ids; static foreach (i, comp; Components) { @@ -2376,9 +2371,39 @@ export struct EntityManager static foreach (i, comp; comps) { data.changeEntitiesList.add((cast(ubyte*)&comp)[0 .. comp.sizeof]); - } + }*/ //__addComponents(entity_id, new_ids, pointers); + + ComponentRef[num] _comps; + static foreach(i, comp; comps) + { + _comps[i] = comp.ref_; + } + addComponents(entity_id, _comps); + + } + + export void addComponents(const EntityID entity_id, ComponentRef[] comps) nothrow @nogc + { + uint num = cast(uint)comps.length; + ThreadData* data = &threads[threadID]; + data.changeEntitiesList.add(cast(ubyte) 1u); + data.changeEntitiesList.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); + data.changeEntitiesList.add((cast(ubyte*)&num)[0 .. uint.sizeof]); + foreach(ref_; comps) + { + data.changeEntitiesList.add((cast(ubyte*)&ref_.component_id)[0 .. ushort.sizeof]); + } + foreach(ref_; comps) + { + data.changeEntitiesList.add((cast(ubyte*)ref_.ptr)[0 .. components[ref_.component_id].size]); + } + /*data.changeEntitiesList.add(cast(ubyte[]) new_ids); + static foreach (i, comp; comps) + { + data.changeEntitiesList.add((cast(ubyte*)&comp)[0 .. comp.sizeof]); + }*/ } /************************************************************************************************************************ @@ -2455,6 +2480,58 @@ export struct EntityManager tmpl = pointer entity template allocated by EntityManager. */ export Entity* addEntity(EntityTemplate* tmpl) + { + /*EntityInfo* info = tmpl.info; + + ushort index = 0; + EntitiesBlock* block; + do + { + block = findBlockWithFreeSpaceMT(info); + index = block.added_count.atomicOp!"+="(1); + } + while (block.entities_count + index > info.max_entities); + + uint id = (block.entities_count + index - 1); //block.added_count); + + void* data_begin = block.dataBegin(); + void* start = data_begin + EntityID.sizeof * id; + + foreach (comp; info.components) + { + memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id, + tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size); + + if (components[comp].create_callback) + { + components[comp].create_callback( + cast(void*) block + info.deltas[comp] + id * components[comp].size); + } + + } + + if (index == 1) + threads[threadID].blockToUpdate.add(block); + + Entity* entity = cast(Entity*) start; + //add_mutex.lock_nothrow(); + entity.id = id_manager.getNewID(); + //add_mutex.unlock_nothrow(); + id_manager.update(*entity); //entity.updateID(); + + return entity;*/ + return addEntity(tmpl, null); + } + + /************************************************************************************************************************ + Add entity to system. Returen pointer is valid only before one from commit(), begin() or end() will be called. To save entity to further + use you should save ID instead of pointer. + + Params: + tmpl = pointer entity template allocated by EntityManager. + replacement = list of components references to used. Memory form list replace data from template inside new entity. Should be used only for data which vary between most entities (like 3D position etc.) + */ + export Entity* addEntity(EntityTemplate* tmpl, ComponentRef[] replacement) { EntityInfo* info = tmpl.info; @@ -2472,17 +2549,34 @@ export struct EntityManager void* data_begin = block.dataBegin(); void* start = data_begin + EntityID.sizeof * id; + foreach (comp; info.components) + { + uint size = components[comp].size; + memcpy(cast(void*) block + info.deltas[comp] + size * id, + tmpl.entity_data.ptr + info.tmpl_deltas[comp], size); + } + + foreach(comp; replacement) + { + if(comp.component_id < info.deltas.length) + { + ushort delta = info.deltas[comp.component_id]; + if(delta != ushort.max) + { + uint size = components[comp.component_id].size; + memcpy(cast(void*) block + delta + size * id, + comp.ptr, size); + } + } + } + foreach (i, comp; info.components) { - memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id, - tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size); - if (components[comp].create_callback) { components[comp].create_callback( cast(void*) block + info.deltas[comp] + id * components[comp].size); } - } if (index == 1) @@ -2916,12 +3010,12 @@ export struct EntityManager swapData(); has_work = false; + has_work |= updateEvents(); + id_manager.optimize(); has_work |= updateBlocks(); has_work |= changeEntities(); has_work |= removeEntities(); - - has_work |= updateEvents(); } event_manager.clearEvents(); } diff --git a/tests/basic.d b/tests/basic.d index 3bf2814..ab9acec 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -153,6 +153,14 @@ unittest assert(entity2.getComponent!CFloat); assert(*entity2.getComponent!CInt == 2); assert(*entity2.getComponent!CFloat == 2.0); + + CInt cint = CInt(10); + CLong clong; + Entity* entity3 = gEM.addEntity(tmpl_, [cint.ref_, clong.ref_].staticArray); + assert(entity3.getComponent!CInt); + assert(entity3.getComponent!CFloat); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); } //allocate templates @@ -1142,7 +1150,7 @@ unittest entity = gEM.getEntity(id); assert(*entity.getComponent!CLong == 66); - assert(*entity.getComponent!CInt == 36); + assert(*entity.getComponent!CInt == 2);//36); //test for multiple event blocks long result = *entity.getComponent!CLong; From 6929f5a7487a1c96239d03c256456f2952dab448 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 27 May 2020 17:03:44 +0200 Subject: [PATCH 31/58] Mostly bugfix update + empty components support and remove EntityID from Event structure -empty components now take no memory, so flag components is now far better -added test for critical bug -fixed critical bug with adding/removing entities form inside events -fixed small bug with TestRunner -improve basic tests -fixed betterC compilation on DMD -remove EntityID form Event structure -added "return" attribute to some functions -moved some code from Tempalte side to actual implementation -fixed bug with EntityTemplate copying -commented out some possibliy unused code -use code formatter --- source/bubel/ecs/atomic.d | 125 +++++++---- source/bubel/ecs/attributes.d | 2 +- source/bubel/ecs/block_allocator.d | 21 +- source/bubel/ecs/core.d | 9 +- source/bubel/ecs/entity.d | 11 +- source/bubel/ecs/events.d | 63 +++--- source/bubel/ecs/hash_map.d | 186 ++++++++++------ source/bubel/ecs/id_manager.d | 54 +++-- source/bubel/ecs/manager.d | 330 ++++++++++++++++------------- source/bubel/ecs/package.d | 2 +- source/bubel/ecs/simple_vector.d | 40 ++-- source/bubel/ecs/std.d | 215 +++++++++++-------- source/bubel/ecs/vector.d | 173 ++++++++++----- tests/basic.d | 153 ++++++++----- tests/bugs.d | 142 +++++++++++++ tests/runner.d | 6 +- 16 files changed, 988 insertions(+), 544 deletions(-) create mode 100644 tests/bugs.d diff --git a/source/bubel/ecs/atomic.d b/source/bubel/ecs/atomic.d index 9155c8f..8ea43df 100644 --- a/source/bubel/ecs/atomic.d +++ b/source/bubel/ecs/atomic.d @@ -9,9 +9,9 @@ License: BSD 3-clause, see LICENSE file in project root folder. */ module bubel.ecs.atomic; -version(Emscripten)version = ECSEmscripten; +version (Emscripten) version = ECSEmscripten; -version(ECSEmscripten) +version (ECSEmscripten) { import std.traits; @@ -24,74 +24,109 @@ version(ECSEmscripten) seq } - extern(C) ubyte emscripten_atomic_cas_u8(void *addr, ubyte oldVal, ubyte newVal) @nogc nothrow pure; - extern(C) ushort emscripten_atomic_cas_u16(void *addr, ushort oldVal, ushort newVal) @nogc nothrow pure; - extern(C) uint emscripten_atomic_cas_u32(void *addr, uint oldVal, uint newVal) @nogc nothrow pure; + extern (C) ubyte emscripten_atomic_cas_u8(void* addr, ubyte oldVal, ubyte newVal) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_cas_u16(void* addr, ushort oldVal, ushort newVal) @nogc nothrow pure; + extern (C) uint emscripten_atomic_cas_u32(void* addr, uint oldVal, uint newVal) @nogc nothrow pure; - extern(C) ubyte emscripten_atomic_load_u8(const void *addr) @nogc nothrow pure; - extern(C) ushort emscripten_atomic_load_u16(const void *addr) @nogc nothrow pure; - extern(C) uint emscripten_atomic_load_u32(const void *addr) @nogc nothrow pure; + extern (C) ubyte emscripten_atomic_load_u8(const void* addr) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_load_u16(const void* addr) @nogc nothrow pure; + extern (C) uint emscripten_atomic_load_u32(const void* addr) @nogc nothrow pure; - extern(C) ubyte emscripten_atomic_store_u8(void *addr, ubyte val) @nogc nothrow pure; - extern(C) ushort emscripten_atomic_store_u16(void *addr, ushort val) @nogc nothrow pure; - extern(C) uint emscripten_atomic_store_u32(void *addr, uint val) @nogc nothrow pure; + extern (C) ubyte emscripten_atomic_store_u8(void* addr, ubyte val) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_store_u16(void* addr, ushort val) @nogc nothrow pure; + extern (C) uint emscripten_atomic_store_u32(void* addr, uint val) @nogc nothrow pure; - extern(C) ubyte emscripten_atomic_add_u8(void *addr, ubyte val) @nogc nothrow pure; - extern(C) ushort emscripten_atomic_add_u16(void *addr, ushort val) @nogc nothrow pure; - extern(C) uint emscripten_atomic_add_u32(void *addr, uint val) @nogc nothrow pure; + extern (C) ubyte emscripten_atomic_add_u8(void* addr, ubyte val) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_add_u16(void* addr, ushort val) @nogc nothrow pure; + extern (C) uint emscripten_atomic_add_u32(void* addr, uint val) @nogc nothrow pure; - extern(C) ubyte emscripten_atomic_sub_u8(void *addr, ubyte val) @nogc nothrow pure; - extern(C) ushort emscripten_atomic_sub_u16(void *addr, ushort val) @nogc nothrow pure; - extern(C) uint emscripten_atomic_sub_u32(void *addr, uint val) @nogc nothrow pure; + extern (C) ubyte emscripten_atomic_sub_u8(void* addr, ubyte val) @nogc nothrow pure; + extern (C) ushort emscripten_atomic_sub_u16(void* addr, ushort val) @nogc nothrow pure; + extern (C) uint emscripten_atomic_sub_u32(void* addr, uint val) @nogc nothrow pure; public pure nothrow @nogc Unqual!T atomicOp(string op, T, V1)(ref shared T val, V1 mod) { - static if(op == "+=") + static if (op == "+=") { - static if(is(T == byte) || is(T == ubyte))return cast(Unqual!T)(emscripten_atomic_add_u8(cast(void*)&val, cast(Unqual!T)mod) + 1); - else static if(is(T == short) || is(T == ushort))return cast(Unqual!T)(emscripten_atomic_add_u16(cast(void*)&val, cast(Unqual!T)mod) + 1); - else static if(is(T == int) || is(T == uint))return cast(Unqual!T)(emscripten_atomic_add_u32(cast(void*)&val, cast(Unqual!T)mod) + 1); - else static assert(0); + static if (is(T == byte) || is(T == ubyte)) + return cast(Unqual!T)(emscripten_atomic_add_u8(cast(void*)&val, + cast(Unqual!T) mod) + 1); + else static if (is(T == short) || is(T == ushort)) + return cast(Unqual!T)(emscripten_atomic_add_u16(cast(void*)&val, + cast(Unqual!T) mod) + 1); + else static if (is(T == int) || is(T == uint)) + return cast(Unqual!T)(emscripten_atomic_add_u32(cast(void*)&val, + cast(Unqual!T) mod) + 1); + else + static assert(0); } - else static if(op == "-=") + else static if (op == "-=") { - static if(is(T == byte) || is(T == ubyte))return cast(Unqual!T)(emscripten_atomic_sub_u8(cast(void*)&val, cast(Unqual!T)mod) - 1); - else static if(is(T == short) || is(T == ushort))return cast(Unqual!T)(emscripten_atomic_sub_u16(cast(void*)&val, cast(Unqual!T)mod) - 1); - else static if(is(T == int) || is(T == uint))return cast(Unqual!T)(emscripten_atomic_sub_u32(cast(void*)&val, cast(Unqual!T)mod) - 1); - else static assert(0); + static if (is(T == byte) || is(T == ubyte)) + return cast(Unqual!T)(emscripten_atomic_sub_u8(cast(void*)&val, + cast(Unqual!T) mod) - 1); + else static if (is(T == short) || is(T == ushort)) + return cast(Unqual!T)(emscripten_atomic_sub_u16(cast(void*)&val, + cast(Unqual!T) mod) - 1); + else static if (is(T == int) || is(T == uint)) + return cast(Unqual!T)(emscripten_atomic_sub_u32(cast(void*)&val, + cast(Unqual!T) mod) - 1); + else + static assert(0); } } - public pure nothrow @nogc @trusted void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref T val, V newval) + public pure nothrow @nogc @trusted void atomicStore(MemoryOrder ms = MemoryOrder.seq, T, V)(ref T val, + V newval) { alias UT = Unqual!T; - static if(is(UT == bool) || is(UT == byte) || is(UT == ubyte))emscripten_atomic_store_u8(cast(void*)&val, cast(UT)newval); - else static if(is(UT == short) || is(UT == ushort))emscripten_atomic_store_u16(cast(void*)&val, cast(UT)newval); - else static if(is(UT == int) || is(UT == uint))emscripten_atomic_store_u32(cast(void*)&val, cast(UT)newval); - else static assert(0); + static if (is(UT == bool) || is(UT == byte) || is(UT == ubyte)) + emscripten_atomic_store_u8(cast(void*)&val, cast(UT) newval); + else static if (is(UT == short) || is(UT == ushort)) + emscripten_atomic_store_u16(cast(void*)&val, cast(UT) newval); + else static if (is(UT == int) || is(UT == uint)) + emscripten_atomic_store_u32(cast(void*)&val, cast(UT) newval); + else + static assert(0); } - public pure nothrow @nogc @trusted T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref const T val) + public pure nothrow @nogc @trusted T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)( + ref const T val) { alias UT = Unqual!T; - static if(is(UT == bool))return emscripten_atomic_load_u8(cast(const void*)&val) != 0; - else static if(is(UT == byte) || is(UT == ubyte))return emscripten_atomic_load_u8(cast(const void*)&val); - else static if(is(UT == short) || is(UT == ushort))return emscripten_atomic_load_u16(cast(const void*)&val); - else static if(is(UT == int) || is(UT == uint))return emscripten_atomic_load_u32(cast(const void*)&val); - else static assert(0); + static if (is(UT == bool)) + return emscripten_atomic_load_u8(cast(const void*)&val) != 0; + else static if (is(UT == byte) || is(UT == ubyte)) + return emscripten_atomic_load_u8(cast(const void*)&val); + else static if (is(UT == short) || is(UT == ushort)) + return emscripten_atomic_load_u16(cast(const void*)&val); + else static if (is(UT == int) || is(UT == uint)) + return emscripten_atomic_load_u32(cast(const void*)&val); + else + static assert(0); } - public pure nothrow @nogc @trusted bool cas(MemoryOrder succ = MemoryOrder.seq, MemoryOrder fail = MemoryOrder.seq, T, V1, V2)(T* here, V1 ifThis, V2 writeThis) + public pure nothrow @nogc @trusted bool cas(MemoryOrder succ = MemoryOrder.seq, + MemoryOrder fail = MemoryOrder.seq, T, V1, V2)(T* here, V1 ifThis, V2 writeThis) { alias UT = Unqual!T; - static if(is(UT == bool))return emscripten_atomic_cas_u8(cast(void*)here, cast(Unqual!T)ifThis, cast(Unqual!T)writeThis) == ifThis; - else static if(is(UT == byte) || is(UT == ubyte))return emscripten_atomic_cas_u8(cast(void*)here, cast(Unqual!T)ifThis, cast(Unqual!T)writeThis) == ifThis; - else static if(is(UT == short) || is(UT == ushort))return emscripten_atomic_cas_u16(cast(void*)here, cast(Unqual!T)ifThis, cast(Unqual!T)writeThis) == ifThis; - else static if(is(UT == int) || is(UT == uint))return emscripten_atomic_cas_u32(cast(void*)here, cast(Unqual!T)ifThis, cast(Unqual!T)writeThis) == ifThis; - else static assert(0); + static if (is(UT == bool)) + return emscripten_atomic_cas_u8(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else static if (is(UT == byte) || is(UT == ubyte)) + return emscripten_atomic_cas_u8(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else static if (is(UT == short) || is(UT == ushort)) + return emscripten_atomic_cas_u16(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else static if (is(UT == int) || is(UT == uint)) + return emscripten_atomic_cas_u32(cast(void*) here, + cast(Unqual!T) ifThis, cast(Unqual!T) writeThis) == ifThis; + else + static assert(0); } } else { public import core.atomic; -} \ No newline at end of file +} diff --git a/source/bubel/ecs/attributes.d b/source/bubel/ecs/attributes.d index 2bc0aec..d094aad 100644 --- a/source/bubel/ecs/attributes.d +++ b/source/bubel/ecs/attributes.d @@ -25,4 +25,4 @@ module bubel.ecs.attributes; ///Used to mark optional components for system. enum optional = "optional"; ///Used to mark readonly components for system. "const" can be used insted. -enum readonly = "readonly"; \ No newline at end of file +enum readonly = "readonly"; diff --git a/source/bubel/ecs/block_allocator.d b/source/bubel/ecs/block_allocator.d index 5a2d02c..d3070c4 100644 --- a/source/bubel/ecs/block_allocator.d +++ b/source/bubel/ecs/block_allocator.d @@ -35,7 +35,7 @@ struct BlockAllocator */ void freeBlock(void* block) nothrow @nogc { - *cast(void**)block = next_block; + *cast(void**) block = next_block; next_block = block; } @@ -44,9 +44,9 @@ struct BlockAllocator */ void freeMemory() nothrow @nogc { - while(pointers) + while (pointers) { - foreach(i;0..pointers.numberof) + foreach (i; 0 .. pointers.numberof) { Mallocator.alignDispose(pointers.blocks[i]); } @@ -60,12 +60,14 @@ private: void allocBlock() nothrow @nogc { - next_block = cast(void*) Mallocator.alignAlloc( - block_size * blocks_in_allocation, block_size); - if(next_block is null)assert(0); + next_block = cast(void*) Mallocator.alignAlloc(block_size * blocks_in_allocation, + block_size); + if (next_block is null) + assert(0); - if(pointers is null)pointers = Mallocator.make!BlockPointers; - if(pointers.numberof >= 32) + if (pointers is null) + pointers = Mallocator.make!BlockPointers; + if (pointers.numberof >= 32) { BlockPointers* new_pointers = Mallocator.make!BlockPointers; new_pointers.next_pointers = pointers; @@ -78,8 +80,7 @@ private: void** pointer = cast(void**)(next_block + i * block_size); *pointer = next_block + (i + 1) * block_size; } - void** pointer = cast(void**)( - next_block + (blocks_in_allocation - 1) * block_size); + void** pointer = cast(void**)(next_block + (blocks_in_allocation - 1) * block_size); *pointer = null; } diff --git a/source/bubel/ecs/core.d b/source/bubel/ecs/core.d index 4a90928..c032d21 100644 --- a/source/bubel/ecs/core.d +++ b/source/bubel/ecs/core.d @@ -75,19 +75,18 @@ static struct ECS { __gshared ushort component_id = ushort.max; - ComponentRef ref_() @nogc nothrow + ComponentRef ref_() @nogc nothrow return { - return ComponentRef(&this,component_id); + return ComponentRef(&this, component_id); } } /************************************************************************************************************************ Mark structure as Event. Should be added on top of structure (before any data). */ - mixin template Event() + mixin template Event() { __gshared ushort event_id = ushort.max; - EntityID entity_id; } /************************************************************************************************************************ @@ -113,4 +112,4 @@ static struct ECS { alias WritableDependencies = T; } -} \ No newline at end of file +} diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index f24ddf3..6a64d50 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -39,11 +39,7 @@ struct Entity if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) return null; - static if (EntityID.sizeof == 8) - uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) >> 3); - else - uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof()); - return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof); + return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof); } bool hasComponent(ushort component_id) @@ -58,10 +54,7 @@ struct Entity { EntityMeta meta; meta.block = gEM.getMetaData(&this); - static if (EntityID.sizeof == 8) - meta.index = cast(ushort)((cast(void*)&this - meta.block.dataBegin()) >> 3); - else - meta.index = cast(ushort)((cast(void*)&this - meta.block.dataBegin()) / EntityID.sizeof()); + meta.index = meta.block.entityIndex(&this); return meta; } } diff --git a/source/bubel/ecs/events.d b/source/bubel/ecs/events.d index 25b864d..64e0c79 100644 --- a/source/bubel/ecs/events.d +++ b/source/bubel/ecs/events.d @@ -20,7 +20,7 @@ package struct EventManager void destroy() nothrow @nogc { - if(event_block_alloc_mutex) + if (event_block_alloc_mutex) { event_block_alloc_mutex.destroy(); Mallocator.dispose(event_block_alloc_mutex); @@ -30,14 +30,14 @@ package struct EventManager export void sendEvent(Ev)(EntityID id, Ev event, uint thread_id = 0) nothrow @nogc { - uint block_id = current_index+thread_id; + uint block_id = current_index + thread_id; EventData* data = &events[Ev.event_id]; EventBlock* block = data.blocks[block_id]; //EntityManager.EventInfo* info = &manager.events[Ev.event_id]; - event.entity_id = id; + //event.entity_id = id; - if(block is null) + if (block is null) { event_block_alloc_mutex.lock(); block = cast(EventBlock*) allocator.getBlock(); @@ -48,35 +48,42 @@ package struct EventManager data.blocks[block_id] = block; } - if(block.count >= data.max_events) + if (block.count >= data.max_events) { event_block_alloc_mutex.lock(); EventBlock* new_block = cast(EventBlock*) allocator.getBlock(); event_block_alloc_mutex.unlock(); - + *new_block = EventBlock(); block.next = new_block; block = new_block; data.blocks[block_id] = block; } - Ev* event_array = cast(Ev*)(cast(void*)block + data.data_offset); - event_array[block.count] = event; + uint size = Ev.sizeof + EntityID.sizeof; + void* ptr = cast(void*) block + data.data_offset + block.count * size; + *cast(EntityID*)ptr = id; + *cast(Ev*)(ptr + EntityID.sizeof) = event; + //Ev* event_array = cast(Ev*)(cast(void*) block + data.data_offset); + //event_array[block.count] = event; block.count++; } void swapCurrent() nothrow @nogc { - uint threads_count = cast(uint)manager.threads.length; - if(current_index == 0)current_index = threads_count; - else current_index = 0; + uint threads_count = cast(uint) manager.threads.length; + if (current_index == 0) + current_index = threads_count; + else + current_index = 0; - foreach(ref event;events) + foreach (ref event; events) { - foreach(ref first_block; event.first_blocks[current_index .. current_index + threads_count]) + foreach (ref first_block; event.first_blocks[current_index + .. current_index + threads_count]) { EventBlock* block = first_block; - while(block) + while (block) { EventBlock* to_dispose = block; block = block.next; @@ -84,7 +91,7 @@ package struct EventManager } first_block = null; } - foreach(ref block; event.blocks[current_index .. current_index + threads_count]) + foreach (ref block; event.blocks[current_index .. current_index + threads_count]) { block = null; } @@ -94,12 +101,12 @@ package struct EventManager void clearEvents() nothrow @nogc { //uint threads_count = cast(uint)manager.threads.length; - foreach(ref event;events) + foreach (ref event; events) { - foreach(ref first_block; event.first_blocks) + foreach (ref first_block; event.first_blocks) { EventBlock* block = first_block; - while(block) + while (block) { EventBlock* to_dispose = block; block = block.next; @@ -107,7 +114,7 @@ package struct EventManager } first_block = null; } - foreach(ref block; event.blocks) + foreach (ref block; event.blocks) { block = null; } @@ -118,23 +125,25 @@ package struct EventManager { disposeData(); events = Mallocator.makeArray!EventData(manager.events.length); - foreach(i,ref event;events) + foreach (i, ref event; events) { - event.blocks = Mallocator.makeArray!(EventBlock*)(threads_count*2); - event.first_blocks = Mallocator.makeArray!(EventBlock*)(threads_count*2); - event.data_offset = EventBlock.sizeof;//manager.events[i]. + event.blocks = Mallocator.makeArray!(EventBlock*)(threads_count * 2); + event.first_blocks = Mallocator.makeArray!(EventBlock*)(threads_count * 2); + event.data_offset = EventBlock.sizeof; //manager.events[i]. manager.alignNum(event.data_offset, manager.events[i].alignment); - event.max_events = cast(ushort)((events_block_size - event.data_offset) / manager.events[i].size); + uint size = manager.events[i].size + EntityID.sizeof; + event.max_events = cast(ushort)( + (events_block_size - event.data_offset) / size); } } private void disposeData() nothrow @nogc { clearEvents(); - if(events) + if (events) { - foreach(ref event;events) + foreach (ref event; events) { Mallocator.dispose(event.blocks); Mallocator.dispose(event.first_blocks); @@ -166,7 +175,7 @@ package struct EventManager ushort max_events; EventBlock*[] blocks; EventBlock*[] first_blocks; - + //EventBlock*[] current_blocks; } diff --git a/source/bubel/ecs/hash_map.d b/source/bubel/ecs/hash_map.d index 1f7a1f8..6ae6a79 100755 --- a/source/bubel/ecs/hash_map.d +++ b/source/bubel/ecs/hash_map.d @@ -11,36 +11,44 @@ private enum HASH_EMPTY = 0; private enum HASH_DELETED = 0x1; private enum HASH_FILLED_MARK = ulong(1) << 8 * ulong.sizeof - 1; -export ulong defaultHashFunc(T)(auto ref T t) nothrow @nogc { - static if (isIntegral!(T)) { +export ulong defaultHashFunc(T)(auto ref T t) nothrow @nogc +{ + static if (isIntegral!(T)) + { return hashInt(t); - } else { - return 0;//hashInt(t.hashOf); // hashOf is not giving proper distribution between H1 and H2 hash parts + } + else + { + return 0; //hashInt(t.hashOf); // hashOf is not giving proper distribution between H1 and H2 hash parts } } // Can turn bad hash function to good one -export ulong hashInt(ulong x) nothrow @nogc @safe { +export ulong hashInt(ulong x) nothrow @nogc @safe +{ x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; x = x ^ (x >> 31); return x; } -struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { +struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) +{ alias Key = KeyPar; alias Value = ValuePar; - nothrow: +nothrow: enum rehashFactor = 0.75; enum size_t getIndexEmptyValue = size_t.max; - static struct KeyVal { + static struct KeyVal + { Key key; Value value; } - static struct Bucket { + static struct Bucket + { ulong hash; KeyVal keyValue; } @@ -49,58 +57,74 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { size_t length; // Used to compute loadFactor size_t markerdDeleted; - export void clear() { + export void clear() + { elements.clear(); length = 0; markerdDeleted = 0; } - export void reset() { + export void reset() + { elements.reset(); length = 0; markerdDeleted = 0; } - export bool isIn(ref Key el) { + export bool isIn(ref Key el) + { return getIndex(el) != getIndexEmptyValue; } - export bool isIn(Key el) { + export bool isIn(Key el) + { return getIndex(el) != getIndexEmptyValue; } - export Value* getPtr()(auto ref Key k) { + export Value* getPtr()(auto ref Key k) + { size_t index = getIndex(k); - if (index == getIndexEmptyValue) { + if (index == getIndexEmptyValue) + { return null; - } else { + } + else + { return &elements[index].keyValue.value; } } - export ref Value get()(auto ref Key k) { + export ref Value get()(auto ref Key k) + { size_t index = getIndex(k); assert(index != getIndexEmptyValue); return elements[index].keyValue.value; } deprecated("Use get with second parameter.") export auto ref Value getDefault()( - auto ref Key k, auto ref Value defaultValue) { + auto ref Key k, auto ref Value defaultValue) + { return get(k, defaultValue); } - export auto ref Value get()(auto ref Key k, auto ref Value defaultValue) { + export auto ref Value get()(auto ref Key k, auto ref Value defaultValue) + { size_t index = getIndex(k); - if (index == getIndexEmptyValue) { + if (index == getIndexEmptyValue) + { return defaultValue; - } else { + } + else + { return elements[index].keyValue.value; } } - export ref Value getInsertDefault()(auto ref Key k, auto ref Value defaultValue) { + export ref Value getInsertDefault()(auto ref Key k, auto ref Value defaultValue) + { size_t index = getIndex(k); - if (index == getIndexEmptyValue) { + if (index == getIndexEmptyValue) + { add(k, defaultValue); } index = getIndex(k); @@ -109,9 +133,11 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { } - export bool tryRemove(Key el) { + export bool tryRemove(Key el) + { size_t index = getIndex(el); - if (index == getIndexEmptyValue) { + if (index == getIndexEmptyValue) + { return false; } length--; @@ -120,28 +146,34 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return true; } - export void remove(Key el) { + export void remove(Key el) + { bool ok = tryRemove(el); assert(ok); } - export ref Value opIndex()(auto ref Key key) { + export ref Value opIndex()(auto ref Key key) + { return get(key); } - export void opIndexAssign()(auto ref Value value, auto ref Key key) { + export void opIndexAssign()(auto ref Value value, auto ref Key key) + { add(key, value); } - export void add()(auto ref Key key, auto ref Value value) { + export void add()(auto ref Key key, auto ref Value value) + { size_t index = getIndex(key); - if (index != getIndexEmptyValue) { + if (index != getIndexEmptyValue) + { elements[index].keyValue.value = value; return; } if (getLoadFactor(length + 1) > rehashFactor - || getLoadFactor(length + markerdDeleted) > rehashFactor) { + || getLoadFactor(length + markerdDeleted) > rehashFactor) + { rehash(); } length++; @@ -150,10 +182,13 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { immutable size_t rotateMask = elements.length - 1; index = hash & rotateMask; // Starting point - while (true) { + while (true) + { Bucket* gr = &elements[index]; - if ((gr.hash & HASH_FILLED_MARK) == 0) { - if (gr.hash == HASH_DELETED) { + if ((gr.hash & HASH_FILLED_MARK) == 0) + { + if (gr.hash == HASH_DELETED) + { markerdDeleted--; } gr.hash = hash; @@ -171,15 +206,18 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { //int numA; //int numB; - export size_t getIndex(Key el) { + export size_t getIndex(Key el) + { return getIndex(el); } - export size_t getIndex(ref Key el) { + export size_t getIndex(ref Key el) + { mixin(doNotInline); immutable size_t groupsLength = elements.length; - if (groupsLength == 0) { + if (groupsLength == 0) + { return getIndexEmptyValue; } @@ -188,13 +226,16 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { size_t index = hash & rotateMask; // Starting point //numA++; - while (true) { + while (true) + { //numB++; Bucket* gr = &elements[index]; - if (gr.hash == hash && gr.keyValue.key == el) { + if (gr.hash == hash && gr.keyValue.key == el) + { return index; } - if (gr.hash == HASH_EMPTY) { + if (gr.hash == HASH_EMPTY) + { return getIndexEmptyValue; } @@ -204,21 +245,26 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { } - export float getLoadFactor(size_t forElementsNum) { - if (elements.length == 0) { + export float getLoadFactor(size_t forElementsNum) + { + if (elements.length == 0) + { return 1; } return cast(float) forElementsNum / (elements.length); } - export void rehash()() { + export void rehash()() + { mixin(doNotInline); // Get all elements Vector!KeyVal allElements; allElements.reserve(elements.length); - foreach (ref Bucket el; elements) { - if ((el.hash & HASH_FILLED_MARK) == 0) { + foreach (ref Bucket el; elements) + { + if ((el.hash & HASH_FILLED_MARK) == 0) + { el.hash = HASH_EMPTY; continue; } @@ -227,12 +273,14 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { } - if (getLoadFactor(length + 1) > rehashFactor) { // Reallocate + if (getLoadFactor(length + 1) > rehashFactor) + { // Reallocate elements.length = (elements.length ? elements.length : 4) << 1; // Power of two, initially 8 elements } // Insert elements - foreach (i, ref el; allElements) { + foreach (i, ref el; allElements) + { add(el.key, el.value); } length = allElements.length; @@ -240,19 +288,29 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { } // foreach support - export int opApply(DG)(scope DG dg) { + export int opApply(DG)(scope DG dg) + { int result; - foreach (ref Bucket gr; elements) { - if ((gr.hash & HASH_FILLED_MARK) == 0) { + foreach (ref Bucket gr; elements) + { + if ((gr.hash & HASH_FILLED_MARK) == 0) + { continue; } - static if (isForeachDelegateWithTypes!(DG, Key)) { + static if (isForeachDelegateWithTypes!(DG, Key)) + { result = dg(gr.keyValue.key); - } else static if (isForeachDelegateWithTypes!(DG, Value)) { + } + else static if (isForeachDelegateWithTypes!(DG, Value)) + { result = dg(gr.keyValue.value); - } else static if (isForeachDelegateWithTypes!(DG, Key, Value)) { + } + else static if (isForeachDelegateWithTypes!(DG, Key, Value)) + { result = dg(gr.keyValue.key, gr.keyValue.value); - } else { + } + else + { static assert(0); } if (result) @@ -263,9 +321,11 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return result; } - export int byKey(scope int delegate(Key k) nothrow dg) { + export int byKey(scope int delegate(Key k) nothrow dg) + { int result; - foreach (ref Key k; this) { + foreach (ref Key k; this) + { result = dg(k); if (result) break; @@ -273,9 +333,11 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return result; } - export int byValue(scope int delegate(ref Value k) nothrow dg) { + export int byValue(scope int delegate(ref Value k) nothrow dg) + { int result; - foreach (ref Value v; this) { + foreach (ref Value v; this) + { result = dg(v); if (result) break; @@ -283,13 +345,15 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return result; } - export int byKeyValue(scope int delegate(ref Key k, ref Value v) nothrow dg) { + export int byKeyValue(scope int delegate(ref Key k, ref Value v) nothrow dg) + { int result; - foreach (ref Key k, ref Value v; this) { + foreach (ref Key k, ref Value v; this) + { result = dg(k, v); if (result) break; } return result; } -} \ No newline at end of file +} diff --git a/source/bubel/ecs/id_manager.d b/source/bubel/ecs/id_manager.d index 4c3a2c3..084a947 100644 --- a/source/bubel/ecs/id_manager.d +++ b/source/bubel/ecs/id_manager.d @@ -18,7 +18,7 @@ struct IDManager pragma(inline, false) EntityID getNewID() nothrow @nogc { int current = m_stack_top.atomicOp!"-="(1) + 1; - if(current < 0) + if (current < 0) { uint add_id = m_last_id.atomicOp!"+="(1) - 1; @@ -29,7 +29,7 @@ struct IDManager if (block_id >= m_blocks_count) { add_mutex.lock(); - if(block_id >= m_blocks_count) + if (block_id >= m_blocks_count) { m_blocks[m_blocks_count].alloc(); m_blocks_count++; @@ -112,9 +112,11 @@ struct IDManager */ export bool isExist(EntityID id) nothrow @nogc { - if(id.id >= m_ids_array.length)return false; + if (id.id >= m_ids_array.length) + return false; Data* data = &m_ids_array[id.id]; - if(data.entity is null)return false; + if (data.entity is null) + return false; return data.counter == id.counter; } @@ -126,7 +128,8 @@ struct IDManager m_ids_array = Mallocator.makeArray!Data(65536); m_free_stack = Mallocator.makeArray!uint(65536); m_blocks = Mallocator.makeArray!Block(64); - foreach(ref block;m_blocks)block = Block(); + foreach (ref block; m_blocks) + block = Block(); m_blocks_count = 1; m_blocks[0].alloc(); @@ -142,20 +145,23 @@ struct IDManager */ void deinitialize() @trusted @nogc nothrow { - if(m_ids_array)Mallocator.dispose(m_ids_array); - if(m_free_stack)Mallocator.dispose(m_free_stack); - if(m_blocks) + if (m_ids_array) + Mallocator.dispose(m_ids_array); + if (m_free_stack) + Mallocator.dispose(m_free_stack); + if (m_blocks) { - foreach(ref block;m_blocks) + foreach (ref block; m_blocks) { - if(block.data)block.free(); + if (block.data) + block.free(); } Mallocator.dispose(m_blocks); } - if(add_mutex) + if (add_mutex) { add_mutex.destroy(); - Mallocator.dispose(add_mutex);//cast(void*)add_mutex); //workaround for compiler bug + Mallocator.dispose(add_mutex); //cast(void*)add_mutex); //workaround for compiler bug add_mutex = null; } } @@ -165,27 +171,31 @@ struct IDManager */ void optimize() nothrow @nogc { - if(m_stack_top < -1)m_stack_top = -1; - if(m_last_id > m_ids_array.length) + if (m_stack_top < -1) + m_stack_top = -1; + if (m_last_id > m_ids_array.length) { - uint begin = cast(uint)m_ids_array.length; + uint begin = cast(uint) m_ids_array.length; Data[] new_array = Mallocator.makeArray!Data(begin + (m_blocks_count << 16)); memcpy(new_array.ptr, m_ids_array.ptr, m_ids_array.length * Data.sizeof); Mallocator.dispose(m_ids_array); m_ids_array = new_array; uint[] new_stack = Mallocator.makeArray!uint(m_ids_array.length); - memcpy(new_stack.ptr,m_free_stack.ptr,m_free_stack.length * uint.sizeof); + memcpy(new_stack.ptr, m_free_stack.ptr, m_free_stack.length * uint.sizeof); Mallocator.dispose(m_free_stack); m_free_stack = new_stack; - foreach(block;m_blocks[0..m_blocks_count-1]) + foreach (block; m_blocks[0 .. m_blocks_count - 1]) { - memcpy(cast(void*)m_ids_array.ptr + begin * Data.sizeof, block.data.ptr, 65536 * Data.sizeof); + memcpy(cast(void*) m_ids_array.ptr + begin * Data.sizeof, + block.data.ptr, 65536 * Data.sizeof); begin += 65536; } - memcpy(cast(void*)m_ids_array.ptr + begin * Data.sizeof, m_blocks[m_blocks_count-1].data.ptr, (m_last_id - begin) * Data.sizeof); - foreach(ref block;m_blocks[1..m_blocks_count])block.free(); + memcpy(cast(void*) m_ids_array.ptr + begin * Data.sizeof, + m_blocks[m_blocks_count - 1].data.ptr, (m_last_id - begin) * Data.sizeof); + foreach (ref block; m_blocks[1 .. m_blocks_count]) + block.free(); m_blocks_count = 1; } } @@ -217,12 +227,12 @@ struct IDManager private: Mutex* add_mutex; - + Data[] m_ids_array = null; uint m_blocks_count = 0; Block[] m_blocks; uint[] m_free_stack = null; - + align(64) shared uint m_last_id = 0; align(64) shared int m_stack_top = -1; } diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 3ac16e8..cf3712d 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -126,7 +126,7 @@ export struct EntityManager //if(info.components)Mallocator.dispose(info.components); Mallocator.dispose(info); - } + } foreach (UpdatePass* pass; passes) { @@ -402,7 +402,7 @@ export struct EntityManager Sys* data_system = cast(Sys*) data.system_pointer; Type* event = cast(Type*) data.event; - data_system.handleEvent(gEM.getEntity(event.entity_id), *event); + data_system.handleEvent(data.entity, *event); } void setEventCallers(Sys)(ref System system) @@ -474,7 +474,7 @@ export struct EntityManager { //continue; } - else + else { string name; static if (isArray!MemberType) @@ -1018,8 +1018,7 @@ export struct EntityManager static if (hasMember!(Sys.EntitiesData, "job_id")) { - input_data.job_id = cast(typeof(input_data.job_id)) data - .job_id; + input_data.job_id = cast(typeof(input_data.job_id)) data.job_id; } //s.onUpdate(input_data); @@ -1052,8 +1051,7 @@ export struct EntityManager static if (hasMember!(Sys.EntitiesData, "job_id")) { - input_data.job_id = cast(typeof(input_data.job_id)) data - .job_id; + input_data.job_id = cast(typeof(input_data.job_id)) data.job_id; } (cast(typeof(&__traits(getOverloads, s, @@ -1146,7 +1144,8 @@ export struct EntityManager foreach (iii, comp_info; components_info.readonlyDeps) { - ushort comp = external_dependencies_map.get(cast(const (char)[]) comp_info.type, ushort.max); + ushort comp = external_dependencies_map.get(cast(const(char)[]) comp_info.type, + ushort.max); version (D_BetterC) assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof @@ -1156,7 +1155,7 @@ export struct EntityManager ~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\"."); system.m_readonly_dependencies[iii] = comp; } - + foreach (iii, comp_info; components_info.writableDeps) { ushort comp = external_dependencies_map.get(cast(char[]) comp_info.type, ushort.max); @@ -1174,7 +1173,9 @@ export struct EntityManager if (sys_id < systems.length) { systems[sys_id].disable(); - if(systems[sys_id].m_destroy)(cast(void function(void*)) systems[sys_id].m_destroy)(systems[sys_id].m_system_pointer); + if (systems[sys_id].m_destroy) + (cast(void function(void*)) systems[sys_id].m_destroy)( + systems[sys_id].m_system_pointer); if (system.m_create) (cast(void function(void*)) system.m_create)(system.m_system_pointer); @@ -1236,7 +1237,7 @@ export struct EntityManager export void registerDependency(const(char)[] name) { - return external_dependencies_map.add(name, cast(ushort)external_dependencies_map.length); + return external_dependencies_map.add(name, cast(ushort) external_dependencies_map.length); } /************************************************************************************************************************ @@ -1274,7 +1275,10 @@ export struct EntityManager info.create_callback = &callCreate; } - info.size = Comp.sizeof; + static if (Comp.sizeof == 1 && Fields!(Comp).length == 0) + info.size = 0; + else + info.size = Comp.sizeof; info.alignment = Comp.alignof; //8; info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof); *cast(Comp*) info.init_data.ptr = Comp.init; // = Comp(); @@ -1340,7 +1344,9 @@ export struct EntityManager "Can't call function with system which hasn't EntitesData structure."); static assert(__traits(hasMember, Sys, "onUpdate"), "Can't call function with system which hasn't onUpdate function callback."); - static assert(is(SetFunctionAttributes!(T,functionLinkage!(s.onUpdate), functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)), "Function must match system update function."); + static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate), + functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)), + "Function must match system update function."); static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type."); System* system = getSystem(Sys.system_id); @@ -1612,6 +1618,8 @@ export struct EntityManager //fill components with default data foreach (comp; info.components) { + if (components[comp].size == 0) + continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], components[comp].init_data.ptr, components[comp].size); } @@ -1621,6 +1629,8 @@ export struct EntityManager ushort index = block.entityIndex(entity); foreach (comp; info.components) { + if (components[comp].size == 0) + continue; memcpy(cast(void*) temp.entity_data.ptr + info.tmpl_deltas[comp], cast(void*) block + info.deltas[comp] + components[comp].size * index, components[comp].size); @@ -1669,6 +1679,8 @@ export struct EntityManager //fill components with default data foreach (comp; info.components) { + if (components[comp].size == 0) + continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], components[comp].init_data.ptr, components[comp].size); } @@ -1736,14 +1748,19 @@ export struct EntityManager //fill components with default data and copy from base template foreach (comp; info.components) { - if (comp < base_tmpl.info.deltas.length && base_tmpl.info.deltas[comp] != ushort.max) //copy data from base component - { + if (comp < base_tmpl.info.tmpl_deltas.length + && base_tmpl.info.tmpl_deltas[comp] != ushort.max) //copy data from base component + { + if (components[comp].size == 0) + continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], base_tmpl.entity_data.ptr + base_tmpl.info.tmpl_deltas[comp], components[comp].size); } else //fill with default data { + if (components[comp].size == 0) + continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], components[comp].init_data.ptr, components[comp].size); } @@ -1833,8 +1850,8 @@ export struct EntityManager } info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(instance.components.length); - info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(instance.components.length, - info); + //info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(instance.components.length); + info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length); foreach (comp; info.components) { @@ -1894,11 +1911,11 @@ export struct EntityManager } add_len++; //move elements after new listener - if(add_len < tmp_add.length) - for (int k = add_len; k > j; k--) - { - tmp_add[k] = tmp_add[k - 1]; - } + if (add_len < tmp_add.length) + for (int k = add_len; k > j; k--) + { + tmp_add[k] = tmp_add[k - 1]; + } //assign listener tmp_add[j] = cast(ushort) i; } @@ -1914,11 +1931,11 @@ export struct EntityManager } rem_len++; //move elements after new listener - if(rem_len < tmp_add.length) - for (int k = rem_len; k > j; k--) - { - tmp_rem[k] = tmp_rem[k - 1]; - } + if (rem_len < tmp_add.length) + for (int k = rem_len; k > j; k--) + { + tmp_rem[k] = tmp_rem[k - 1]; + } //assign listener tmp_rem[j] = cast(ushort) i; } @@ -1934,11 +1951,11 @@ export struct EntityManager } ch_len++; //move elements after new listener - if(ch_len < tmp_add.length) - for (int k = ch_len; k > j; k--) - { - tmp_ch[k] = tmp_ch[k - 1]; - } + if (ch_len < tmp_add.length) + for (int k = ch_len; k > j; k--) + { + tmp_ch[k] = tmp_ch[k - 1]; + } //assign listener tmp_ch[j] = cast(ushort) i; } @@ -2160,6 +2177,8 @@ export struct EntityManager foreach (comp; new_info.components) { uint comp_size = components[comp].size; + if (comp_size == 0) + continue; memcpy(cast(void*) new_block + new_info.deltas[comp] + new_block.entities_count * comp_size, cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size); } @@ -2296,24 +2315,29 @@ export struct EntityManager foreach (id; new_info.components) //ids[0 .. len]) { - void* dst = cast(void*) new_block + new_info.deltas[id] + ( - new_block.entities_count) * components[id].size; uint size = components[id].size; + void* dst = void; + if (size != 0) + dst = cast(void*) new_block + new_info.deltas[id] + (new_block.entities_count) + * size; if (k >= new_ids.length) { - memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); + if (size != 0) + memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); j++; } else if (j >= info.components.length || id == new_ids[k]) { - memcpy(dst, data_pointers[k], size); + if (size != 0) + memcpy(dst, data_pointers[k], size); k++; } else { assert(id != new_ids[0]); - memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); + if (size != 0) + memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); j++; } } @@ -2376,28 +2400,30 @@ export struct EntityManager //__addComponents(entity_id, new_ids, pointers); ComponentRef[num] _comps; - static foreach(i, comp; comps) + static foreach (i, comp; comps) { _comps[i] = comp.ref_; } addComponents(entity_id, _comps); - + } export void addComponents(const EntityID entity_id, ComponentRef[] comps) nothrow @nogc { - uint num = cast(uint)comps.length; + uint num = cast(uint) comps.length; ThreadData* data = &threads[threadID]; data.changeEntitiesList.add(cast(ubyte) 1u); data.changeEntitiesList.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); data.changeEntitiesList.add((cast(ubyte*)&num)[0 .. uint.sizeof]); - foreach(ref_; comps) + foreach (ref_; comps) { data.changeEntitiesList.add((cast(ubyte*)&ref_.component_id)[0 .. ushort.sizeof]); } - foreach(ref_; comps) + foreach (ref_; comps) { - data.changeEntitiesList.add((cast(ubyte*)ref_.ptr)[0 .. components[ref_.component_id].size]); + if (components[ref_.component_id].size != 0) + data.changeEntitiesList.add( + (cast(ubyte*) ref_.ptr)[0 .. components[ref_.component_id].size]); } /*data.changeEntitiesList.add(cast(ubyte[]) new_ids); static foreach (i, comp; comps) @@ -2449,14 +2475,15 @@ export struct EntityManager foreach (i, comp; info.components) { - memcpy(cast(void*) new_block + info.deltas[comp] + components[comp].size * new_id, - cast(void*) block + info.deltas[comp] + components[comp].size * index, - components[comp].size); + ushort size = components[comp].size; + if (size != 0) + memcpy(cast(void*) new_block + info.deltas[comp] + size * new_id, + cast(void*) block + info.deltas[comp] + size * index, size); if (components[comp].create_callback) { - components[comp].create_callback(cast( - void*) block + info.deltas[comp] + new_id * components[comp].size); + components[comp].create_callback( + cast(void*) block + info.deltas[comp] + new_id * size); } } @@ -2552,20 +2579,21 @@ export struct EntityManager foreach (comp; info.components) { uint size = components[comp].size; - memcpy(cast(void*) block + info.deltas[comp] + size * id, - tmpl.entity_data.ptr + info.tmpl_deltas[comp], size); + if (size != 0) + memcpy(cast(void*) block + info.deltas[comp] + size * id, + tmpl.entity_data.ptr + info.tmpl_deltas[comp], size); } - foreach(comp; replacement) + foreach (comp; replacement) { - if(comp.component_id < info.deltas.length) + if (comp.component_id < info.deltas.length) { ushort delta = info.deltas[comp.component_id]; - if(delta != ushort.max) + if (delta != ushort.max) { uint size = components[comp.component_id].size; - memcpy(cast(void*) block + delta + size * id, - comp.ptr, size); + if (size != 0) + memcpy(cast(void*) block + delta + size * id, comp.ptr, size); } } } @@ -2678,8 +2706,10 @@ export struct EntityManager { //get entity and block meta data pointers Entity* entity = id_manager.getEntityPointer(id); + if (entity is null) return; //return if entity doesn't exist + EntitiesBlock* block = getMetaData(entity); EntityInfo* info = block.type_info; @@ -2700,6 +2730,9 @@ export struct EntityManager { EntityInfo* info = block.type_info; + if (info.last_block.added_count) + updateBlock(info.last_block); + info.last_block.entities_count--; uint pos = block.entityIndex(entity); @@ -2720,9 +2753,11 @@ export struct EntityManager { foreach (comp; info.components) { + uint size = components[comp].size; + if (size == 0) + continue; void* src = cast(void*) info.last_block + info.deltas[comp]; void* dst = cast(void*) block + info.deltas[comp]; - uint size = components[comp].size; memcpy(dst + pos * size, src + info.last_block.entities_count * size, size); } @@ -2768,7 +2803,8 @@ export struct EntityManager { uint index = 0; uint len = cast(uint) thread.changeEntitiesListPrev.length; - if(len)has_work = true; + if (len) + has_work = true; void*[32] pointers; // = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; while (index < len) { @@ -2798,7 +2834,7 @@ export struct EntityManager pointers[i] = &thread.changeEntitiesListPrev[index]; index += components[ids[i]].size; } - + __addComponents(id, ids, pointers[0 .. num]); } } @@ -2885,6 +2921,23 @@ export struct EntityManager (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_change_entity)(data); } + private void updateBlock(EntitiesBlock* block) @nogc nothrow + { + EntityInfo* info = block.type_info; + ushort entities_count = block.entities_count; + block.entities_count += block.added_count; + if (block.entities_count > block.type_info.max_entities) + { + block.entities_count = block.type_info.max_entities; + } + block.added_count.atomicStore(cast(ushort) 0); + + if (info.add_listeners) + { + callAddEntityListeners(info, block, entities_count, block.entities_count); + } + } + private bool updateBlocks() { bool has_work = false; @@ -2892,22 +2945,11 @@ export struct EntityManager foreach (ref ThreadData thread; threads) { //thread.swapToUpdate(); - if(thread.blockToUpdatePrev.length)has_work = true; + if (thread.blockToUpdatePrev.length) + has_work = true; foreach (block; thread.blockToUpdatePrev) { - EntityInfo* info = block.type_info; - ushort entities_count = block.entities_count; - block.entities_count += block.added_count; - if (block.entities_count > block.type_info.max_entities) - { - block.entities_count = block.type_info.max_entities; - } - block.added_count.atomicStore(cast(ushort) 0); - - if (info.add_listeners) - { - callAddEntityListeners(info, block, entities_count, block.entities_count); - } + updateBlock(block); } thread.blockToUpdatePrev.clear(); } @@ -2920,7 +2962,8 @@ export struct EntityManager //foreach (ref ThreadData thread; threads)thread.swapToRemove(); foreach (ref ThreadData thread; threads) { - if(thread.entitiesToRemovePrev.length)has_work = true; + if (thread.entitiesToRemovePrev.length) + has_work = true; foreach (id; thread.entitiesToRemovePrev) { __removeEntity(id); @@ -2936,59 +2979,60 @@ export struct EntityManager // bool empty = true; //while (1) //{ - //event_manager.swapCurrent(); - uint current_index; - if (event_manager.current_index == 0) - current_index = cast(uint) threads.length; - else - current_index = 0; - foreach (i, event; event_manager.events) + //event_manager.swapCurrent(); + uint current_index; + if (event_manager.current_index == 0) + current_index = cast(uint) threads.length; + else + current_index = 0; + foreach (i, event; event_manager.events) + { + foreach (first_block; event.first_blocks[current_index .. current_index + threads + .length]) { - foreach (first_block; event.first_blocks[current_index - .. current_index + threads.length]) + EventManager.EventBlock* block = first_block; + if (block) + has_work = true; + // { + // has_work = true; + // //empty = false; + // } + while (block) { - EventManager.EventBlock* block = first_block; - if (block)has_work = true; - // { - // has_work = true; - // //empty = false; - // } - while (block) + EventCallData call_data; + void* event_pointer = cast(void*) block + event.data_offset; + foreach (j; 0 .. block.count) { - EventCallData call_data; - void* event_pointer = cast(void*) block + event.data_offset; - foreach (j; 0 .. block.count) + call_data.event = event_pointer + EntityID.sizeof; + EntityID entity_id = *cast(EntityID*)(event_pointer); + Entity* entity = id_manager.getEntityPointer(entity_id); + if (entity) { - call_data.event = event_pointer; - EntityID entity_id = *cast(EntityID*) event_pointer; - Entity* entity = id_manager.getEntityPointer(entity_id); - if (entity) - { - call_data.block = getMetaData(entity); - call_data.id = call_data.block.entityIndex(entity); + call_data.block = getMetaData(entity); + call_data.id = call_data.block.entityIndex(entity); + call_data.entity = entity; - foreach (caller; events[i].callers) - { - if ( - call_data.block.type_info.systems[caller.system.m_id] - == false) - continue; - call_data.system_pointer = caller.system.m_system_pointer; - (cast(void function( - ref EventCallData) nothrow @nogc) caller.callback)( - call_data); - } + foreach (caller; events[i].callers) + { + if (call_data.block.type_info.systems[caller.system.m_id] == false + || !caller.system.enabled || !caller.system.willExecute) + continue; + call_data.system_pointer = caller.system.m_system_pointer; + (cast(void function(ref EventCallData) nothrow @nogc) caller + .callback)(call_data); } - if(events[i].destroy_callback)events[i].destroy_callback(event_pointer); - event_pointer += events[i].size; } - block = block.next; + if (events[i].destroy_callback) + events[i].destroy_callback(event_pointer); + event_pointer += events[i].size + EntityID.sizeof; } + block = block.next; } } - // if (empty) - // break; - // empty = true; + } + // if (empty) + // break; + // empty = true; //} return has_work; } @@ -2996,7 +3040,7 @@ export struct EntityManager private void swapData() nothrow @nogc { event_manager.swapCurrent(); - foreach(ref ThreadData thread; threads) + foreach (ref ThreadData thread; threads) { thread.swapData(); } @@ -3005,13 +3049,13 @@ export struct EntityManager export void commit() { bool has_work = true; - while(has_work) - { + while (has_work) + { swapData(); has_work = false; has_work |= updateEvents(); - + id_manager.optimize(); has_work |= updateBlocks(); has_work |= changeEntities(); @@ -3222,14 +3266,15 @@ export struct EntityManager } } - const (UpdatePass)* getPass(const (char)[] name) + const(UpdatePass)* getPass(const(char)[] name) { ushort id = getPassID(name); - if(id == ushort.max)return null; + if (id == ushort.max) + return null; return passes[id]; } - ushort getPassID(const (char)[] name) + ushort getPassID(const(char)[] name) { return passes_map.get(name, ushort.max); } @@ -3267,6 +3312,7 @@ export struct EntityManager EntitiesBlock* block; void* system_pointer; void* event; + Entity* entity; ushort id; } @@ -3357,9 +3403,9 @@ export struct EntityManager return new_info; } - EntityInfo* getNewInfoRemove(ushort id) + EntityInfo* getNewInfoRemove(ushort id) return { - if (comp_rem_info.length <= id) + /*if (comp_rem_info.length <= id) { EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)( instance.components.length, &this); @@ -3371,7 +3417,7 @@ export struct EntityManager Mallocator.dispose(comp_rem_info); } comp_rem_info = new_infos; - } + }*/ if (comp_rem_info[id]) return comp_rem_info[id]; @@ -3386,8 +3432,9 @@ export struct EntityManager ids[len++] = comp; } } - if (len == components.length) - return &this; + assert(len != components.length); + //if (len == components.length) + // return &this; assert(len == components.length - 1); @@ -3455,23 +3502,14 @@ export struct EntityManager */ struct EntitiesBlock { - ///return distance (in bytes) from begin of block to data - ///TODO: probably to remove. It's used by old code if I remeber correctly. - /*export uint dataDelta() nothrow @nogc pure - { - ushort dif = EntitiesBlock.sizeof; - alignNum(dif, type_info.alignment); - return dif; - }*/ - ///return pointer to first element in block - export void* dataBegin() nothrow @nogc pure + export void* dataBegin() nothrow @nogc pure return { ushort dif = EntitiesBlock.sizeof; return cast(void*)&this + dif; } - export ushort entityIndex(Entity* entity) nothrow @nogc pure + export ushort entityIndex(const(Entity)* entity) nothrow @nogc pure { static if (EntityID.sizeof == 8) return cast(ushort)((cast(void*) entity - dataBegin()) >> 3); @@ -3593,32 +3631,32 @@ export struct EntityManager struct ThreadData { - ref Vector!EntityID entitesToRemove() @nogc nothrow + ref Vector!EntityID entitesToRemove() @nogc nothrow return { return entities_to_remove[data_index]; } - ref SimpleVector changeEntitiesList() @nogc nothrow + ref SimpleVector changeEntitiesList() @nogc nothrow return { return change_entities_list[data_index]; } - ref Vector!(EntitiesBlock*) blockToUpdate() @nogc nothrow + ref Vector!(EntitiesBlock*) blockToUpdate() @nogc nothrow return { return blocks_to_update[data_index]; } - - ref Vector!EntityID entitiesToRemovePrev() @nogc nothrow + + ref Vector!EntityID entitiesToRemovePrev() @nogc nothrow return { return entities_to_remove[1 - data_index]; } - ref SimpleVector changeEntitiesListPrev() @nogc nothrow + ref SimpleVector changeEntitiesListPrev() @nogc nothrow return { return change_entities_list[1 - data_index]; } - ref Vector!(EntitiesBlock*) blockToUpdatePrev() @nogc nothrow + ref Vector!(EntitiesBlock*) blockToUpdatePrev() @nogc nothrow return { return blocks_to_update[1 - data_index]; } diff --git a/source/bubel/ecs/package.d b/source/bubel/ecs/package.d index ee3f62b..51da325 100644 --- a/source/bubel/ecs/package.d +++ b/source/bubel/ecs/package.d @@ -7,4 +7,4 @@ public import bubel.ecs.system; import bubel.ecs.events; import bubel.ecs.id_manager; -import bubel.ecs.std; \ No newline at end of file +import bubel.ecs.std; diff --git a/source/bubel/ecs/simple_vector.d b/source/bubel/ecs/simple_vector.d index 1de026e..bb4b610 100644 --- a/source/bubel/ecs/simple_vector.d +++ b/source/bubel/ecs/simple_vector.d @@ -16,10 +16,12 @@ struct SimpleVector ///Add element to vector void add(ubyte el) nothrow @nogc { - while(used >= data.length) + while (used >= data.length) { - if(data is null)data = Mallocator.makeArray!ubyte(1024); - else data = Mallocator.expandArray(data,data.length); + if (data is null) + data = Mallocator.makeArray!ubyte(1024); + else + data = Mallocator.expandArray(data, data.length); } data[used++] = el; } @@ -27,10 +29,12 @@ struct SimpleVector ///Add array of elements to vector void add(ubyte[] el) nothrow @nogc { - while(used + el.length >= data.length) + while (used + el.length >= data.length) { - if(data is null)data = Mallocator.makeArray!ubyte(1024); - else data = Mallocator.expandArray(data,data.length); + if (data is null) + data = Mallocator.makeArray!ubyte(1024); + else + data = Mallocator.expandArray(data, data.length); } memcpy(data.ptr + used, el.ptr, el.length); used += el.length; @@ -44,23 +48,23 @@ struct SimpleVector export ref ubyte opIndex(size_t pos) nothrow @nogc { - return data[pos]; - } + return data[pos]; + } - export ubyte[] opSlice() nothrow @nogc + export ubyte[] opSlice() nothrow @nogc { - return data[0 .. used]; - } + return data[0 .. used]; + } - export ubyte[] opSlice(size_t x, size_t y) nothrow @nogc + export ubyte[] opSlice(size_t x, size_t y) nothrow @nogc { - return data[x .. y]; - } + return data[x .. y]; + } - export size_t opDollar() nothrow @nogc + export size_t opDollar() nothrow @nogc { - return used; - } + return used; + } ///set vector length to 0 void clear() nothrow @nogc @@ -70,4 +74,4 @@ struct SimpleVector ubyte[] data = null; size_t used = 0; -} \ No newline at end of file +} diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d index 6658639..a7dd846 100644 --- a/source/bubel/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -7,45 +7,50 @@ License: BSD 3-clause, see LICENSE file in project root folder. */ module bubel.ecs.std; -version(Emscripten)version = ECSEmscripten; +version (Emscripten) version = ECSEmscripten; import std.traits; -version(ECSEmscripten) +version (ECSEmscripten) { - extern(C) struct pthread_mutex_t - { - union - { - int[6] __i; - void[6] *__p; + extern (C) struct pthread_mutex_t + { + union + { + int[6] __i; + void[6]* __p; } - } - - extern(C) struct pthread_mutexattr_t - { - uint __attr; } - extern(C) int memcmp (const void *s1, const void *s2, size_t size); - extern(C) void exit (int status) nothrow @nogc; - extern(C) void __assert(const(char)* msg, const(char)* file, uint line) { exit(-20);} - extern(C) void free(void*) @nogc nothrow @system; - extern(C) void* malloc(size_t size) @nogc nothrow @system; - extern(C) void* realloc(void*, size_t size) @nogc nothrow @system; - extern(C) void* memcpy(return void*, scope const void*, size_t size) @nogc nothrow @system; - extern(C) void* memset(void*, int val, size_t size) @nogc nothrow @system; - extern(C) int posix_memalign(void**, size_t, size_t) @nogc nothrow @system; - extern(C) void qsort(void* base, size_t num, size_t size, int function(const void*,const void*) compar) @nogc nothrow @system; + extern (C) struct pthread_mutexattr_t + { + uint __attr; + } - extern(C) int pthread_mutex_lock(pthread_mutex_t *mutex) @nogc nothrow; - extern(C) int pthread_mutex_trylock(pthread_mutex_t *mutex) @nogc nothrow; - extern(C) int pthread_mutex_unlock(pthread_mutex_t *mutex) @nogc nothrow; - extern(C) void pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) @nogc nothrow; - extern(C) void pthread_mutexattr_destroy(pthread_mutexattr_t *attr) @nogc nothrow; - extern(C) int pthread_mutexattr_init(pthread_mutexattr_t *attr) @nogc nothrow; - extern(C) int pthread_mutex_destroy(pthread_mutex_t *mutex) @nogc nothrow; - extern(C) int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr) @nogc nothrow; + extern (C) int memcmp(const void* s1, const void* s2, size_t size); + extern (C) void exit(int status) nothrow @nogc; + extern (C) void __assert(const(char)* msg, const(char)* file, uint line) + { + exit(-20); + } + + extern (C) void free(void*) @nogc nothrow @system; + extern (C) void* malloc(size_t size) @nogc nothrow @system; + extern (C) void* realloc(void*, size_t size) @nogc nothrow @system; + extern (C) void* memcpy(return void*, scope const void*, size_t size) @nogc nothrow @system; + extern (C) void* memset(void*, int val, size_t size) @nogc nothrow @system; + extern (C) int posix_memalign(void**, size_t, size_t) @nogc nothrow @system; + extern (C) void qsort(void* base, size_t num, size_t size, + int function(const void*, const void*) compar) @nogc nothrow @system; + + extern (C) int pthread_mutex_lock(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) int pthread_mutex_trylock(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) int pthread_mutex_unlock(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) void pthread_mutexattr_settype(pthread_mutexattr_t* attr, int type) @nogc nothrow; + extern (C) void pthread_mutexattr_destroy(pthread_mutexattr_t* attr) @nogc nothrow; + extern (C) int pthread_mutexattr_init(pthread_mutexattr_t* attr) @nogc nothrow; + extern (C) int pthread_mutex_destroy(pthread_mutex_t* mutex) @nogc nothrow; + extern (C) int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr) @nogc nothrow; } else @@ -55,23 +60,24 @@ else public import core.stdc.stdlib : qsort; } -version(ECSEmscripten) +version (ECSEmscripten) { } else version (Windows) { import core.sys.windows.windows; - extern(Windows) void* _aligned_malloc(size_t size,size_t alignment) @nogc nothrow @system; - extern(Windows) void _aligned_free(void* ptr) @nogc nothrow @system; - - version(LDC) + + extern (Windows) void* _aligned_malloc(size_t size, size_t alignment) @nogc nothrow @system; + extern (Windows) void _aligned_free(void* ptr) @nogc nothrow @system; + + version (LDC) { /*extern(Windows) void* __alloca(size_t size) @nogc nothrow @system; alias alloca = __alloca;*/ - extern(Windows) void ___chkstk_ms() @nogc nothrow @system; - - extern(Windows) void __chkstk() + extern (Windows) void ___chkstk_ms() @nogc nothrow @system; + + extern (Windows) void __chkstk() { ___chkstk_ms(); } @@ -80,17 +86,18 @@ else version (Windows) else version (Posix) { import core.sys.posix.pthread; - import core.sys.posix.stdlib; + import core.sys.posix.stdlib : posix_memalign; } -version(ECSEmscripten) +version (ECSEmscripten) { - private const uint max_alloca = 10000; + private const uint max_alloca = 10000; private __gshared byte[max_alloca] alloca_array; private __gshared uint alloca_pos = 0; - export extern(C) void* alloca(size_t length) @nogc nothrow + export extern (C) void* alloca(size_t length) @nogc nothrow { - if(alloca_pos + length > max_alloca)alloca_pos = 0; + if (alloca_pos + length > max_alloca) + alloca_pos = 0; void* ret = &alloca_array[alloca_pos]; alloca_pos += length; return ret; @@ -101,28 +108,44 @@ version(ECSEmscripten) return null; }*/ } -else version(D_BetterC) +else version (D_BetterC) { - private const uint max_alloca = 10000; + private const uint max_alloca = 10000; private __gshared byte[max_alloca] alloca_array; private uint alloca_pos = 0; - export extern(C) void* alloca(size_t length) @nogc nothrow + export extern (C) void* __alloca(size_t length) @nogc nothrow { - if(alloca_pos + length > max_alloca)alloca_pos = 0; + if (alloca_pos + length > max_alloca) + alloca_pos = 0; void* ret = &alloca_array[alloca_pos]; alloca_pos += length; return ret; } - version(GNU) + alias alloca = __alloca; + + version (DigitalMars) { - extern(C) void __gdc_personality_v0() + export extern (C) float* _memsetFloat(float* p, float value, size_t count) @nogc nothrow + { + float* pstart = p; + float* ptop; + + for (ptop = &p[count]; p < ptop; p++) + *p = value; + return pstart; + } + } + + version (GNU) + { + extern (C) void __gdc_personality_v0() { } } } -else +else { public import core.stdc.stdlib : alloca; } @@ -131,13 +154,13 @@ static struct Mallocator { static T[] makeArray(T)(size_t length) nothrow @nogc { - T[] ret = (cast(T*)malloc(T.sizeof * length))[0 .. length]; + T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length]; - static if(__traits(isPOD, T)) + static if (__traits(isPOD, T)) { static immutable T init = T.init; - - foreach(i;0..ret.length) + + foreach (i; 0 .. ret.length) { memcpy(&ret[i], &init, T.sizeof); } @@ -145,7 +168,8 @@ static struct Mallocator else { static import std.conv; - foreach(i;0..ret.length) + + foreach (i; 0 .. ret.length) { std.conv.emplace(&ret[i]); } @@ -155,78 +179,94 @@ static struct Mallocator static T[] makeArray(T)(size_t length, T initializer) nothrow @nogc { - T[] ret = (cast(T*)malloc(T.sizeof * length))[0 .. length]; - foreach(ref v; ret)v = initializer; + T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length]; + foreach (ref v; ret) + v = initializer; return ret; } static T[] expandArray(T)(T[] array, size_t length) nothrow @nogc { size_t new_length = array.length + length; - return (cast(T*)realloc(array.ptr, T.sizeof * new_length))[0 .. new_length]; + return (cast(T*) realloc(array.ptr, T.sizeof * new_length))[0 .. new_length]; } static T[] makeArray(T)(T[] array) nothrow @nogc { - T[] ret = (cast(T*)malloc(T.sizeof * array.length))[0 .. array.length];//Mallocator.makeArray!(T)(array.length); - foreach(i, ref v;ret)v = array[i]; + T[] ret = (cast(T*) malloc(T.sizeof * array.length))[0 .. array.length]; //Mallocator.makeArray!(T)(array.length); + foreach (i, ref v; ret) + v = array[i]; return ret; } - static T* make(T, Args...)(Args args) + static T* make(T, Args...)(Args args) { - T* ret = cast(T*)malloc(T.sizeof); + T* ret = cast(T*) malloc(T.sizeof); static import std.conv; - static if(__traits(isPOD, T)) + + static if (__traits(isPOD, T)) { static immutable T init = T.init; memcpy(ret, &init, T.sizeof); } - else static if(is(T == struct))std.conv.emplace(ret, args); + else static if (is(T == struct)) + std.conv.emplace(ret, args); return ret; } static void* alignAlloc(size_t length, size_t alignment) nothrow @nogc { void* ret; - version(Posix)posix_memalign(&ret, alignment, length);//ret = aligned_alloc(alignment, length); - else version(Windows)ret = _aligned_malloc(length, alignment); - else version(ECSEmscripten)posix_memalign(&ret, alignment, length);//malloc(length); - else static assert(0, "Unimplemented platform!"); + version (Posix) + posix_memalign(&ret, alignment, length); //ret = aligned_alloc(alignment, length); + else version (Windows) + ret = _aligned_malloc(length, alignment); + else version (ECSEmscripten) + posix_memalign(&ret, alignment, length); //malloc(length); + else + static assert(0, "Unimplemented platform!"); return ret; } static void dispose(T)(T object) nothrow @nogc { - static if(__traits(hasMember, T, "__xdtor"))object.__xdtor(); - else static if(__traits(hasMember, T, "__dtor"))object.__dtor(); - free(cast(void*)object); + static if (__traits(hasMember, T, "__xdtor")) + object.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + object.__dtor(); + free(cast(void*) object); } static void alignDispose(T)(T object) { - static if(__traits(hasMember, T, "__xdtor"))object.__xdtor(); - else static if(__traits(hasMember, T, "__dtor"))object.__dtor(); - version(Posix)free(cast(void*)object); - else version(Windows)_aligned_free(cast(void*)object); - else version(ECSEmscripten)free(cast(void*)object); - else static assert(0, "Unimplemented platform!"); + static if (__traits(hasMember, T, "__xdtor")) + object.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + object.__dtor(); + version (Posix) + free(cast(void*) object); + else version (Windows) + _aligned_free(cast(void*) object); + else version (ECSEmscripten) + free(cast(void*) object); + else + static assert(0, "Unimplemented platform!"); } } struct Mutex { - version(ECSEmscripten) + version (ECSEmscripten) { void initialize() nothrow @nogc { pthread_mutexattr_t attr = void; //pthread_mutexattr_init(&attr); - + //pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(cast(pthread_mutex_t*) &m_handle, &attr); + pthread_mutex_init(cast(pthread_mutex_t*)&m_handle, &attr); //pthread_mutexattr_destroy(&attr); } @@ -257,7 +297,7 @@ struct Mutex { void initialize() nothrow @nogc { - InitializeCriticalSection(cast(CRITICAL_SECTION*) &m_handle); + InitializeCriticalSection(cast(CRITICAL_SECTION*)&m_handle); } void destroy() nothrow @nogc @@ -280,7 +320,7 @@ struct Mutex return TryEnterCriticalSection(&m_handle) != 0; } - CRITICAL_SECTION m_handle; + CRITICAL_SECTION m_handle; } else version (Posix) { @@ -289,9 +329,9 @@ struct Mutex pthread_mutexattr_t attr = void; pthread_mutexattr_init(&attr); - + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(cast(pthread_mutex_t*) &m_handle, &attr); + pthread_mutex_init(cast(pthread_mutex_t*)&m_handle, &attr); pthread_mutexattr_destroy(&attr); } @@ -318,5 +358,6 @@ struct Mutex private pthread_mutex_t m_handle; } - else static assert(0, "unsupported platform!"); -} \ No newline at end of file + else + static assert(0, "unsupported platform!"); +} diff --git a/source/bubel/ecs/vector.d b/source/bubel/ecs/vector.d index 1ec8a93..ca6cd6c 100644 --- a/source/bubel/ecs/vector.d +++ b/source/bubel/ecs/vector.d @@ -1,30 +1,36 @@ module bubel.ecs.vector; import core.bitop; + //import core.stdc.stdlib : free, malloc; import bubel.ecs.std; + //import core.stdc.string : memcpy, memset; //import std.algorithm : swap; import std.conv : emplace; import std.traits : hasMember, isCopyable, TemplateOf, Unqual; -export @nogc @safe nothrow pure size_t nextPow2(size_t num) { +export @nogc @safe nothrow pure size_t nextPow2(size_t num) +{ return 1 << bsr(num) + 1; } export __gshared size_t gVectorsCreated = 0; export __gshared size_t gVectorsDestroyed = 0; -struct Vector(T) { +struct Vector(T) +{ T[] array; size_t used; public: - export this()(T t) { + export this()(T t) + { add(t); } - export this(X)(X[] t) if (is(Unqual!X == Unqual!T)) { + export this(X)(X[] t) if (is(Unqual!X == Unqual!T)) + { add(t); } @@ -42,79 +48,101 @@ public: @disable this(this); - export ~this() { + export ~this() + { clear(); } - export void clear() { + export void clear() + { removeAll(); } - export void removeAll() { - if (array !is null) { + export void removeAll() + { + if (array !is null) + { /*foreach (ref el; array[0 .. used]) { destroy(el); }*/ //freeData(cast(void[]) array); - freeData((cast(void*)array.ptr)[0 .. array.length * T.sizeof]); + freeData((cast(void*) array.ptr)[0 .. array.length * T.sizeof]); gVectorsDestroyed++; } array = null; used = 0; } - export bool empty() const { + export bool empty() const + { return (used == 0); } - export size_t length() const { + export size_t length() const + { return used; } - export void length(size_t newLength) { - if (newLength > used) { + export void length(size_t newLength) + { + if (newLength > used) + { reserve(newLength); - foreach (ref el; array[used .. newLength]) { + foreach (ref el; array[used .. newLength]) + { emplace(&el); } - } else { - foreach (ref el; array[newLength .. used]) { + } + else + { + foreach (ref el; array[newLength .. used]) + { //destroy(el); - static if(__traits(hasMember, T, "__xdtor"))el.__xdtor(); - else static if(__traits(hasMember, T, "__dtor"))el.__dtor(); + static if (__traits(hasMember, T, "__xdtor")) + el.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + el.__dtor(); } } used = newLength; } - export void reset() { + export void reset() + { used = 0; } - export void reserve(size_t numElements) { - if (numElements > array.length) { + export void reserve(size_t numElements) + { + if (numElements > array.length) + { extend(numElements); } } - export size_t capacity() { + export size_t capacity() + { return array.length - used; } - export void extend(size_t newNumOfElements) { + export void extend(size_t newNumOfElements) + { auto oldArray = manualExtend(array, newNumOfElements); - if (oldArray !is null) { + if (oldArray !is null) + { freeData(oldArray); } } - export @nogc void freeData(void[] data) { + export @nogc void freeData(void[] data) + { // 0x0F probably invalid value for pointers and other types memset(data.ptr, 0x0F, data.length); // Makes bugs show up xD free(data.ptr); } - export static void[] manualExtend(ref T[] array, size_t newNumOfElements = 0) { + export static void[] manualExtend(ref T[] array, size_t newNumOfElements = 0) + { if (newNumOfElements == 0) newNumOfElements = 2; if (array.length == 0) @@ -126,22 +154,26 @@ public: memcpy(cast(void*) memory, cast(void*) oldArray.ptr, oldSize); array = memory[0 .. newNumOfElements]; //return cast(void[]) oldArray; - return (cast(void*)oldArray.ptr)[0 .. oldArray.length * T.sizeof]; + return (cast(void*) oldArray.ptr)[0 .. oldArray.length * T.sizeof]; } - export Vector!T copy()() { + export Vector!T copy()() + { Vector!T duplicate; duplicate.reserve(used); duplicate ~= array[0 .. used]; return duplicate; } - export bool canAddWithoutRealloc(uint elemNum = 1) { + export bool canAddWithoutRealloc(uint elemNum = 1) + { return used + elemNum <= array.length; } - export void add()(T t) { - if (used >= array.length) { + export void add()(T t) + { + if (used >= array.length) + { extend(nextPow2(used + 1)); } emplace(&array[used], t); @@ -149,48 +181,62 @@ public: } /// Add element at given position moving others - export void add()(T t, size_t pos) { + export void add()(T t, size_t pos) + { assert(pos <= used); - if (used >= array.length) { + if (used >= array.length) + { extend(array.length * 2); } - foreach_reverse (size_t i; pos .. used) { + foreach_reverse (size_t i; pos .. used) + { //swap(array[i + 1], array[i]); - array[i+1] = array[i]; + array[i + 1] = array[i]; } emplace(&array[pos], t); used++; } - export void add(X)(X[] t) if (is(Unqual!X == Unqual!T)) { - if (used + t.length > array.length) { + export void add(X)(X[] t) if (is(Unqual!X == Unqual!T)) + { + if (used + t.length > array.length) + { extend(nextPow2(used + t.length)); } - foreach (i; 0 .. t.length) { + foreach (i; 0 .. t.length) + { emplace(&array[used + i], t[i]); } used += t.length; } - export void remove(size_t elemNum) { + export void remove(size_t elemNum) + { //destroy(array[elemNum]); - static if(__traits(hasMember, T, "__xdtor"))array[elemNum].__xdtor(); - else static if(__traits(hasMember, T, "__dtor"))array[elemNum].__dtor(); + static if (__traits(hasMember, T, "__xdtor")) + array[elemNum].__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + array[elemNum].__dtor(); //swap(array[elemNum], array[used - 1]); array[elemNum] = array[used - 1]; used--; } - export void removeStable()(size_t elemNum) { + export void removeStable()(size_t elemNum) + { used--; - foreach (i; 0 .. used) { + foreach (i; 0 .. used) + { array[i] = array[i + 1]; } } - export bool tryRemoveElement()(T elem) { - foreach (i, ref el; array[0 .. used]) { - if (el == elem) { + export bool tryRemoveElement()(T elem) + { + foreach (i, ref el; array[0 .. used]) + { + if (el == elem) + { remove(i); return true; } @@ -198,55 +244,66 @@ public: return false; } - export void removeElement()(T elem) { + export void removeElement()(T elem) + { bool ok = tryRemoveElement(elem); assert(ok, "There is no such an element in vector"); } - export ref T opIndex(size_t elemNum) const { + export ref T opIndex(size_t elemNum) const + { //debug assert(elemNum < used, "Range violation [index]"); return *cast(T*)&array.ptr[elemNum]; } - export auto opSlice() { + export auto opSlice() + { return array.ptr[0 .. used]; } - export T[] opSlice(size_t x, size_t y) { + export T[] opSlice(size_t x, size_t y) + { assert(y <= used); return array.ptr[x .. y]; } - export size_t opDollar() { + export size_t opDollar() + { return used; } - export void opAssign(X)(X[] slice) { + export void opAssign(X)(X[] slice) + { reset(); this ~= slice; } - export void opOpAssign(string op)(T obj) { + export void opOpAssign(string op)(T obj) + { //static assert(op == "~"); add(obj); } - export void opOpAssign(string op, X)(X[] obj) { + export void opOpAssign(string op, X)(X[] obj) + { //static assert(op == "~"); add(obj); } - export void opIndexAssign()(T obj, size_t elemNum) { + export void opIndexAssign()(T obj, size_t elemNum) + { assert(elemNum < used, "Range viloation"); array[elemNum] = obj; } - export void opSliceAssign()(T[] obj, size_t a, size_t b) { + export void opSliceAssign()(T[] obj, size_t a, size_t b) + { assert(b <= used && a <= b, "Range viloation"); array.ptr[a .. b] = obj; } - export bool opEquals()(auto ref const Vector!(T) r) const { + export bool opEquals()(auto ref const Vector!(T) r) const + { return used == r.used && array.ptr[0 .. used] == r.array.ptr[0 .. r.used]; } -} \ No newline at end of file +} diff --git a/tests/basic.d b/tests/basic.d index ab9acec..b8e1d2c 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -68,6 +68,11 @@ struct CUnregistered short value = 12; } +struct CFlag +{ + mixin ECS.Component; +} + struct LongAddSystem { mixin ECS.System; @@ -110,6 +115,7 @@ struct EmptySystem void beforeEveryTest() { + CUnregistered.component_id = ushort.max; gEM.initialize(0); gEM.beginRegister(); @@ -119,6 +125,7 @@ void beforeEveryTest() gEM.registerComponent!CDouble; gEM.registerComponent!CLong; gEM.registerComponent!CShort; + gEM.registerComponent!CFlag; gEM.endRegister(); } @@ -131,11 +138,12 @@ void afterEveryTest() @("AddEntity") unittest { - ushort[2] ids = [CInt.component_id, CFloat.component_id]; - EntityTemplate* tmpl_ = gEM.allocateTemplate(ids); - assert(tmpl_.info.components.length == 2); + EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray); + assert(tmpl_.info.components.length == 3); + assert(tmpl_.info.size == (CInt.sizeof + CFloat.sizeof + EntityID.sizeof)); assert(tmpl_.getComponent!CInt); assert(tmpl_.getComponent!CFloat); + assert(tmpl_.getComponent!CFlag); assert(!tmpl_.getComponent!CLong); assert(!tmpl_.getComponent!CUnregistered); assert(*tmpl_.getComponent!CInt == 1); @@ -154,13 +162,66 @@ unittest assert(*entity2.getComponent!CInt == 2); assert(*entity2.getComponent!CFloat == 2.0); - CInt cint = CInt(10); - CLong clong; - Entity* entity3 = gEM.addEntity(tmpl_, [cint.ref_, clong.ref_].staticArray); + //CInt cint = CInt(10); + //CLong clong; + //Entity* entity3 = gEM.addEntity(tmpl_, [cint.ref_, clong.ref_].staticArray); + Entity* entity3 = gEM.addEntity(tmpl_, [CInt(10).ref_, CLong().ref_, CFlag().ref_].staticArray); + EntityID id = entity3.id; assert(entity3.getComponent!CInt); assert(entity3.getComponent!CFloat); assert(*entity3.getComponent!CInt == 10); assert(*entity3.getComponent!CFloat == 2.0); + + gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_]); + gEM.commit(); + entity3 = gEM.getEntity(id); + assert(entity3.getComponent!CInt); + assert(entity3.getComponent!CFloat); + assert(entity3.getComponent!CFlag); + assert(entity3.getComponent!CShort); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); + assert(*entity3.getComponent!CShort == 2); + + gEM.removeComponents(entity3.id, [CFlag().component_id,CShort(2).component_id]); + gEM.commit(); + entity3 = gEM.getEntity(id); + assert(entity3.getComponent!CInt); + assert(entity3.getComponent!CFloat); + assert(!entity3.getComponent!CFlag); + assert(!entity3.getComponent!CShort); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); + + gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_]); + gEM.removeComponents(entity3.id, [CUnregistered.component_id]); + gEM.commit(); + entity3 = gEM.getEntity(id); + assert(entity3.getComponent!CInt); + assert(entity3.getComponent!CFloat); + assert(entity3.getComponent!CFlag); + assert(entity3.getComponent!CShort); + assert(*entity3.getComponent!CInt == 10); + assert(*entity3.getComponent!CFloat == 2.0); + assert(*entity3.getComponent!CShort == 2); + + gEM.beginRegister(); + + gEM.registerComponent!CUnregistered; + + gEM.endRegister(); + + gEM.addComponents(entity3.id, [CUnregistered(4).ref_]); + gEM.commit(); + entity3 = gEM.getEntity(id); + assert(entity3.getComponent!CUnregistered); + assert(*entity3.getComponent!CUnregistered == 4); + + gEM.removeComponents(entity3.id, [CUnregistered.component_id]); + gEM.commit(); + entity3 = gEM.getEntity(id); + assert(!entity3.getComponent!CUnregistered); + } //allocate templates @@ -171,32 +232,48 @@ unittest ushort[2] ids = [CInt.component_id, CFloat.component_id]; EntityTemplate* tmpl_ = gEM.allocateTemplate(ids); EntityTemplate* tmpl_d = gEM.allocateTemplate([CFloat.component_id, CInt.component_id, CFloat.component_id].staticArray); + EntityTemplate* tmpl_cp = gEM.allocateTemplate(tmpl_); assert(tmpl_d.info == tmpl_.info); + assert(tmpl_cp.info == tmpl_cp.info); assert(tmpl_.info.components.length == 2); assert(tmpl_.getComponent!CInt); assert(tmpl_.getComponent!CFloat); assert(*tmpl_.getComponent!CInt == 1); assert(*tmpl_.getComponent!CFloat == 2.0); + assert(tmpl_cp.getComponent!CFloat); + assert(tmpl_cp.getComponent!CInt); + assert(tmpl_.getComponent!CInt != tmpl_cp.getComponent!CInt); + assert(tmpl_.getComponent!CFloat != tmpl_cp.getComponent!CFloat); + assert(*tmpl_.getComponent!CInt == *tmpl_cp.getComponent!CInt); + assert(*tmpl_.getComponent!CFloat == *tmpl_cp.getComponent!CFloat); *tmpl_.getComponent!CInt = 4; *tmpl_.getComponent!CFloat = 5.0; - //allocate template from template with additional component - ushort[1] ids2 = [CDouble.component_id]; + //allocate template from template with additional components + ushort[2] ids2 = [CDouble.component_id,CFlag.component_id]; EntityTemplate* tmpl_2 = gEM.allocateTemplate(tmpl_, ids2); - assert(tmpl_2.info.components.length == 3); + assert(tmpl_2.info.components.length == 4); assert(tmpl_2.getComponent!CInt); assert(tmpl_2.getComponent!CFloat); assert(tmpl_2.getComponent!CDouble); + assert(tmpl_2.getComponent!CFlag); assert(*tmpl_2.getComponent!CInt == 4); assert(*tmpl_2.getComponent!CFloat == 5.0); assert(*tmpl_2.getComponent!CDouble == 3.0); + assert(tmpl_.info.blocksCount() == 0); + Entity* entity = gEM.addEntity(tmpl_); - gEM.addComponents(entity.id, CDouble(8.0)); + gEM.addComponents(entity.id, CFloat(100)); + gEM.addComponents(entity.id, CDouble(8.0), CFloat(100)); + + assert(tmpl_.info.blocksCount() == 1); //apply entity changes gEM.commit(); + assert(tmpl_.info.blocksCount() == 0); + //allocate template as entity copy EntityTemplate* tmpl_3 = gEM.allocateTemplate(entity.id); assert(tmpl_3.info.components.length == 3); @@ -217,18 +294,20 @@ unittest assert(*tmpl_4.getComponent!CFloat == 2.0); assert(*tmpl_4.getComponent!CDouble == 3.0); - //allocate template from template with two additional component - ushort[2] ids3 = [CDouble.component_id, CLong.component_id]; - EntityTemplate* tmpl_5 = gEM.allocateTemplate(tmpl_, ids3); - assert(tmpl_5.info.components.length == 4); + //allocate template from template with three additional component + ushort[3] ids3 = [CDouble.component_id, CLong.component_id, CShort.component_id]; + EntityTemplate* tmpl_5 = gEM.allocateTemplate(tmpl_2, ids3); + assert(tmpl_5.info.components.length == 6); assert(tmpl_5.getComponent!CInt); assert(tmpl_5.getComponent!CFloat); assert(tmpl_5.getComponent!CDouble); assert(tmpl_5.getComponent!CLong); + assert(tmpl_5.getComponent!CShort); assert(*tmpl_5.getComponent!CInt == 4); assert(*tmpl_5.getComponent!CFloat == 5.0); assert(*tmpl_5.getComponent!CDouble == 3.0); assert(*tmpl_5.getComponent!CLong == 10); + assert(*tmpl_5.getComponent!CShort == 12); //allocate template from template without one component ushort[1] rem_ids = [CFloat.component_id]; @@ -239,7 +318,7 @@ unittest //allocate template from template without one component and two additional EntityTemplate* tmpl_7 = gEM.allocateTemplate(tmpl_, ids3, rem_ids); - assert(tmpl_7.info.components.length == 3); + assert(tmpl_7.info.components.length == 4); assert(tmpl_7.getComponent!CInt); assert(tmpl_7.getComponent!CDouble); assert(tmpl_7.getComponent!CLong); @@ -496,6 +575,10 @@ unittest gEM.endRegister(); + assert(gEM.getPass("custom")); + assert(!gEM.getPass("custommm")); + + LongAddSystem* system = gEM.getSystem!LongAddSystem; assert(system !is null); assert(system.updates_count == 0); @@ -1131,9 +1214,9 @@ unittest assert(*entity2.getComponent!CShort == 12); gEM.sendEvent(id,ETest()); - gEM.sendEvent(id,ETest2(id,10)); + gEM.sendEvent(id,ETest2(10)); gEM.sendEvent(id2,ETest()); - gEM.sendEvent(id2,ETest2(id2,12)); + gEM.sendEvent(id2,ETest2(12)); gEM.commit(); assert(ETest2.destory == 2); @@ -1144,7 +1227,7 @@ unittest gEM.addComponents(id, CInt(2), CShort(1)); gEM.sendEvent(id,ETest()); - gEM.sendEvent(id,ETest2(id,2)); + gEM.sendEvent(id,ETest2(2)); gEM.commit(); assert(ETest2.destory == 3); @@ -1157,7 +1240,7 @@ unittest foreach(i;0..10000) { gEM.sendEvent(id,ETest()); - gEM.sendEvent(id,ETest2(id,4)); + gEM.sendEvent(id,ETest2(4)); result += 16; result += 8; } @@ -1321,22 +1404,6 @@ unittest } } - void func1(TestSystem.EntitiesData entities) - { - foreach(i;0 .. entities.length) - { - entities.int_[i] += entities.int_[i] / 2; - } - } - - void func2(TestSystem.EntitiesData entities) - { - foreach(i;0 .. entities.length) - { - entities.int_[i] += 8; - } - } - gEM.beginRegister(); gEM.registerSystem!TestSystem(0); @@ -1462,22 +1529,6 @@ unittest } } - void func1(TestSystem.EntitiesData entities) - { - foreach(i;0 .. entities.length) - { - entities.int_[i] += entities.int_[i] / 2; - } - } - - void func2(TestSystem.EntitiesData entities) - { - foreach(i;0 .. entities.length) - { - entities.int_[i] += 8; - } - } - gEM.beginRegister(); gEM.registerDependency(TestDependency); diff --git a/tests/bugs.d b/tests/bugs.d new file mode 100644 index 0000000..49e3b12 --- /dev/null +++ b/tests/bugs.d @@ -0,0 +1,142 @@ +module tests.bugs; + +import tests.basic; + +import bubel.ecs.core; +import bubel.ecs.manager; +import bubel.ecs.system; +import bubel.ecs.attributes; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +@("Bug0001") +unittest +{ + struct Event1 + { + mixin ECS.Event; + + EntityID id; + } + + struct Event2 + { + mixin ECS.Event; + } + + struct System1 + { + mixin ECS.System; + + struct EntitiesData + { + CInt[] int_; + } + + EntityTemplate* tmpl; + EntityID id; + + void onCreate() + { + tmpl = gEM.allocateTemplate([CInt.component_id, CLong.component_id].staticArray); + } + + void onDestroy() + { + gEM.freeTemplate(tmpl); + } + + void handleEvent(Entity* entity, Event1 event) + { + gEM.removeEntity(event.id); + gEM.sendEvent(entity.id,Event2()); + } + + void handleEvent(Entity* entity, Event2 event) + { + id = gEM.addEntity(tmpl,[CInt(2).ref_, CLong(8).ref_].staticArray).id; + } + } + + struct System2 + { + mixin ECS.System; + + struct EntitiesData + { + Entity[] entity; + } + + ///check if every entity was removed correctly + void onUpdate(EntitiesData data) + { + assert(0); + } + } + + struct System3 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + Entity[] entity; + } + + ///remove every entity + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length)gEM.removeEntity(data.entity[i].id); + } + } + + gEM.initialize(0); + + gEM.beginRegister(); + + gEM.registerComponent!CInt; + gEM.registerComponent!CFloat; + gEM.registerComponent!CDouble; + gEM.registerComponent!CLong; + gEM.registerComponent!CShort; + gEM.registerComponent!CFlag; + + gEM.registerEvent!Event1; + gEM.registerEvent!Event2; + + gEM.registerSystem!System1(0); + gEM.registerSystem!System2(-200); + gEM.registerSystem!System3(-200); + + gEM.endRegister(); + + EntityTemplate* tmpl = gEM.allocateTemplate([CInt.component_id, CLong.component_id].staticArray); + EntityID id = gEM.addEntity(tmpl,[CLong(10).ref_, CInt(6).ref_].staticArray).id; + EntityID id2 = gEM.addEntity(tmpl,[CInt(4).ref_].staticArray).id; + gEM.freeTemplate(tmpl); + gEM.commit(); + + gEM.sendEvent(id2, Event1(id)); + + gEM.getSystem(System2.system_id).disable(); + + gEM.begin(); + gEM.update(); + gEM.end(); + + gEM.getSystem(System2.system_id).enable(); + + gEM.begin(); + gEM.update(); + gEM.end(); + + gEM.destroy(); +} \ No newline at end of file diff --git a/tests/runner.d b/tests/runner.d index f299664..b14dafe 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -210,7 +210,7 @@ struct TestRunner(Args...) else test.name = attributes[0]; - static if (__traits(hasMember, module_, "beforeEveryTest")) + static if (__traits(hasMember, module_, "beforeEveryTest") && __traits(compiles, module_.beforeEveryTest())) module_.beforeEveryTest(); if(before)before(); @@ -256,7 +256,7 @@ struct TestRunner(Args...) else suite.failed++; suite.tests ~= test; - static if (__traits(hasMember, module_, "afterEveryTest")) + static if (__traits(hasMember, module_, "afterEveryTest") && __traits(compiles, module_.beforeEveryTest())) module_.afterEveryTest(); } passed += suite.passed; @@ -420,7 +420,7 @@ extern (C) int main(int argc, char** args) } } - TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf) runner; + TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf, tests.bugs) runner; runner.runTests(include[], exclude[]); From 2f827a94db33c34445044a11056580f3c85563a5 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 27 May 2020 18:22:55 +0200 Subject: [PATCH 32/58] Fixed betterC compilation --- tests/basic.d | 12 ++++++------ tests/bugs.d | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/basic.d b/tests/basic.d index b8e1d2c..aefdc7e 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -172,7 +172,7 @@ unittest assert(*entity3.getComponent!CInt == 10); assert(*entity3.getComponent!CFloat == 2.0); - gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_]); + gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_].staticArray); gEM.commit(); entity3 = gEM.getEntity(id); assert(entity3.getComponent!CInt); @@ -183,7 +183,7 @@ unittest assert(*entity3.getComponent!CFloat == 2.0); assert(*entity3.getComponent!CShort == 2); - gEM.removeComponents(entity3.id, [CFlag().component_id,CShort(2).component_id]); + gEM.removeComponents(entity3.id, [CFlag().component_id,CShort(2).component_id].staticArray); gEM.commit(); entity3 = gEM.getEntity(id); assert(entity3.getComponent!CInt); @@ -193,8 +193,8 @@ unittest assert(*entity3.getComponent!CInt == 10); assert(*entity3.getComponent!CFloat == 2.0); - gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_]); - gEM.removeComponents(entity3.id, [CUnregistered.component_id]); + gEM.addComponents(entity3.id, [CFlag().ref_,CShort(2).ref_].staticArray); + gEM.removeComponents(entity3.id, [CUnregistered.component_id].staticArray); gEM.commit(); entity3 = gEM.getEntity(id); assert(entity3.getComponent!CInt); @@ -211,13 +211,13 @@ unittest gEM.endRegister(); - gEM.addComponents(entity3.id, [CUnregistered(4).ref_]); + gEM.addComponents(entity3.id, [CUnregistered(4).ref_].staticArray); gEM.commit(); entity3 = gEM.getEntity(id); assert(entity3.getComponent!CUnregistered); assert(*entity3.getComponent!CUnregistered == 4); - gEM.removeComponents(entity3.id, [CUnregistered.component_id]); + gEM.removeComponents(entity3.id, [CUnregistered.component_id].staticArray); gEM.commit(); entity3 = gEM.getEntity(id); assert(!entity3.getComponent!CUnregistered); diff --git a/tests/bugs.d b/tests/bugs.d index 49e3b12..4c4153a 100644 --- a/tests/bugs.d +++ b/tests/bugs.d @@ -61,7 +61,7 @@ unittest void handleEvent(Entity* entity, Event2 event) { - id = gEM.addEntity(tmpl,[CInt(2).ref_, CLong(8).ref_].staticArray).id; + id = gEM.addEntity(tmpl).id; } } From f964d7bf85e4dafd15b63d85cb6a1812ca243956 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 27 May 2020 19:46:11 +0200 Subject: [PATCH 33/58] Added more tests -added Vector test -added HashMap test -added EntityMeta test -added default hashing function to hashmap --- source/bubel/ecs/hash_map.d | 13 ++++++++- source/bubel/ecs/vector.d | 4 +-- tests/basic.d | 22 +++++++++++++-- tests/map.d | 53 +++++++++++++++++++++++++++++++++++++ tests/runner.d | 2 +- tests/vector.d | 46 +++++++++++++++++++++++++++++++- 6 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 tests/map.d diff --git a/source/bubel/ecs/hash_map.d b/source/bubel/ecs/hash_map.d index 6ae6a79..764374c 100755 --- a/source/bubel/ecs/hash_map.d +++ b/source/bubel/ecs/hash_map.d @@ -19,10 +19,21 @@ export ulong defaultHashFunc(T)(auto ref T t) nothrow @nogc } else { - return 0; //hashInt(t.hashOf); // hashOf is not giving proper distribution between H1 and H2 hash parts + static if(isArray!T)return hashInt(hash((cast(byte*)t.ptr)[0 .. t.length * ForeachType!(T).sizeof])); + else return hashInt(hash((cast(byte*)&t)[0 .. T.sizeof])); //hashInt(t.hashOf); // hashOf is not giving proper distribution between H1 and H2 hash parts } } +ulong hash(byte[] array) nothrow @nogc +{ + ulong hash = 0; + + foreach(c;array) + hash = c + (hash << 6) + (hash << 16) - hash; + + return hash; +} + // Can turn bad hash function to good one export ulong hashInt(ulong x) nothrow @nogc @safe { diff --git a/source/bubel/ecs/vector.d b/source/bubel/ecs/vector.d index ca6cd6c..019673b 100644 --- a/source/bubel/ecs/vector.d +++ b/source/bubel/ecs/vector.d @@ -165,10 +165,10 @@ public: return duplicate; } - export bool canAddWithoutRealloc(uint elemNum = 1) + /*export bool canAddWithoutRealloc(uint elemNum = 1) { return used + elemNum <= array.length; - } + }*/ export void add()(T t) { diff --git a/tests/basic.d b/tests/basic.d index aefdc7e..5046dff 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -135,6 +135,24 @@ void afterEveryTest() gEM.destroy(); } +@("EntityMeta") +unittest +{ + EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray); + Entity* entity = gEM.addEntity(tmpl_); + EntityMeta meta = entity.getMeta(); + assert(meta.hasComponent(CInt.component_id)); + assert(meta.getComponent!CInt); + assert(meta.hasComponent(CFloat.component_id)); + assert(meta.getComponent!CFloat); + assert(!meta.getComponent!CLong); + assert(!meta.hasComponent(CLong.component_id)); + assert(!meta.getComponent!CUnregistered); + assert(!meta.hasComponent(CUnregistered.component_id)); + assert(*meta.getComponent!CInt == 1); + assert(*meta.getComponent!CFloat == 2.0); +} + @("AddEntity") unittest { @@ -167,8 +185,8 @@ unittest //Entity* entity3 = gEM.addEntity(tmpl_, [cint.ref_, clong.ref_].staticArray); Entity* entity3 = gEM.addEntity(tmpl_, [CInt(10).ref_, CLong().ref_, CFlag().ref_].staticArray); EntityID id = entity3.id; - assert(entity3.getComponent!CInt); - assert(entity3.getComponent!CFloat); + assert(entity3.hasComponent(CInt.component_id)); + assert(entity3.hasComponent(CFloat.component_id)); assert(*entity3.getComponent!CInt == 10); assert(*entity3.getComponent!CFloat == 2.0); diff --git a/tests/map.d b/tests/map.d new file mode 100644 index 0000000..a82985b --- /dev/null +++ b/tests/map.d @@ -0,0 +1,53 @@ +module tests.map; + +import bubel.ecs.hash_map; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; + +@("HashMap") +unittest +{ + HashMap!(string, int) map; + + assert(map.length == 0); + map.add("asd",1); + assert(map.length == 1); + map.clear(); + assert(map.length == 0); + map.add("asd",1); + assert(map.length == 1); + map.reset(); + assert(map.length == 0); + + map.add("asd",1); + string asd = "asd"; + assert(map.isIn("asd")); + assert(map.isIn(asd)); + assert(!map.isIn("asdf")); + map.tryRemove("asdf"); + map.tryRemove("asd"); + assert(map.length == 0); + map.add("asdf",1); + map.add("asd",2); + assert(map["asd"] == 2); + assert(map["asdf"] == 1); + assert(map.length == 2); + map.tryRemove("asdf"); + assert(map.length == 1); + map.remove("asd"); + assert(map.length == 0); + + map.add("asd",1); + map.add("asdwwghe",6); + foreach(k,v;&map.byKeyValue) + { + assert(map[k] == v); + } +} \ No newline at end of file diff --git a/tests/runner.d b/tests/runner.d index b14dafe..7e3dd07 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -420,7 +420,7 @@ extern (C) int main(int argc, char** args) } } - TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf, tests.bugs) runner; + TestRunner!(tests.id_manager, tests.vector, tests.basic, tests.perf, tests.access_perf, tests.bugs, tests.map) runner; runner.runTests(include[], exclude[]); diff --git a/tests/vector.d b/tests/vector.d index d733f0f..1756518 100644 --- a/tests/vector.d +++ b/tests/vector.d @@ -1,7 +1,16 @@ module tests.vector; import bubel.ecs.simple_vector; -//import bubel.ecs.vector; +import bubel.ecs.vector; + +version(GNU) +{ + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } +} +else import std.array : staticArray; @("simple-vector") unittest @@ -33,3 +42,38 @@ unittest assert(vector2[1023] == 'a'); assert(vector2[1024] == 'b'); } + +@("Vector") +unittest +{ + struct G + { + int a; + } + + Vector!G vector; + assert(vector.empty()); + vector.add(G(1)); + assert(!vector.empty()); + vector.clear(); + assert(vector.empty()); + vector.add(G(1)); + assert(!vector.empty()); + vector.reset(); + assert(vector.empty()); + + vector.add(G(1)); + vector.add([G(2),G(5)].staticArray); + assert(vector.length == 3); + assert(vector.capacity == 1); + + Vector!G vector2; + vector2.add([G(1),G(2),G(5)].staticArray); + assert(vector == vector2); + vector2.remove(1); + assert(vector != vector2); + assert(vector2.length == 2); + assert(vector2[1] == G(5)); + vector2.add(G(2),1); + assert(vector == vector2); +} From 3719cdaee0f28a610ef59078f775b3c7f3951cb8 Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 28 May 2020 09:39:17 +0200 Subject: [PATCH 34/58] Some small fixes --- source/bubel/ecs/id_manager.d | 1 + source/bubel/ecs/manager.d | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/bubel/ecs/id_manager.d b/source/bubel/ecs/id_manager.d index 084a947..aaeef30 100644 --- a/source/bubel/ecs/id_manager.d +++ b/source/bubel/ecs/id_manager.d @@ -56,6 +56,7 @@ struct IDManager */ void releaseID(EntityID id) nothrow @nogc { + optimize(); Data* data = &m_ids_array[id.id]; if (data.counter != id.counter) return; diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index cf3712d..a8954e0 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -2923,6 +2923,7 @@ export struct EntityManager private void updateBlock(EntitiesBlock* block) @nogc nothrow { + if(block.added_count == 0)return; EntityInfo* info = block.type_info; ushort entities_count = block.entities_count; block.entities_count += block.added_count; @@ -3056,7 +3057,7 @@ export struct EntityManager has_work = false; has_work |= updateEvents(); - id_manager.optimize(); + //id_manager.optimize(); has_work |= updateBlocks(); has_work |= changeEntities(); has_work |= removeEntities(); From 7a0ddf7494b94e26b828a77e18dd115a85c6efb4 Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 28 May 2020 15:53:05 +0200 Subject: [PATCH 35/58] Bugfix update -fixed critical bug with adding entities -fixed small bug with adding entity with replacement components which entity hasn't -added multiple asserts to faster bug detection in future --- source/bubel/ecs/manager.d | 136 +++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 43 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index a8954e0..0982531 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -2154,6 +2154,8 @@ export struct EntityManager return;*/ EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); + updateEntityInfoBlocks(new_info); + assert(new_block.added_count == 0); void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; @@ -2183,6 +2185,10 @@ export struct EntityManager cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size); } + new_block.entities_count++; + if (new_block != new_info.update_block) + new_info.update_block = new_block; + if (new_info.add_listeners) { foreach (listener; new_info.add_listeners) @@ -2190,7 +2196,7 @@ export struct EntityManager if (!info.systems[listener]) { callAddEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count, new_block.entities_count + 1); + new_block.entities_count - 1, new_block.entities_count); } } } @@ -2202,13 +2208,11 @@ export struct EntityManager if (info.systems[listener]) { callChangeEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count, new_block.entities_count + 1, del_ids); + new_block.entities_count - 1, new_block.entities_count, del_ids); } } } - new_block.entities_count++; - removeEntityNoID(entity, block); } @@ -2291,12 +2295,14 @@ export struct EntityManager //EntityInfo* new_info = getEntityInfo(ids[0 .. len]); EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); + updateEntityInfoBlocks(new_info); + assert(new_block.added_count == 0); void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; Entity* new_entity = cast(Entity*) start; new_entity.id = entity.id; - id_manager.update(*new_entity); //new_entity.updateID(); + id_manager.update(*new_entity); uint j = 0; uint k = 0; @@ -2342,6 +2348,10 @@ export struct EntityManager } } + new_block.entities_count++; + if (new_block != new_info.update_block) + new_info.update_block = new_block; + if (new_info.add_listeners) { foreach (listener; new_info.add_listeners) @@ -2349,7 +2359,7 @@ export struct EntityManager if (!info.systems[listener]) { callAddEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count, new_block.entities_count + 1); + new_block.entities_count - 1, new_block.entities_count); } } } @@ -2361,12 +2371,11 @@ export struct EntityManager if (info.systems[listener]) { callChangeEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count, new_block.entities_count + 1, new_ids); + new_block.entities_count - 1, new_block.entities_count, new_ids); } } } - new_block.entities_count++; removeEntityNoID(entity, block); } @@ -2487,14 +2496,12 @@ export struct EntityManager } } - if (new_index == 1) - threads[threadID].blockToUpdate.add(new_block); + if (new_index == 1 && info.update_block == block) + threads[threadID].infosToUpdate.add(info); Entity* new_entity = cast(Entity*) start; - //add_mutex.lock_nothrow(); new_entity.id = id_manager.getNewID(); - //add_mutex.unlock_nothrow(); - id_manager.update(*new_entity); //new_entity.updateID(); + id_manager.update(*new_entity); return new_entity; } @@ -2538,12 +2545,10 @@ export struct EntityManager } if (index == 1) - threads[threadID].blockToUpdate.add(block); + threads[threadID].infosToUpdate.add(block); Entity* entity = cast(Entity*) start; - //add_mutex.lock_nothrow(); entity.id = id_manager.getNewID(); - //add_mutex.unlock_nothrow(); id_manager.update(*entity); //entity.updateID(); return entity;*/ @@ -2589,7 +2594,7 @@ export struct EntityManager if (comp.component_id < info.deltas.length) { ushort delta = info.deltas[comp.component_id]; - if (delta != ushort.max) + if (delta != 0) { uint size = components[comp.component_id].size; if (size != 0) @@ -2607,14 +2612,12 @@ export struct EntityManager } } - if (index == 1) - threads[threadID].blockToUpdate.add(block); + if (index == 1 && info.update_block == block) + threads[threadID].infosToUpdate.add(info); Entity* entity = cast(Entity*) start; - //add_mutex.lock_nothrow(); entity.id = id_manager.getNewID(); - //add_mutex.unlock_nothrow(); - id_manager.update(*entity); //entity.updateID(); + id_manager.update(*entity); return entity; } @@ -2633,6 +2636,7 @@ export struct EntityManager block.id = 0; info.first_block = block; info.last_block = block; + info.update_block = block; } else if (block.entities_count >= info.max_entities) { @@ -2643,6 +2647,12 @@ export struct EntityManager new_block.id = cast(ushort)(block.id + 1); block = new_block; info.last_block = block; + ///make sure that update_block point to unfilled block + if (info.update_block.entities_count == info.max_entities) + { + assert(!info.update_block.added_count); + info.update_block = block; + } } return block; } @@ -2668,8 +2678,9 @@ export struct EntityManager block.id = 0; info.first_block = block; info.last_block = block; + info.update_block = block; } - else if (block.entities_count + block.added_count > info.max_entities) + else if (block.entities_count + block.added_count >= info.max_entities) { EntitiesBlock* last_block = info.last_block; @@ -2687,6 +2698,12 @@ export struct EntityManager new_block.id = cast(ushort)(block.id + 1); block = new_block; info.last_block = block; + ///make sure that update_block point to unfilled block + if (info.update_block.entities_count == info.max_entities) + { + assert(!info.update_block.added_count); + info.update_block = block; + } } return block; } @@ -2730,8 +2747,10 @@ export struct EntityManager { EntityInfo* info = block.type_info; - if (info.last_block.added_count) - updateBlock(info.last_block); + updateEntityInfoBlocks(info); + + assert(info.last_block.added_count == 0); + assert(info.last_block.entities_count > 0); info.last_block.entities_count--; @@ -2764,12 +2783,13 @@ export struct EntityManager block = info.last_block; entity.id = *cast(EntityID*)(block.dataBegin() + block.entities_count * EntityID.sizeof); - id_manager.update(*entity); //entity.updateID(); + id_manager.update(*entity); } block = info.last_block; if (block.entities_count == 0) { + assert(info.update_block is block); info.last_block = block.prev_block; if (info.first_block is block) { @@ -2778,7 +2798,9 @@ export struct EntityManager if (block.prev_block) { block.prev_block.next_block = null; - block.prev_block.added_count = 0; + info.update_block = block.prev_block; + assert(block.prev_block.added_count == 0); + //block.prev_block.added_count.atomicStore(cast(ushort)0); } allocator.freeBlock(block); } @@ -2852,7 +2874,7 @@ export struct EntityManager } } - private void callAddEntityListener(System* system, EntityInfo* info, + private static void callAddEntityListener(System* system, EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow { ListenerCallData data; @@ -2873,8 +2895,8 @@ export struct EntityManager } } - private void callRemoveEntityListener(System* system, EntityInfo* info, - EntitiesBlock* block, int begin, int end) @nogc nothrow + private static void callRemoveEntityListener(System* system, + EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow { ListenerCallData data; data.system = system; @@ -2921,9 +2943,34 @@ export struct EntityManager (cast(void function(ref ListenerCallData) nothrow @nogc) system.m_change_entity)(data); } + private void updateEntityInfoBlocks(EntityInfo* info) nothrow @nogc + { + while (info.last_block.added_count) + { + EntitiesBlock* block = info.update_block; + assert(block !is null); + if (block.entities_count == info.max_entities) + { + assert(!block.added_count); + block = block.next_block; + } + assert(!block.prev_block || !block.prev_block.added_count); + info.update_block = info.last_block; + + while (block) + { + assert(block.added_count.atomicLoad() > 0); + updateBlock(block); + block = block.next_block; + } + } + assert(info.last_block is info.update_block); + } + private void updateBlock(EntitiesBlock* block) @nogc nothrow { - if(block.added_count == 0)return; + //if(block.added_count == 0)return; + assert(block.added_count != 0); EntityInfo* info = block.type_info; ushort entities_count = block.entities_count; block.entities_count += block.added_count; @@ -2942,17 +2989,15 @@ export struct EntityManager private bool updateBlocks() { bool has_work = false; - //foreach (ref ThreadData thread; threads)thread.swapToUpdate(); foreach (ref ThreadData thread; threads) { - //thread.swapToUpdate(); - if (thread.blockToUpdatePrev.length) + if (thread.infosToUpdatePrev.length) has_work = true; - foreach (block; thread.blockToUpdatePrev) + foreach (info; thread.infosToUpdatePrev) { - updateBlock(block); + updateEntityInfoBlocks(info); } - thread.blockToUpdatePrev.clear(); + thread.infosToUpdatePrev.clear(); } return has_work; } @@ -3055,6 +3100,9 @@ export struct EntityManager swapData(); has_work = false; + // has_work |= updateBlocks(); + // has_work |= changeEntities(); + // has_work |= removeEntities(); has_work |= updateEvents(); //id_manager.optimize(); @@ -3477,7 +3525,7 @@ export struct EntityManager EntityInfo*[] comp_rem_info; ///alignment of whole entity - ushort alignment; //unused in linear-layout + ushort alignment; //unused in linear-layout TODO: to remove ///size of entity (with alignment respect) ushort size; ///max number of entities in block @@ -3496,6 +3544,8 @@ export struct EntityManager EntitiesBlock* first_block; ///pointer to last block EntitiesBlock* last_block; + ///pointer to last updated block + EntitiesBlock* update_block; } /************************************************************************************************************************ @@ -3642,9 +3692,9 @@ export struct EntityManager return change_entities_list[data_index]; } - ref Vector!(EntitiesBlock*) blockToUpdate() @nogc nothrow return + ref Vector!(EntityInfo*) infosToUpdate() @nogc nothrow return { - return blocks_to_update[data_index]; + return infos_to_update[data_index]; } ref Vector!EntityID entitiesToRemovePrev() @nogc nothrow return @@ -3657,9 +3707,9 @@ export struct EntityManager return change_entities_list[1 - data_index]; } - ref Vector!(EntitiesBlock*) blockToUpdatePrev() @nogc nothrow return + ref Vector!(EntityInfo*) infosToUpdatePrev() @nogc nothrow return { - return blocks_to_update[1 - data_index]; + return infos_to_update[1 - data_index]; } private: @@ -3671,7 +3721,7 @@ export struct EntityManager Vector!EntityID[2] entities_to_remove; SimpleVector[2] change_entities_list; - Vector!(EntitiesBlock*)[2] blocks_to_update; + Vector!(EntityInfo*)[2] infos_to_update; ubyte data_index = 0; } From 9af1cee60b3ce3bf07f3e06876749de3257d6224 Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 28 May 2020 16:11:27 +0200 Subject: [PATCH 36/58] SpaceShip demo update -added wave shooted upon death of boss tower -cleanup code a little bit -moved to new entityAdding method -fixed bug with changeing demos --- demos/source/app.d | 9 +- demos/source/demos/chipmunk2d.d | 19 - demos/source/demos/events.d | 19 - demos/source/demos/flag_component.d | 19 - demos/source/demos/simple.d | 2 +- demos/source/demos/snake.d | 47 +-- demos/source/demos/space_invaders.d | 549 +++++++++++++++++----------- demos/source/gui/manager.d | 1 + 8 files changed, 368 insertions(+), 297 deletions(-) delete mode 100644 demos/source/demos/chipmunk2d.d delete mode 100644 demos/source/demos/events.d delete mode 100644 demos/source/demos/flag_component.d diff --git a/demos/source/app.d b/demos/source/app.d index 9017f8d..ede93b5 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -96,6 +96,7 @@ struct Launcher void switchDemo(void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, void function(vec2, Tool, int) tool, const (char)* tips) { gui_manager.clear(); + //launcher.ent if(this.end)this.end(); @@ -262,7 +263,7 @@ void mainLoop(void* arg) if(launcher.tool && launcher.tool_repeat != 0 && launcher.mouse.left && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) { float range = 500.0 / cast(float)launcher.tool_repeat; - launcher.repeat_time += launcher.delta_time * 100; + launcher.repeat_time += launcher.delta_time; while(launcher.repeat_time > range) { launcher.repeat_time -= range; @@ -463,7 +464,7 @@ 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, 250), ImGuiCond_Once); + igSetNextWindowSize(ImVec2(250, 500), ImGuiCond_Once); if(igBegin("Demo",&launcher.show_demo_wnd,0)) { ImDrawList* draw_list = igGetWindowDrawList(); @@ -745,8 +746,8 @@ int main(int argc, char** argv) { import demos.simple; import demos.space_invaders; - launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips); - // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips); + // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips); + launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips); } int key_num; diff --git a/demos/source/demos/chipmunk2d.d b/demos/source/demos/chipmunk2d.d deleted file mode 100644 index 96e5fa6..0000000 --- a/demos/source/demos/chipmunk2d.d +++ /dev/null @@ -1,19 +0,0 @@ -module demos.chipmunk2d; - -import app; - -import bindbc.sdl; - -import cimgui.cimgui; - -import bubel.ecs.attributes; -import bubel.ecs.core; -import bubel.ecs.entity; -import bubel.ecs.manager; -import bubel.ecs.std; - -import ecs_utils.gfx.texture; -import ecs_utils.math.vector; -import ecs_utils.utils; - -extern(C): \ No newline at end of file diff --git a/demos/source/demos/events.d b/demos/source/demos/events.d deleted file mode 100644 index 6215160..0000000 --- a/demos/source/demos/events.d +++ /dev/null @@ -1,19 +0,0 @@ -module demos.events; - -import app; - -import bindbc.sdl; - -import cimgui.cimgui; - -import bubel.ecs.attributes; -import bubel.ecs.core; -import bubel.ecs.entity; -import bubel.ecs.manager; -import bubel.ecs.std; - -import ecs_utils.gfx.texture; -import ecs_utils.math.vector; -import ecs_utils.utils; - -extern(C): \ No newline at end of file diff --git a/demos/source/demos/flag_component.d b/demos/source/demos/flag_component.d deleted file mode 100644 index 392164e..0000000 --- a/demos/source/demos/flag_component.d +++ /dev/null @@ -1,19 +0,0 @@ -module demos.flag_component; - -import app; - -import bindbc.sdl; - -import cimgui.cimgui; - -import bubel.ecs.attributes; -import bubel.ecs.core; -import bubel.ecs.entity; -import bubel.ecs.manager; -import bubel.ecs.std; - -import ecs_utils.gfx.texture; -import ecs_utils.math.vector; -import ecs_utils.utils; - -extern(C): \ No newline at end of file diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 5e82d27..313cc00 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -52,7 +52,7 @@ struct DrawSystem struct EntitiesData { uint length; - uint thread_id; + //uint thread_id; uint job_id; @readonly CTexture[] textures; @readonly CLocation[] locations; diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 50f7729..01e9a36 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -129,9 +129,10 @@ struct Snake } if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return; } - CILocation* location = apple_tmpl.getComponent!CILocation; - *location = random_pos; - Entity* apple = launcher.manager.addEntity(apple_tmpl); + //CILocation* location = apple_tmpl.getComponent!CILocation; + //*location = random_pos; + //Entity* apple = + launcher.manager.addEntity(apple_tmpl,[CILocation(random_pos).ref_].staticArray); } } @@ -366,8 +367,8 @@ struct MoveSystem mixin ECS.System!64; EntityTemplate* destroy_template; - CLocation* destroy_location; - CParticleVector* destroy_vector; + //CLocation* destroy_location; + //CParticleVector* destroy_vector; struct EntitiesData { @@ -381,8 +382,8 @@ struct MoveSystem void setTemplates() { destroy_template = snake.snake_destroy_particle; - destroy_location = destroy_template.getComponent!CLocation; - destroy_vector = destroy_template.getComponent!CParticleVector; + //destroy_location = destroy_template.getComponent!CLocation; + //destroy_vector = destroy_template.getComponent!CParticleVector; } void moveLocation(ref CILocation location, CMovement.Direction direction) @@ -436,24 +437,26 @@ struct MoveSystem case MapElement.Type.snake: foreach(loc; data.snakes[i].parts) { - destroy_location.x = loc.x * 16; - destroy_location.y = loc.y * 16; + //destroy_location.x = loc.x * 16; + //destroy_location.y = loc.y * 16; snake.element(MapElement(MapElement.Type.empty, EntityID()),loc); - launcher.manager.addEntity(snake.snake_destroy_particle); + launcher.manager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(loc * 16)).ref_].staticArray); + + CLocation destroy_location; foreach(j;0..10) { destroy_location.x = loc.x * 16 + randomf() * 8 - 4; destroy_location.y = loc.y * 16 + randomf() * 8 - 4; - destroy_vector.velocity = vec2(randomf(),randomf())*0.4-0.2; + //destroy_vector.velocity = vec2(randomf(),randomf())*0.4-0.2; snake.element(MapElement(MapElement.Type.empty, EntityID()),loc); - launcher.manager.addEntity(snake.snake_destroy_particle); + launcher.manager.addEntity(snake.snake_destroy_particle, [destroy_location.ref_, CParticleVector(vec2(randomf(),randomf())*0.4-0.2).ref_].staticArray); } } - destroy_location.x = new_location.x * 16; - destroy_location.y = new_location.y * 16; + //destroy_location.x = new_location.x * 16; + //destroy_location.y = new_location.y * 16; snake.element(MapElement(MapElement.Type.empty, EntityID()),new_location); - launcher.manager.addEntity(snake.snake_destroy_particle); + launcher.manager.addEntity(snake.snake_destroy_particle,[CLocation(cast(vec2)(new_location * 16)).ref_].staticArray); launcher.manager.removeEntity(data.entities[i].id); break; @@ -796,9 +799,9 @@ void snakeStart() { ushort[4] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id]; snake.snake_tmpl = launcher.manager.allocateTemplate(components); - CILocation* loc_comp = snake.snake_tmpl.getComponent!CILocation; - *loc_comp = ivec2(2,2); - launcher.manager.addEntity(snake.snake_tmpl); + //CILocation* loc_comp = snake.snake_tmpl.getComponent!CILocation; + //*loc_comp = ivec2(2,2); + launcher.manager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray); } { @@ -846,15 +849,15 @@ void snakeTool(vec2 position, Tool tool, int size) CLocation* location = tmpl.getComponent!CLocation; if(location) { - position.x += (randomf - 0.5) * size; - position.y += (randomf - 0.5) * size; + position.x += (randomf() - 0.5) * size; + position.y += (randomf() - 0.5) * size; *location = position; } CILocation* ilocation = tmpl.getComponent!CILocation; if(ilocation) { - position.x += (randomf - 0.5) * size; - position.y += (randomf - 0.5) * size; + position.x += (randomf() - 0.5) * size; + position.y += (randomf() - 0.5) * size; ivec2 ipos; ipos.x = cast(int)(position.x / 16); ipos.y = cast(int)(position.y / 16); diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index c047d25..5615f0d 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -40,6 +40,7 @@ struct SpaceInvaders EntityTemplate* enemy_tmpl; EntityTemplate* ship_tmpl; EntityTemplate* laser_tmpl; + EntityTemplate*[5] bullet_tmpl; Texture texture; ShootGrid* shoot_grid; @@ -55,9 +56,13 @@ struct SpaceInvaders ~this() @nogc nothrow { if(shoot_grid)Mallocator.dispose(shoot_grid); - launcher.manager.freeTemplate(enemy_tmpl); - launcher.manager.freeTemplate(ship_tmpl); - launcher.manager.freeTemplate(laser_tmpl); + if(enemy_tmpl)launcher.manager.freeTemplate(enemy_tmpl); + if(ship_tmpl)launcher.manager.freeTemplate(ship_tmpl); + if(laser_tmpl)launcher.manager.freeTemplate(laser_tmpl); + foreach (EntityTemplate* tmpl; bullet_tmpl) + { + if(tmpl)launcher.manager.freeTemplate(tmpl); + } texture.destory(); } } @@ -115,7 +120,7 @@ struct CLocation alias value this; - vec2 value; + vec2 value = vec2(0); } struct CScale @@ -192,7 +197,7 @@ struct CGuild byte guild; } -struct CLaser +struct CBullet { mixin ECS.Component; @@ -408,12 +413,35 @@ struct CParticleEmitterTime { mixin ECS.Component; - float time; + float time = 0; } +///You can create separate component for every kind of spawned entities but it's not practial due to archetype fragmentation. +///Second approach can be commented code. It's gives good flexibility inchoosing entity, but it limits to one entity. +///Instead of entity it can be array of templates which is good solution, but if possibilities is known at time of game development it +///can be simply index/enum for type of spawn. Bad thing about this solution is problem witch merging multiple spawning types during +///gameplay, i.e. giving buff which cast firebols upon death. +struct CSpawnUponDeath +{ + mixin ECS.Component; + + enum Type + { + flashes_emitter, + } + + //EntityID parent; + //EntityTemplate* tmpl; + Type type; +} + +///This component can be replaced by "CSpawnUponDeath" but I want to gives possibility to add this component to every entity +///during gameplay. End application works exacly the same way for every demo so I can't use different way as adding component. struct CShootWaveUponDeath { mixin ECS.Component; + + CWeapon.Type bullet_type; } /*####################################################################################################################### @@ -604,7 +632,7 @@ struct ShootGridManager struct EntitiesData { uint length; - uint thread_id; + //uint thread_id; const (Entity)[] entity; @readonly CLocation[] locations; @readonly CShootGrid[] grid_flag; @@ -748,7 +776,8 @@ struct ShipWeaponSystem weapon_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,0); weapon_tmpl.getComponent!CGuild().guild = 1; weapon_tmpl.getComponent!CScale().value = vec2(4,16); - weapon_tmpl.getComponent!CWeapon().level = 1; + //weapon_tmpl.getComponent!CWeapon().level = 1; + *weapon_tmpl.getComponent!CWeapon() = CWeapon(0,CWeapon.Type.canon,1); weapon_tmpl.getComponent!CDepth().depth = -1; weapon_tmpl.getComponent!CTexture().coords = vec4(136,96,4,16)*px; weapon_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,12); @@ -801,7 +830,8 @@ struct ShipWeaponSystem [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, - CChildren.component_id, CDepth.component_id, CTargetParent.component_id].staticArray + CChildren.component_id, CDepth.component_id, CTargetParent.component_id, + CSpawnUponDeath.component_id, CShootWaveUponDeath.component_id].staticArray ); CTexture* tex_comp = tower1_tmpl.getComponent!CTexture; @@ -813,6 +843,7 @@ struct ShipWeaponSystem tower1_tmpl.getComponent!CInit().type = CInit.Type.tower; tower1_tmpl.getComponent!CHitPoints().value = 10; tower1_tmpl.getComponent!CDepth().depth = -2; + tower1_tmpl.getComponent!CShootWaveUponDeath().bullet_type = CWeapon.Type.canon; tower1_tmpl.getComponent!CTargetParent().rel_pos = vec2(-33,2); tower2_tmpl = launcher.manager.allocateTemplate(tower1_tmpl); @@ -865,22 +896,12 @@ struct ShipWeaponSystem { foreach(i; 0..data.length) { - /*if(data.children[i].childern.length != 0)continue; - EntityID[3] weapons; - laser1_tmpl.getComponent!CTargetParent().parent = data.entity[i].id; - laser2_tmpl.getComponent!CTargetParent().parent = data.entity[i].id; - main_weapon_tmpl.getComponent!CTargetParent().parent = data.entity[i].id; - weapons[0] = launcher.manager.addEntity(laser1_tmpl).id; - weapons[1] = launcher.manager.addEntity(laser2_tmpl).id; - weapons[2] = launcher.manager.addEntity(main_weapon_tmpl).id; - data.children[i].childern = Mallocator.makeArray(weapons);*/ final switch(data.init[i].type) { case CInit.Type.space_ship:ship.add(&data.entity[i]);break; case CInit.Type.tower:tower.add(&data.entity[i]);break; case CInit.Type.boss:boss.add(&data.entity[i]);break; } - } } } @@ -942,7 +963,7 @@ struct DrawSystem struct EntitiesData { uint length; - uint thread_id; + //uint thread_id; uint job_id; @readonly CTexture[] textures; @readonly CLocation[] locations; @@ -1046,8 +1067,6 @@ struct LaserShootingSystem mixin ECS.System!32; bool shoot = false; - //static float[18] laser_shoot_times = [500,400,300,200,100,50,25,10,5,2,1,0.8,0.6,0.5,0.4,0.3,0.2,0.1]; - //static float[18] laser_shoot_disp = [0,0,0,0,0.05,0.06,0.08,0.1,0.14,0.18,0.2,0.25,0.26,0.27,0.28,0.29,0.3,0.4]; __gshared vec4[] fire_frames = [vec4(96,64,8,16)*px,vec4(104,64,8,16)*px,vec4(112,64,8,16)*px,vec4(120,64,8,16)*px,vec4(128,64,8,16)*px, vec4(136,64,8,16)*px,vec4(144,64,8,16)*px,vec4(152,64,8,16)*px,vec4(160,64,8,16)*px]; @@ -1055,16 +1074,10 @@ struct LaserShootingSystem // __gshared vec4[] fire_frames = [vec4(0,160,8,16)*px,vec4(16,160,16,16)*px,vec4(32,160,16,16)*px,vec4(48,160,16,16)*px,vec4(64,160,16,16)*px, // vec4(80,160,16,16)*px,vec4(96,160,16,16)*px,vec4(112,160,16,16)*px]; - /*CLocation* laser_location; - CVelocity* laser_velocity; - CGuild* laser_guild;*/ - struct EntitiesData { ///variable named "length" contain entites count uint length; - ///variable named "length" contain thread identifier - uint thread_id; CWeapon[] laser; @readonly CLocation[] location; @readonly CGuild[] guild; @@ -1076,77 +1089,53 @@ struct LaserShootingSystem @optional @readonly CRotation[] rotation; } - struct ThreadData - { - EntityTemplate* laser_tmpl; - CLocation* laser_location; - CVelocity* laser_velocity; - CGuild* laser_guild; + //EntityTemplate* laser_tmpl; + EntityTemplate* fire_tmpl; - EntityTemplate* fire_tmpl; - CLocation* fire_location; - CVelocity* fire_velocity; - CRotation* fire_rotation; - } - - ThreadData[] threads; + //EntityTemplate*[5] bullet_tmpl; ///Called inside "registerSystem" function void onCreate() { - threads = Mallocator.makeArray!ThreadData(32); - threads[0].laser_tmpl = launcher.manager.allocateTemplate( + /*bullet_tmpl[0] = launcher.manager.allocateTemplate( [CLocation.component_id, CTexture.component_id, CVelocity.component_id, - CScale.component_id, CLaser.component_id, CGuild.component_id].staticArray + CScale.component_id, CBullet.component_id, CGuild.component_id].staticArray ); + bullet_tmpl[0].getComponent!CTexture().coords = vec4(0,24,2,8)*px; + bullet_tmpl[0].getComponent!CScale().value = vec2(2,8); - CTexture* tex_comp = threads[0].laser_tmpl.getComponent!CTexture; - //tex_comp.tex = space_invaders.texture;//laser_tex; - tex_comp.coords = vec4(0*px,24*px,2*px,8*px); - CScale* scale_comp = threads[0].laser_tmpl.getComponent!CScale; - scale_comp.value = vec2(2,8); - threads[0].laser_location = threads[0].laser_tmpl.getComponent!CLocation; - threads[0].laser_velocity = threads[0].laser_tmpl.getComponent!CVelocity; - threads[0].laser_guild = threads[0].laser_tmpl.getComponent!CGuild; + bullet_tmpl[1] = launcher.manager.allocateTemplate(bullet_tmpl[0]); + bullet_tmpl[2] = launcher.manager.allocateTemplate(bullet_tmpl[0]); + bullet_tmpl[2].getComponent!CTexture().coords = vec4(64,32,8,16)*px; + bullet_tmpl[2].getComponent!CScale().value = vec2(8,16); + bullet_tmpl[3] = launcher.manager.allocateTemplate(bullet_tmpl[0]); + bullet_tmpl[3].getComponent!CTexture().coords = vec4(56,32,2,2)*px; + bullet_tmpl[3].getComponent!CScale().value = vec2(2,2); + // bullet_tmpl[3].getComponent!CTexture().coords = vec4(48,32,8,8)*px; + // bullet_tmpl[3].getComponent!CScale().value = vec2(8,8); + bullet_tmpl[4] = launcher.manager.allocateTemplate(bullet_tmpl[0]);*/ - threads[0].fire_tmpl = launcher.manager.allocateTemplate( + + fire_tmpl = launcher.manager.allocateTemplate( [CLocation.component_id, CTexture.component_id, CScale.component_id, CAnimation.component_id, CParticle.component_id, CRotation.component_id, CVelocity.component_id, CDamping.component_id].staticArray ); - tex_comp = threads[0].fire_tmpl.getComponent!CTexture; - //tex_comp.tex = space_invaders.texture;//laser_tex; - tex_comp.coords = vec4(96*px,64*px,8*px,16*px); - scale_comp = threads[0].fire_tmpl.getComponent!CScale; - scale_comp.value = vec2(8,16); - threads[0].fire_location = threads[0].fire_tmpl.getComponent!CLocation; - threads[0].fire_rotation = threads[0].fire_tmpl.getComponent!CRotation; - threads[0].fire_velocity = threads[0].fire_tmpl.getComponent!CVelocity; - threads[0].fire_tmpl.getComponent!(CParticle).life = 300; - *threads[0].fire_tmpl.getComponent!(CAnimation) = CAnimation(fire_frames, 0, 3); - - foreach(ref ThreadData thread;threads[1..$]) - { - thread.laser_tmpl = launcher.manager.allocateTemplate(threads[0].laser_tmpl); - thread.laser_location = thread.laser_tmpl.getComponent!CLocation; - thread.laser_velocity = thread.laser_tmpl.getComponent!CVelocity; - thread.laser_guild = thread.laser_tmpl.getComponent!CGuild; - thread.fire_tmpl = launcher.manager.allocateTemplate(threads[0].fire_tmpl); - thread.fire_location = thread.fire_tmpl.getComponent!CLocation; - thread.fire_rotation = thread.fire_tmpl.getComponent!CRotation; - thread.fire_velocity = thread.fire_tmpl.getComponent!CVelocity; - } - //laser_location = space_invaders.laser_tmpl.getComponent!CLocation; + fire_tmpl.getComponent!CTexture().coords = vec4(96,64,8,16)*px; + fire_tmpl.getComponent!CScale().value = vec2(8,16); + fire_tmpl.getComponent!(CParticle).life = 300; + *fire_tmpl.getComponent!(CAnimation) = CAnimation(fire_frames, 0, 3); } void onDestroy() { - foreach(ref ThreadData thread;threads[1..$]) + //launcher.manager.freeTemplate(laser_tmpl); + /*foreach (EntityTemplate* tmpl; bullet_tmpl) { - launcher.manager.freeTemplate(thread.laser_tmpl); - } - Mallocator.dispose(threads); + launcher.manager.freeTemplate(tmpl); + }*/ + launcher.manager.freeTemplate(fire_tmpl); } bool onBegin() @@ -1164,7 +1153,6 @@ struct LaserShootingSystem void onUpdate(EntitiesData data) { - ThreadData* thread = &threads[data.thread_id]; //conditional branch for whole entities block if(shoot || data.auto_shoot) { @@ -1174,58 +1162,65 @@ struct LaserShootingSystem laser.shoot_time += launcher.delta_time; while(laser.shoot_time > CWeapon.levels[laser.level - 1].reload_time) { + CVelocity laser_velocity; + CGuild laser_guild; + CLocation laser_location; + CVelocity fire_velocity; + CLocation fire_location; + CRotation fire_rotation; + laser.shoot_time -= CWeapon.levels[laser.level - 1].reload_time; - thread.laser_location.value = data.location[i]; + laser_location.value = data.location[i]; - thread.laser_velocity.value = vec2((randomf()*2-1) * CWeapon.levels[laser.level - 1].dispersion,1);//data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); - if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down)thread.laser_velocity.y = -1; + laser_velocity.value = vec2((randomf()*2-1) * CWeapon.levels[laser.level - 1].dispersion,1);//data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); + if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down)laser_velocity.y = -1; - thread.laser_guild.guild = data.guild[i].guild; + laser_guild.guild = data.guild[i].guild; - if(laser.level < 3)thread.laser_velocity.value = thread.laser_velocity.value * 0.4f; + if(laser.level < 3)laser_velocity.value = laser_velocity.value * 0.4f; if(data.velocity) { - thread.fire_velocity.value = data.velocity[i]; - //thread.laser_velocity.value += data.velocity[i] * 0.5; + fire_velocity.value = data.velocity[i]; + //laser_velocity.value += data.velocity[i] * 0.5; } - else thread.fire_velocity.value = vec2(0,0); + else fire_velocity.value = vec2(0,0); - thread.fire_location.value = data.location[i]; + fire_location.value = data.location[i]; if(data.shoot_direction[i].direction == Direction.down) { - thread.fire_rotation.value = PI; - //thread.fire_location.value.y -= 16; + fire_rotation.value = PI; + //fire_location.value.y -= 16; } else { - thread.fire_rotation.value = 0; - //thread.fire_location.value.y += 24; + fire_rotation.value = 0; + //fire_location.value.y += 24; } if(data.rotation) { float sinn = sinf(data.rotation[i]); float coss = cosf(data.rotation[i]); - float x = thread.laser_velocity.y*sinn + thread.laser_velocity.x*coss; - float y = thread.laser_velocity.y*coss + thread.laser_velocity.x*sinn; - thread.laser_velocity.value = vec2(x,y); - thread.fire_rotation.value = data.rotation[i]; + float x = laser_velocity.y*sinn + laser_velocity.x*coss; + float y = laser_velocity.y*coss + laser_velocity.x*sinn; + laser_velocity.value = vec2(x,y); + fire_rotation.value = data.rotation[i]; if(data.weapon_location) { vec2 rel_pos = vec2(data.weapon_location[i].rel_pos.y*sinn+data.weapon_location[i].rel_pos.x*coss, data.weapon_location[i].rel_pos.y*coss+data.weapon_location[i].rel_pos.x*sinn); - thread.laser_location.value += rel_pos; - thread.fire_location.value += rel_pos; + laser_location.value += rel_pos; + fire_location.value += rel_pos; } } else if(data.weapon_location) { - thread.laser_location.value += data.weapon_location[i].rel_pos; - thread.fire_location.value += data.weapon_location[i].rel_pos; + laser_location.value += data.weapon_location[i].rel_pos; + fire_location.value += data.weapon_location[i].rel_pos; } - launcher.manager.addEntity(thread.laser_tmpl); - launcher.manager.addEntity(thread.fire_tmpl); + launcher.manager.addEntity(space_invaders.bullet_tmpl[data.laser[i].type],[laser_velocity.ref_, laser_guild.ref_, laser_location.ref_].staticArray); + launcher.manager.addEntity(fire_tmpl,[fire_location.ref_, fire_rotation.ref_, fire_velocity.ref_].staticArray); } } } @@ -1287,7 +1282,7 @@ struct LaserCollisionSystem uint length; const (Entity)[] entity; @readonly CLocation[] location; - @readonly CLaser[] laser; + @readonly CBullet[] laser; @readonly CGuild[] guild; } @@ -1312,69 +1307,63 @@ struct ParticleEmittingSystem struct EntitiesData { uint length; - uint thread_id; + //uint thread_id; CParticleEmitterTime[] emit_time; @readonly CLocation[] location; @readonly CParticleEmitter[] emitter; @optional @readonly CVelocity[] velocity; + @optional @readonly CDepth[] depth; } + + __gshared vec4[] flashes = [vec4(224,0,16,16)*px,vec4(240,0,16,16)*px,vec4(256,0,16,16)*px,vec4(272,0,16,16)*px,vec4(288,0,16,16)*px, + vec4(304,0,16,16)*px,vec4(320,0,16,16)*px]; - struct Thread - { - EntityTemplate*[1] templates; - } - - Thread[] threads; + EntityTemplate*[1] templates; void onCreate() { - threads = Mallocator.makeArray!Thread(32); - - threads[0].templates[0] = launcher.manager.allocateTemplate( + templates[0] = launcher.manager.allocateTemplate( [CLocation.component_id, CTexture.component_id, CScale.component_id, CAnimation.component_id, CParticle.component_id, CRotation.component_id, - CVelocity.component_id, CDamping.component_id].staticArray); - - foreach(ref thread;threads[1 .. $]) - { - thread.templates[0] = launcher.manager.allocateTemplate(threads[0].templates[0]); - } + CVelocity.component_id, CDamping.component_id, CDepth.component_id].staticArray); + *templates[0].getComponent!CAnimation() = CAnimation(flashes,0,2); + *templates[0].getComponent!CParticle() = CParticle(350); + //*templates[0].getComponent!CDepth() = CDepth(-3); } void onDestroy() { - foreach(ref thread;threads[1 .. $]) + foreach(tmpl; templates) { - foreach(tmpl; thread.templates) - { - launcher.manager.freeTemplate(tmpl); - } - } - Mallocator.dispose(threads); + launcher.manager.freeTemplate(tmpl); + } } void onUpdate(EntitiesData data) { - Thread* thread = &threads[data.thread_id]; foreach(i;0..data.length) { data.emit_time[i].time -= launcher.delta_time; while(data.emit_time[i].time < 0) { + CVelocity velocity; + CDepth depth; + CParticleEmitter* emitter = &data.emitter[i]; data.emit_time[i].time += emitter.time_range.x + randomf() * emitter.time_range.y; - EntityTemplate* tmpl = thread.templates[emitter.tmpl_id]; - CLocation* location = tmpl.getComponent!CLocation; - if(location)location.value = data.location[i]; - if(data.velocity) { - CVelocity* velocity = tmpl.getComponent!CVelocity; - if(velocity)velocity.value = data.velocity[i]; + velocity.value = data.velocity[i]; } - launcher.manager.addEntity(tmpl); + + if(data.depth) + { + depth.depth = data.depth[i]; + } + + launcher.manager.addEntity(templates[0],[data.location[i].ref_,velocity.ref_,depth.ref_].staticArray); } } } @@ -1617,10 +1606,7 @@ struct HitPointsSystem __gshared vec4[] explosion_laser_frames = [vec4(80,128,16,16)*px,vec4(96,128,16,16)*px,vec4(112,128,16,16)*px,vec4(128,128,16,16)*px,vec4(144,128,16,16)*px,vec4(160,128,16,16)*px,vec4(176,128,16,16)*px,vec4(192,128,16,16)*px,vec4(208,128,16,16)*px]; EntityTemplate* upgrade_tmpl; - CLocation* upgrade_location; - EntityTemplate* explosion_tmpl; - CLocation* explosion_location; struct EntitiesData { @@ -1629,29 +1615,31 @@ struct HitPointsSystem void onCreate() { - upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id, CAnimation.component_id, CAnimationLooped.component_id].staticArray); - CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; + upgrade_tmpl = launcher.manager.allocateTemplate( + [CVelocity.component_id, CLocation.component_id, CTexture.component_id, + CScale.component_id, CUpgrade.component_id, CAnimation.component_id, + CAnimationLooped.component_id].staticArray); //tex_comp.tex = space_invaders.texture;//ship_tex; - tex_comp.coords = vec4(0*px,32*px,16*px,16*px); + upgrade_tmpl.getComponent!CTexture().coords = vec4(0*px,32*px,16*px,16*px); *upgrade_tmpl.getComponent!CAnimation = CAnimation(upgrade_laser_frames, 0, 1); - CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; - vel_comp.value = vec2(0,-0.1); - upgrade_location = upgrade_tmpl.getComponent!CLocation; + upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.1); - explosion_tmpl = launcher.manager.allocateTemplate([CDepth.component_id, CParticle.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CAnimation.component_id].staticArray); + explosion_tmpl = launcher.manager.allocateTemplate( + [CDepth.component_id, CParticle.component_id, CLocation.component_id, + CTexture.component_id, CScale.component_id, CAnimation.component_id].staticArray); //explosion_tmpl.getComponent!(CTexture).tex = space_invaders.texture; *explosion_tmpl.getComponent!CAnimation = CAnimation(explosion_laser_frames, 0, 1.333); explosion_tmpl.getComponent!(CParticle).life = 600; *explosion_tmpl.getComponent!CDepth = -1; - explosion_location = explosion_tmpl.getComponent!CLocation; } void onDestroy() { launcher.manager.freeTemplate(upgrade_tmpl); + launcher.manager.freeTemplate(explosion_tmpl); } - void handleEvent(Entity* entity, EDamage event) + /*void handleEvent(Entity* entity, EDamage event) { CHitPoints* hp = entity.getComponent!CHitPoints; if(*hp <= 0)return; @@ -1663,7 +1651,7 @@ struct HitPointsSystem } CHitMark* hit_mark = entity.getComponent!CHitMark; if(hit_mark)hit_mark.value = 127; - } + }*/ void handleEvent(Entity* entity, EBulletHit event) { @@ -1690,11 +1678,9 @@ struct HitPointsSystem { if(randomRange(0, 1000) < 5) { - *upgrade_location = *location; - launcher.manager.addEntity(upgrade_tmpl); + launcher.manager.addEntity(upgrade_tmpl,[location.ref_].staticArray); } - *explosion_location = *location; - launcher.manager.addEntity(explosion_tmpl); + launcher.manager.addEntity(explosion_tmpl,[location.ref_].staticArray); } } launcher.manager.removeEntity(entity.id); @@ -1720,6 +1706,55 @@ struct ChildDestroySystem } } +struct ShootWaveSystem +{ + mixin ECS.System; + + struct EntitiesData + { + CLocation[] location; + CShootWaveUponDeath[] shoot_wave; + } + + vec2[] dirs; + + void onCreate() + { + enum count = 24; + dirs = Mallocator.makeArray!vec2(count); + float step = 2 * PI / cast(float)count; + foreach(i;0..count) + { + float angle = step * i; + dirs[i] = vec2(sinf(angle),cosf(angle)) * 0.2; + } + } + + void onDestroy() + { + Mallocator.dispose(dirs); + } + + void handleEvent(Entity* entity, EDeath event) + { + + CShootWaveUponDeath* wave = entity.getComponent!CShootWaveUponDeath; + CLocation* location = entity.getComponent!CLocation; + CGuild* guild = entity.getComponent!CGuild; + + //LaserShootingSystem.bullet_tmpl + EntityTemplate* tmpl = space_invaders.bullet_tmpl[wave.bullet_type]; + foreach(dir;dirs) + { + if(guild)launcher.manager.addEntity(tmpl,[location.ref_,guild.ref_,CVelocity(dir).ref_].staticArray); + else launcher.manager.addEntity(tmpl,[location.ref_,CVelocity(dir).ref_].staticArray); + } + //launcher.manager.addEntity(tmpl);//,[location.ref_].staticArray); + + //launcher.manager.addEntity(space_invaders.bullet_tmpl[0]); + } +} + struct PartsDestroySystem { mixin ECS.System; @@ -1738,9 +1773,14 @@ struct PartsDestroySystem flashes_emitter = launcher.manager.allocateTemplate( [ CVelocity.component_id, CLocation.component_id, CParticleEmitter.component_id, - CParticleEmitterTime.component_id, CTargetParent.component_id + CParticleEmitterTime.component_id, CTargetParent.component_id, CDepth.component_id ].staticArray); - *flashes_emitter.getComponent!CParticleEmitter() = CParticleEmitter(vec2(0,0), vec2(400,400), 0); + *flashes_emitter.getComponent!CParticleEmitter() = CParticleEmitter(vec2(0,0), vec2(800,1600), 0); + } + + void onDestroy() + { + launcher.manager.freeTemplate(flashes_emitter); } void handleEvent(Entity* entity, EDestroyedChild event) @@ -1752,17 +1792,24 @@ struct PartsDestroySystem if(init.type == CInit.Type.boss) { CChildren* children = entity.getComponent!CChildren; - foreach(EntityID child; children.childern) + foreach(ref EntityID child; children.childern) { if(child == event.id) { Entity* child_entity = launcher.manager.getEntity(child); if(child_entity) { + CLocation location; CTargetParent* target_parent = child_entity.getComponent!CTargetParent; + CDepth* target_depth = child_entity.getComponent!CDepth; + CLocation* target_location = child_entity.getComponent!CLocation; + //CVelocity* velocity = child_entity.getComponent!CTargetParent; + + if(target_location)location = *target_location; *flashes_emitter.getComponent!CTargetParent() = *target_parent; - launcher.manager.addEntity(flashes_emitter); + if(target_depth)child = launcher.manager.addEntity(flashes_emitter, [target_depth.ref_, location.ref_].staticArray).id; + else child = launcher.manager.addEntity(flashes_emitter, [location.ref_].staticArray).id; } break; } @@ -1793,7 +1840,7 @@ struct ClampPositionSystem @optional @readonly CColliderScale[] collider_scale; @optional @readonly CScale[] scale; - @optional const (CLaser)[] laser; + @optional const (CBullet)[] laser; @optional const (CUpgrade)[] upgrade; //@optional CVelocity[] velocity; //@optional const (CSideMove)[] side_move; @@ -1891,7 +1938,7 @@ struct MovementSystem const (CVelocity)[] velocity; //components are treated as required by default CLocation[] locations; - //@optional const (CLaser)[] laser; + //@optional const (CBullet)[] laser; const (Entity)[] entities; //@optional CSideMove[] side_move; @@ -1927,8 +1974,10 @@ struct AnimationSystem foreach(i;0..data.length) { data.animation[i].time += dt * data.animation[i].speed; - while(data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; - data.texture[i].coords = data.animation[i].frames[cast(int)(data.animation[i].time)]; + while(cast(uint)data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; + if(cast(uint)(data.animation[i].time) >= data.animation[i].frames.length)assert(0); + uint index = cast(uint)(data.animation[i].time); + if(index < data.animation[i].frames.length)data.texture[i].coords = data.animation[i].frames[index]; } } else @@ -1936,8 +1985,9 @@ struct AnimationSystem foreach(i;0..data.length) { data.animation[i].time += dt * data.animation[i].speed; - if(data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time = data.animation[i].frames.length - 0.1; - data.texture[i].coords = data.animation[i].frames[cast(int)(data.animation[i].time)]; + if(cast(uint)data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time = data.animation[i].frames.length - 0.9; + uint index = cast(uint)(data.animation[i].time); + if(index < data.animation[i].frames.length)data.texture[i].coords = data.animation[i].frames[index]; } } @@ -2070,6 +2120,66 @@ struct CShipIterator } } +/*struct SpawnUponDeathSystem +{ + mixin ECS.System; + + struct EntitiesData + { + @readonly CSpawnUponDeath[] spawn; + @optional CTargetParent[] parent; + } + + EntityTemplate* flashes_emitter; + + void onCreate() + { + flashes_emitter = launcher.manager.allocateTemplate( + [ + CVelocity.component_id, CLocation.component_id, CParticleEmitter.component_id, + CParticleEmitterTime.component_id, CTargetParent.component_id + ].staticArray); + *flashes_emitter.getComponent!CParticleEmitter() = CParticleEmitter(vec2(0,0), vec2(400,400), 0); + } + + void onDestroy() + { + launcher.manager.freeTemplate(flashes_emitter); + } + + void onRemoveEntity(EntitiesData data) + { + //CSpawnUponDeath[] spawn = + switch(data.spawn[0].type) + { + case CSpawnUponDeath.Type.flashes_emitter: + if(data.parent) + { + /*Entity* parent_entity = launcher.manager.getEntity(data.parent[0].parent); + CChildren* children = entity.getComponent!CChildren; + foreach(ref EntityID child; children.childern) + { + if(child == event.id) + { + Entity* child_entity = launcher.manager.getEntity(child); + if(child_entity) + { + *flashes_emitter.getComponent!CTargetParent = data.parent[0]; + launcher.manager.addEntity(flashes_emitter); + //child = launcher.manager.addEntity(flashes_emitter); + } + break; + } + } + } + break; + default:break; + } + } + + //void handleEvent(Entity* entity, ) +}//*/ + extern(C) float sqrtf(float x) @nogc nothrow @system; extern(C) float acosf(float x) @nogc nothrow @system; extern(C) float sinf(float x) @nogc nothrow @system; @@ -2198,7 +2308,7 @@ void spaceInvadersStart() launcher.manager.registerComponent!CAutoShoot; launcher.manager.registerComponent!CWeapon; launcher.manager.registerComponent!CVelocity; - launcher.manager.registerComponent!CLaser; + launcher.manager.registerComponent!CBullet; launcher.manager.registerComponent!CSideMove; launcher.manager.registerComponent!CDepth; launcher.manager.registerComponent!CShootGrid; @@ -2223,6 +2333,8 @@ void spaceInvadersStart() launcher.manager.registerComponent!CColliderScale; launcher.manager.registerComponent!CParticleEmitter; launcher.manager.registerComponent!CParticleEmitterTime; + launcher.manager.registerComponent!CSpawnUponDeath; + launcher.manager.registerComponent!CShootWaveUponDeath; launcher.manager.registerEvent!EChangeDirection; launcher.manager.registerEvent!EDamage; @@ -2248,16 +2360,17 @@ void spaceInvadersStart() launcher.manager.registerSystem!ParticleSystem(-100); launcher.manager.registerSystem!AnimationSystem(-100); launcher.manager.registerSystem!DampingSystem(-101); - launcher.manager.registerSystem!MoveToParentTargetSystem(99); + launcher.manager.registerSystem!MoveToParentTargetSystem(-98); launcher.manager.registerSystem!ParentOwnerSystem(-101); launcher.manager.registerSystem!ShipWeaponSystem(-100); - launcher.manager.registerSystem!ParticleEmittingSystem(-100); - + launcher.manager.registerSystem!ParticleEmittingSystem(-95); launcher.manager.registerSystem!RotateToTargetSystem(-100); launcher.manager.registerSystem!ShipTargetSystem(-110); launcher.manager.registerSystem!CShipIterator(-100); launcher.manager.registerSystem!PartsDestroySystem(-80); launcher.manager.registerSystem!ChildDestroySystem(-110); + launcher.manager.registerSystem!ShootWaveSystem(-100); + //launcher.manager.registerSystem!SpawnUponDeathSystem(-110); launcher.manager.endRegister(); @@ -2267,19 +2380,26 @@ void spaceInvadersStart() launcher.gui_manager.addSystem(MovementSystem.system_id,"Movement System"); launcher.gui_manager.addSystem(ClampPositionSystem.system_id,"Clamp Position System"); launcher.gui_manager.addSystem(ChangeDirectionSystem.system_id,"Change Direction System"); - launcher.gui_manager.addSystem(LaserCollisionSystem.system_id,"Draw System"); + launcher.gui_manager.addSystem(LaserCollisionSystem.system_id,"Laser Collision System"); launcher.gui_manager.addSystem(ShootGridManager.system_id,"Shoot Grid Manager"); launcher.gui_manager.addSystem(ShootGridCleaner.system_id,"Shoot Grid Cleaner"); launcher.gui_manager.addSystem(HitPointsSystem.system_id,"Hit Points System"); - launcher.gui_manager.addSystem(HitMarkingSystem.system_id,"Hit Matking System"); + launcher.gui_manager.addSystem(HitMarkingSystem.system_id,"Hit Marking System"); launcher.gui_manager.addSystem(UpgradeCollisionSystem.system_id,"Upgrade Collision System"); launcher.gui_manager.addSystem(UpgradeSystem.system_id,"Upgrade System"); launcher.gui_manager.addSystem(ParticleSystem.system_id,"Particle System"); launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation System"); launcher.gui_manager.addSystem(DampingSystem.system_id,"Damping System"); launcher.gui_manager.addSystem(MoveToParentTargetSystem.system_id,"Move To Target System"); - launcher.gui_manager.addSystem(ParentOwnerSystem.system_id,"Parent Owner System System"); + launcher.gui_manager.addSystem(ParentOwnerSystem.system_id,"Parent Owner System"); launcher.gui_manager.addSystem(ShipWeaponSystem.system_id,"Ship Weapon System"); + launcher.gui_manager.addSystem(ParticleEmittingSystem.system_id,"Particle Emitting System"); + launcher.gui_manager.addSystem(RotateToTargetSystem.system_id,"Rotate To Target System"); + launcher.gui_manager.addSystem(ShipTargetSystem.system_id,"Ship Target System"); + launcher.gui_manager.addSystem(PartsDestroySystem.system_id,"Parts Destroy System"); + launcher.gui_manager.addSystem(ChildDestroySystem.system_id,"Child Destroy System"); + launcher.gui_manager.addSystem(ShootWaveSystem.system_id,"Shoot Wave System"); + //launcher.gui_manager.addSystem(SpawnUponDeathSystem.system_id,"Child Destroy System"); //launcher.manager.getSystem(CleanSystem.system_id).disable(); { @@ -2290,30 +2410,23 @@ void spaceInvadersStart() CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id, CDamping.component_id, CChildren.component_id, CInit.component_id].staticArray ); - //CWeapon* weapon = space_invaders.ship_tmpl.getComponent!CWeapon; - //weapon.level = 3; - space_invaders.ship_tmpl.getComponent!CTexture().coords = vec4(0*px,80*px,48*px,32*px); + space_invaders.ship_tmpl.getComponent!CTexture().coords = vec4(0,80,48,32)*px; space_invaders.ship_tmpl.getComponent!CScale().value = vec2(48,32); - space_invaders.ship_tmpl.getComponent!CLocation().value = vec2(64,64); space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; space_invaders.ship_tmpl.getComponent!CDamping().value = 7; space_invaders.ship_tmpl.getComponent!CInit().type = CInit.Type.space_ship; space_invaders.ship_tmpl.getComponent!CColliderScale().value = vec2(26,24); - launcher.manager.addEntity(space_invaders.ship_tmpl); + launcher.manager.addEntity(space_invaders.ship_tmpl,[CLocation(vec2(64,64)).ref_].staticArray); } { - ushort[6] components = [CLocation.component_id, CTexture.component_id, CVelocity.component_id, CScale.component_id, CLaser.component_id, CGuild.component_id]; + ushort[6] components = [CLocation.component_id, CTexture.component_id, CVelocity.component_id, CScale.component_id, CBullet.component_id, CGuild.component_id]; space_invaders.laser_tmpl = launcher.manager.allocateTemplate(components); - CTexture* tex_comp = space_invaders.laser_tmpl.getComponent!CTexture; - //tex_comp.tex = 0;//space_invaders.texture;//laser_tex; - tex_comp.coords = vec4(0*px,24*px,2*px,8*px); - CScale* scale_comp = space_invaders.laser_tmpl.getComponent!CScale; - scale_comp.value = vec2(2,8); - CVelocity* vel_comp = space_invaders.laser_tmpl.getComponent!CVelocity; - vel_comp.value = vec2(0,1); + space_invaders.laser_tmpl.getComponent!CTexture().coords = vec4(0,24,2,8)*px; + space_invaders.laser_tmpl.getComponent!CScale().value = vec2(2,8); + space_invaders.laser_tmpl.getComponent!CVelocity().value = vec2(0,1); } EntityTemplate* enemy_tmpl; @@ -2333,11 +2446,12 @@ void spaceInvadersStart() CDepth.component_id].staticArray ); - CTexture* tex_comp = boss_tmpl.getComponent!CTexture; + //CTexture* tex_comp = boss_tmpl.getComponent!CTexture; //tex_comp.tex = space_invaders.texture;//ship_tex; - tex_comp.coords = vec4(128*px,0*px,96*px,48*px); - CLocation* loc_comp = boss_tmpl.getComponent!CLocation; - loc_comp.value = vec2(64,space_invaders.map_size.y - 16); + //tex_comp.coords = vec4(128*px,0*px,96*px,48*px); + //CLocation* loc_comp = boss_tmpl.getComponent!CLocation; + //loc_comp.value = vec2(64,space_invaders.map_size.y - 16); + boss_tmpl.getComponent!CTexture().coords = vec4(128,0,96,48)*px; boss_tmpl.getComponent!CGuild().guild = 1; boss_tmpl.getComponent!CInit().type = CInit.Type.boss; boss_tmpl.getComponent!CScale().value = vec2(96,48); @@ -2354,11 +2468,7 @@ void spaceInvadersStart() CChildren.component_id].staticArray ); - CTexture* tex_comp = tower_tmpl.getComponent!CTexture; - //tex_comp.tex = space_invaders.texture;//ship_tex; - tex_comp.coords = vec4(96*px,96*px,16*px,16*px); - CLocation* loc_comp = tower_tmpl.getComponent!CLocation; - loc_comp.value = vec2(64,space_invaders.map_size.y - 16); + tower_tmpl.getComponent!CTexture().coords = vec4(96,96,16,16)*px; tower_tmpl.getComponent!CGuild().guild = 1; tower_tmpl.getComponent!CInit().type = CInit.Type.tower; tower_tmpl.getComponent!CHitPoints().value = 10; @@ -2373,35 +2483,29 @@ void spaceInvadersStart() CGuild.component_id].staticArray ); - CTexture* tex_comp = space_invaders.enemy_tmpl.getComponent!CTexture; - //tex_comp.tex = space_invaders.texture;//ship_tex; - tex_comp.coords = vec4(32*px,32*px,16*px,16*px); - CLocation* loc_comp = space_invaders.enemy_tmpl.getComponent!CLocation; - loc_comp.value = vec2(64,space_invaders.map_size.y - 16); - CShootDirection* shoot_dir_comp = space_invaders.enemy_tmpl.getComponent!CShootDirection; - shoot_dir_comp.direction = Direction.down; - CVelocity* vel_comp = space_invaders.enemy_tmpl.getComponent!CVelocity; - vel_comp.value = vec2(0.1,0); + space_invaders.enemy_tmpl.getComponent!CTexture().coords = vec4(32,32,16,16)*px; + space_invaders.enemy_tmpl.getComponent!CShootDirection().direction = Direction.down; + space_invaders.enemy_tmpl.getComponent!CVelocity().value = vec2(0.1,0); space_invaders.enemy_tmpl.getComponent!CGuild().guild = 1; space_invaders.enemy_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,-15); Entity* current_entity; - current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl); + current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(32,space_invaders.map_size.y - 16)).ref_].staticArray); launcher.manager.addComponents(current_entity.id,CSideMove(0)); - loc_comp.value = vec2(128,space_invaders.map_size.y - 16); - current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl); + //loc_comp.value = vec2(128,space_invaders.map_size.y - 16); + current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(128,space_invaders.map_size.y - 16)).ref_].staticArray); launcher.manager.addComponents(current_entity.id,CSideMove(-1)); enemy_id = current_entity.id; //enemy_tmpl = launcher.manager.allocateTemplate(current_entity.id); - loc_comp.value = vec2(256,space_invaders.map_size.y - 16); - launcher.manager.addEntity(space_invaders.enemy_tmpl); + //loc_comp.value = vec2(256,space_invaders.map_size.y - 16); + launcher.manager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(256,space_invaders.map_size.y - 16)).ref_].staticArray); - loc_comp.value = vec2(0,space_invaders.map_size.y - 16); - current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl); + //loc_comp.value = vec2(0,space_invaders.map_size.y - 16); + current_entity = launcher.manager.addEntity(space_invaders.enemy_tmpl,[CLocation(vec2(0,space_invaders.map_size.y - 16)).ref_].staticArray); launcher.manager.addComponents(current_entity.id,CSideMove(0)); grouped_id = current_entity.id; @@ -2412,11 +2516,8 @@ void spaceInvadersStart() { upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id, CAnimationLooped.component_id, CAnimation.component_id].staticArray); - CTexture* tex_comp = upgrade_tmpl.getComponent!CTexture; - //tex_comp.tex = space_invaders.texture;//ship_tex; - tex_comp.coords = vec4(0*px,32*px,16*px,16*px); - CVelocity* vel_comp = upgrade_tmpl.getComponent!CVelocity; - vel_comp.value = vec2(0,-0.1); + upgrade_tmpl.getComponent!CTexture().coords = vec4(0,32,16,16)*px; + upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.1); *upgrade_tmpl.getComponent!CAnimation = CAnimation(HitPointsSystem.upgrade_laser_frames, 0, 0.75); } @@ -2425,6 +2526,24 @@ void spaceInvadersStart() enemy_tmpl = launcher.manager.allocateTemplate(enemy_id); grouped_tmpl = launcher.manager.allocateTemplate(grouped_id); + space_invaders.bullet_tmpl[0] = launcher.manager.allocateTemplate( + [CLocation.component_id, CTexture.component_id, CVelocity.component_id, + CScale.component_id, CBullet.component_id, CGuild.component_id].staticArray + ); + space_invaders.bullet_tmpl[0].getComponent!CTexture().coords = vec4(0,24,2,8)*px; + space_invaders.bullet_tmpl[0].getComponent!CScale().value = vec2(2,8); + + space_invaders.bullet_tmpl[1] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); + space_invaders.bullet_tmpl[2] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); + space_invaders.bullet_tmpl[2].getComponent!CTexture().coords = vec4(64,32,8,16)*px; + space_invaders.bullet_tmpl[2].getComponent!CScale().value = vec2(8,16); + space_invaders.bullet_tmpl[3] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); + space_invaders.bullet_tmpl[3].getComponent!CTexture().coords = vec4(56,32,2,2)*px; + space_invaders.bullet_tmpl[3].getComponent!CScale().value = vec2(2,2); + // bullet_tmpl[3].getComponent!CTexture().coords = vec4(48,32,8,8)*px; + // bullet_tmpl[3].getComponent!CScale().value = vec2(8,8); + space_invaders.bullet_tmpl[4] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); + launcher.gui_manager.addTemplate(enemy_tmpl,"Enemy"); launcher.gui_manager.addTemplate(grouped_tmpl,"Grouped enemy"); launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.ship_tmpl),"Ship"); @@ -2432,6 +2551,9 @@ void spaceInvadersStart() launcher.gui_manager.addTemplate(upgrade_tmpl,"Upgrade"); launcher.gui_manager.addTemplate(tower_tmpl,"Tower"); launcher.gui_manager.addTemplate(boss_tmpl,"Boss"); + launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[3]),"Cannon bullet"); + //launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[4]),"Laser"); + //launcher.gui_manager.addTemplate(launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[5]),"Laser"); } void spaceInvadersEnd() @@ -2445,6 +2567,7 @@ void spaceInvadersEnd() //launcher.manager.freeTemplate(space_invaders.enemy_tmpl); Mallocator.dispose(space_invaders); + space_invaders = null; } void spaceInvadersTool(vec2 position, Tool tool, int size) diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index 185fcd1..4d452ad 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -30,6 +30,7 @@ struct GUIManager systems.clear(); templates.clear(); + selected_tempalte = 0; } EntityTemplate* getSelectedTemplate() From 2ad238841bb98048faddad9af63dd3f087b8a467 Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 28 May 2020 16:41:58 +0200 Subject: [PATCH 37/58] Fixed .gitlab-ci.yml emscripten build --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a2d26ff..376aead 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -76,7 +76,7 @@ emscripten: stage: build_emscripten image: "registry.gitlab.com/mergul/bubel-ecs/emscripten:latest" dependencies: - - build_code + - build_wasm script: - /bin/bash /build.sh rules: From 66860b904222ee8eb37e4234b28283e1c4851962 Mon Sep 17 00:00:00 2001 From: Mergul Date: Mon, 1 Jun 2020 11:24:50 +0200 Subject: [PATCH 38/58] Android update and small improvements -fixed code do cross compiling to android -fixed build with GCC (workaround) -added little benchmark -several small fixes -updated meson build (demos building, working with GCC, LDC and DMD) -added some meson options -added ImGUI bind for OpenGL3 --- .gitignore | 3 +- compile_android.py | 78 +++ demos/.gitignore | 1 + demos/compile_android.py | 91 +++ demos/dub.json | 3 +- .../external/android/bindbc/loader/package.d | 11 + .../android/bindbc/loader/sharedlib.d | 335 ++++++++++ demos/external/android/bindbc/loader/system.d | 55 ++ demos/external/sources/mmutils/thread_pool.d | 15 + .../wasm_imports/bindbc/sdl/dynload.d | 12 +- .../external/wasm_imports/bindbc/sdl/image.d | 4 +- demos/libs/armeabi-v7a/libcimgui.so | Bin 0 -> 3111272 bytes demos/source/app.d | 68 +- demos/source/demos/space_invaders.d | 2 +- demos/source/game_core/job_updater.d | 12 + demos/utils/dub.json | 3 +- demos/utils/source/ecs_utils/gfx/buffer.d | 12 +- demos/utils/source/ecs_utils/gfx/material.d | 4 +- demos/utils/source/ecs_utils/gfx/mesh.d | 4 +- demos/utils/source/ecs_utils/gfx/renderer.d | 6 + demos/utils/source/ecs_utils/gfx/shader.d | 6 +- demos/utils/source/ecs_utils/gfx/texture.d | 4 +- demos/utils/source/ecs_utils/imgui_bind.d | 598 ++++++++++++++---- demos/utils/source/ecs_utils/utils.d | 8 + meson.build | 35 +- meson_options.txt | 4 +- source/bubel/ecs/id_manager.d | 2 +- source/bubel/ecs/manager.d | 13 +- source/bubel/ecs/std.d | 31 +- tests/tests.d | 111 ++++ 30 files changed, 1358 insertions(+), 173 deletions(-) create mode 100644 compile_android.py create mode 100644 demos/compile_android.py create mode 100644 demos/external/android/bindbc/loader/package.d create mode 100644 demos/external/android/bindbc/loader/sharedlib.d create mode 100644 demos/external/android/bindbc/loader/system.d create mode 100755 demos/libs/armeabi-v7a/libcimgui.so diff --git a/.gitignore b/.gitignore index e595637..636ea36 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ !skeleton.html !meson.build !meson_options.txt -!compile_wasm.py \ No newline at end of file +!compile_wasm.py +!compile_android.py \ No newline at end of file diff --git a/compile_android.py b/compile_android.py new file mode 100644 index 0000000..15f04ea --- /dev/null +++ b/compile_android.py @@ -0,0 +1,78 @@ +import os +import ntpath +import sys + +def compile(sources, output): + files = [] + # r=root, d=directories, f = files + for path in sources: + for r, d, f in os.walk(path): + for file in f: + if ntpath.basename(file) != 'win_dll.d': + filename, file_extension = os.path.splitext(file) + if file_extension == '.d' and filename != 'package': + files.append(os.path.join(r, file)) + + ldc_path = 'ldc' + if 'LDC' in os.environ: + ldc_path = os.environ['LDC'] + + ldc_cmd = ldc_path + ' ' + ldc_flags + '-lib -mtriple=armv7-none-linux-androideabi -fvisibility=hidden -betterC -oq -od=obj/ --singleobj --of=' + output + ' ' + + for path in sources: + ldc_cmd += '-I' + path + ' ' + + for path in import_paths: + ldc_cmd += '-I' + path + ' ' + + for f in files: + ldc_cmd += f + ' ' + + print(ldc_cmd) + + if os.system(ldc_cmd): + exit(0) + print() + +clean = 0 +ldc_flags = '' +import_paths = ['source','tests'] +build_tests = 0 + +for arg in sys.argv[1:]: + if(arg == '-release'): + ldc_flags += '-release ' + elif(arg == '-enable-inlining'): + ldc_flags += '-enable-inlining ' + elif(arg == '-O3'): + ldc_flags += '-O3 ' + elif(arg == '-O2'): + ldc_flags += '-O2 ' + elif(arg == '-O1'): + ldc_flags += '-O1 ' + elif(arg == '-O0'): + ldc_flags += '-O0 ' + elif(arg == '-Os'): + ldc_flags += '-Os ' + elif(arg == '-Oz'): + ldc_flags += '-Oz ' + elif(arg == '-g'): + ldc_flags += '-g ' + elif(arg == '-opt'): + ldc_flags += '-release -enable-inlining -O3 ' + else: + print('unknown argument: ' + arg) + exit() + +compile(['source'], 'ecs.a') + +#export LDC_LIBS=/path/to/your/ldc-build-runtime.tmp/lib/ +CC = os.environ['NDK'] + '/toolchains/llvm/prebuilt/linux-x86_64/bin/clang' +TOOLCHAIN = os.environ['NDK'] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64' +SYSROOT = os.environ['NDK'] + '/platforms/android-21/arch-arm' +LDC_LIBS = ''#os.environ['LDC_LIBS'] + '/libphobos2-ldc.a ' + os.environ['LDC_LIBS'] + '/libdruntime-ldc.a' + +os.system(CC + ' -Wl,-soname,libecs.so -shared --sysroot=' + SYSROOT + ' obj/*.o ' + LDC_LIBS + ' -lgcc -gcc-toolchain ' + TOOLCHAIN + +' -no-canonical-prefixes -fuse-ld=bfd -target armv7-none-linux-androideabi -fvisibility=hidden \ +-Wl,--gc-sections -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro \ +-Wl,-z,now -mthumb -o libecs.so') diff --git a/demos/.gitignore b/demos/.gitignore index 1ac2a4a..974bbb2 100644 --- a/demos/.gitignore +++ b/demos/.gitignore @@ -14,4 +14,5 @@ !cimgui.bc !emscripten_shell.html !emscripten_multi_shell.html +!compile_android.py .dub \ No newline at end of file diff --git a/demos/compile_android.py b/demos/compile_android.py new file mode 100644 index 0000000..2e3f967 --- /dev/null +++ b/demos/compile_android.py @@ -0,0 +1,91 @@ +import os +import ntpath +import sys + +def compile(sources, output): + files = [] + # r=root, d=directories, f = files + for path in sources: + for r, d, f in os.walk(path): + for file in f: + if ntpath.basename(file) != 'win_dll.d': + filename, file_extension = os.path.splitext(file) + if file_extension == '.d': + files.append(os.path.join(r, file)) + + ldc_path = 'ldc' + if 'LDC' in os.environ: + ldc_path = os.environ['LDC'] + + ldc_cmd = ldc_path + ' ' + ldc_flags + '-lib -mtriple=armv7-none-linux-androideabi -fvisibility=hidden -betterC -oq -od=obj/ --singleobj --of=' + output + ' ' + + for path in sources: + ldc_cmd += '-I' + path + ' ' + + for path in import_paths: + ldc_cmd += '-I' + path + ' ' + + for f in files: + ldc_cmd += f + ' ' + + print(ldc_cmd) + + if os.system(ldc_cmd): + print('some kind of error') + exit(0) + print() + +clean = 0 +ldc_flags = '--d-version=SDL_209 --d-version=BindSDL_Image --d-version=MM_USE_POSIX_THREADS ' +#import_paths = ['source','tests'] +import_paths = ['external','external/sources', 'external/imports', 'external/wasm_imports', '../source', 'utils/source', 'simple/source'] +build_tests = 0 + +for arg in sys.argv[1:]: + if(arg == '-release'): + ldc_flags += '-release ' + elif(arg == '-enable-inlining'): + ldc_flags += '-enable-inlining ' + elif(arg == '-O3'): + ldc_flags += '-O3 ' + elif(arg == '-O2'): + ldc_flags += '-O2 ' + elif(arg == '-O1'): + ldc_flags += '-O1 ' + elif(arg == '-O0'): + ldc_flags += '-O0 ' + elif(arg == '-Os'): + ldc_flags += '-Os ' + elif(arg == '-Oz'): + ldc_flags += '-Oz ' + elif(arg == '-g'): + ldc_flags += '-g ' + elif(arg == '-opt'): + ldc_flags += '-release -enable-inlining -O3 ' + else: + print('unknown argument: ' + arg) + exit() + +#compile(['source'], 'ecs.a') +compile(['external/wasm_imports/bindbc/sdl'], 'build/bindbc-sdl.a') +compile(['utils/source'], 'build/utils.a') +compile(['external/sources/mmutils'], 'build/mmutils.a') +compile(['external/sources/glad'], 'build/glad.a') +compile(['external/android/bindbc'], 'build/bindbc.a') +compile(['source'], 'build/demo.a') + +#compile(['external/wasm_imports/bindbc/sdl','utils/source','external/sources/mmutils','external/sources/glad'], 'build/asd.a') + +#export LDC_LIBS=/path/to/your/ldc-build-runtime.tmp/lib/ +CC = os.environ['NDK'] + '/toolchains/llvm/prebuilt/linux-x86_64/bin/clang' +TOOLCHAIN = os.environ['NDK'] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64' +SYSROOT = os.environ['NDK'] + '/platforms/android-21/arch-arm' +#LDC_LIBS = os.environ['LDC_LIBS'] + '/libphobos2-ldc.a ' + os.environ['LDC_LIBS'] + '/libdruntime-ldc.a' +LDC_LIBS = '' +LIBS = '-L/platforms/android-21/arch-arm/usr/lib' + +os.system(CC + ' -Wl,-soname,libdemos.so -shared --sysroot=' + SYSROOT + ' ../obj/*.o obj/*.o ' + LDC_LIBS + ' -lgcc -gcc-toolchain ' + TOOLCHAIN + +' -no-canonical-prefixes -fuse-ld=bfd -target armv7-none-linux-androideabi -fvisibility=hidden \ +-Wl,--gc-sections -Wl,--fix-cortex-a8 -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro \ +-Wl,-z,now -mthumb -lm -lc -Llibs/armeabi-v7a -lcimgui -o libdemos.so') + diff --git a/demos/dub.json b/demos/dub.json index 1c1fe65..417b831 100644 --- a/demos/dub.json +++ b/demos/dub.json @@ -19,7 +19,8 @@ "libs-linux-x86_64": ["cimgui","SDL2","SDL2_image"], "lflags-linux-x86_64": ["-rpath=libs/linux/x64/","-Llibs/linux/x64/"], "dflags-ldc" : [ - "--ffast-math" + "--ffast-math", + "-enable-cross-module-inlining" ], "configurations" : [ { diff --git a/demos/external/android/bindbc/loader/package.d b/demos/external/android/bindbc/loader/package.d new file mode 100644 index 0000000..3ed4e31 --- /dev/null +++ b/demos/external/android/bindbc/loader/package.d @@ -0,0 +1,11 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.loader; + +public +import bindbc.loader.sharedlib, + bindbc.loader.system; \ No newline at end of file diff --git a/demos/external/android/bindbc/loader/sharedlib.d b/demos/external/android/bindbc/loader/sharedlib.d new file mode 100644 index 0000000..ab6c444 --- /dev/null +++ b/demos/external/android/bindbc/loader/sharedlib.d @@ -0,0 +1,335 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.loader.sharedlib; + +import core.stdc.stdlib; +import core.stdc.string; + +/// Handle to a shared library +struct SharedLib { + private void* _handle; +} + +/// Indicates an uninitialized or unassigned handle. +enum invalidHandle = SharedLib.init; + +// Contains information about shared library and symbol load failures. +struct ErrorInfo { +private: + char[32] _error; + char[96] _message; + +public @nogc nothrow @property: + /** + Returns the string "Missing Symbol" to indicate a symbol load failure, and + the name of a library to indicate a library load failure. + */ + const(char)* error() const { return _error.ptr; } + + /** + Returns a symbol name for symbol load failures, and a system-specific error + message for library load failures. + */ + const(char)* message() const { return _message.ptr; } +} + +private { + __gshared ErrorInfo[] _errors; + __gshared size_t _errorCount; +} + +@nogc nothrow: + +/** + Returns an slice containing all errors that have been accumulated by the + `load` and `bindSymbol` functions since the last call to `resetErrors`. +*/ +const(ErrorInfo)[] errors() +{ + return _errors[0 .. _errorCount]; +} + +/** + Returns the total number of errors that have been accumulated by the + `load` and `bindSymbol` functions since the last call to `resetErrors`. +*/ +size_t errorCount() +{ + return _errorCount; +} + +/** + Sets the error count to 0 and erases all accumulated errors. This function + does not release any memory allocated for the error list. +*/ +void resetErrors() +{ + _errorCount = 0; + memset(_errors.ptr, 0, _errors.length * ErrorInfo.sizeof); +} + +/* +void freeErrors() +{ + free(_errors.ptr); + _errors.length = _errorCount = 0; +} +*/ + +/** + Loads a symbol from a shared library and assigns it to a caller-supplied pointer. + + Params: + lib = a valid handle to a shared library loaded via the `load` function. + ptr = a pointer to a function or variable pointer whose declaration is + appropriate for the symbol being bound (it is up to the caller to + verify the types match). + symbolName = the name of the symbol to bind. +*/ +void bindSymbol(SharedLib lib, void** ptr, const(char)* symbolName) +{ + // Without this, DMD can hang in release builds + pragma(inline, false); + + assert(lib._handle); + auto sym = loadSymbol(lib._handle, symbolName); + if(sym) { + *ptr = sym; + } + else { + addErr("Missing Symbol", symbolName); + } +} + +/** + Formats a symbol using the Windows stdcall mangling if necessary before passing it on to + bindSymbol. + + Params: + lib = a valid handle to a shared library loaded via the `load` function. + ptr = a pointer to a function or variable pointer whose declaration is + appropriate for the symbol being bound (it is up to the caller to + verify the types match). + symbolName = the name of the symbol to bind. +*/ +void bindSymbol_stdcall(Func)(SharedLib lib, ref Func f, const(char)* symbolName) +{ + import bindbc.loader.system : bindWindows, bind32; + + static if(bindWindows && bind32) { + import core.stdc.stdio : snprintf; + import std.traits : ParameterTypeTuple; + + uint paramSize(A...)(A args) + { + size_t sum = 0; + foreach(arg; args) { + sum += arg.sizeof; + + // Align on 32-bit stack + if((sum & 3) != 0) { + sum += 4 - (sum & 3); + } + } + return sum; + } + + ParameterTypeTuple!f params; + char[128] mangled; + snprintf(mangled.ptr, mangled.length, "_%s@%d", symbolName, paramSize(params)); + symbolName = mangled.ptr; + } + bindSymbol(lib, cast(void**)&f, symbolName); +} + +/** + Loads a shared library from disk, using the system-specific API and search rules. + + libName = the name of the library to load. May include the full or relative + path for the file. +*/ +SharedLib load(const(char)* libName) +{ + auto handle = loadLib(libName); + if(handle) return SharedLib(handle); + else { + addErr(libName, null); + return invalidHandle; + } +} + +/** + Unloads a shared library from process memory. + + Generally, it is not necessary to call this function at program exit, as the system will ensure + any shared libraries loaded by the process will be unloaded then. However, any loaded shared + libraries that are no longer needed by the program during runtime, such as those that are part + of a "hot swap" mechanism, should be unloaded to free up resources. +*/ +void unload(ref SharedLib lib) { + if(lib._handle) { + unloadLib(lib._handle); + lib = invalidHandle; + } +} + +private: +void allocErrs() { + size_t newSize = _errorCount == 0 ? 16 : _errors.length * 2; + auto errs = cast(ErrorInfo*)malloc(ErrorInfo.sizeof * newSize); + if(!errs) exit(EXIT_FAILURE); + + if(_errorCount > 0) { + memcpy(errs, _errors.ptr, ErrorInfo.sizeof * _errors.length); + free(_errors.ptr); + } + + _errors = errs[0 .. newSize]; +} + +void addErr(const(char)* errstr, const(char)* message) +{ + if(_errors.length == 0 || _errorCount >= _errors.length) { + allocErrs(); + } + + auto pinfo = &_errors[_errorCount]; + strcpy(pinfo._error.ptr, errstr); + + if(message) { + strncpy(pinfo._message.ptr, message, pinfo._message.length); + pinfo._message[pinfo._message.length - 1] = 0; + } + else { + sysError(pinfo._message.ptr, pinfo._message.length); + } + ++_errorCount; +} + +version(Windows) +{ + import core.sys.windows.windows; + extern(Windows) @nogc nothrow alias pSetDLLDirectory = BOOL function(const(char)*); + pSetDLLDirectory setDLLDirectory; + + void* loadLib(const(char)* name) + { + return LoadLibraryA(name); + } + + void unloadLib(void* lib) + { + FreeLibrary(lib); + } + + void* loadSymbol(void* lib, const(char)* symbolName) + { + return GetProcAddress(lib, symbolName); + } + + void sysError(char* buf, size_t len) + { + char* msgBuf; + enum uint langID = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT); + + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + null, + GetLastError(), + langID, + cast(char*)&msgBuf, + 0, + null + ); + + if(msgBuf) { + strncpy(buf, msgBuf, len); + buf[len - 1] = 0; + LocalFree(msgBuf); + } + else strncpy(buf, "Unknown Error\0", len); + } + + /** + Adds a path to the default search path on Windows, replacing the path set in a previous + call to the same function. + + Any path added to this function will be added to the default DLL search path as documented at + https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectoryw. + + Generally, when loading DLLs on a path that is not on the search path, e.g., from a subdirectory + of the application, the path should be prepended to the DLL name passed to the load function, + e.g., "dlls\\SDL2.dll". If `setCustomLoaderSearchPath(".\\dlls")` is called first, then the subdirectory + will become part of the DLL search path and the path may be omitted from the load function. (Be + aware that ".\\dlls" is relative to the current working directory, which may not be the application + directory, so the path should be built appropriately.) + + Some DLLs may depend on other DLLs, perhaps even attempting to load them dynamically at run time + (e.g., SDL2_image only loads dependencies such as libpng if it is initialized at run time with + PNG support). In this case, if the DLL and its dependencies are placed in a subdirectory and + loaded as e.g., "dlls\\SDL2_image.dll", then it will not be able to find its dependencies; the + system loader will look for them on the regular DLL search path. When that happens, the solution + is to call `setCustomLoaderSearchPath` with the subdirectory before initializing the library. + + Calling this function with `null` as the argument will reset the default search path. + + When the function returns `false`, the relevant `ErrorInfo` is added to the global error list and can + be retrieved by looping through the array returned by the `errors` function. + + When placing DLLs in a subdirectory of the application, it should be considered good practice to + call `setCustomLoaderSearchPath` to ensure all DLLs load properly. It should also be considered good + practice to reset the default search path once all DLLs are loaded. + + This function is only available on Windows, so any usage of it should be preceded with + `version(Windows)`. + + Params: + path = the path to add to the DLL search path, or `null` to reset the default. + + Returns: + `true` if the path was successfully added to the DLL search path, otherwise `false`. + */ + public + bool setCustomLoaderSearchPath(const(char)* path) + { + if(!setDLLDirectory) { + auto lib = load("Kernel32.dll"); + if(lib == invalidHandle) return false; + lib.bindSymbol(cast(void**)&setDLLDirectory, "SetDllDirectoryA"); + if(!setDLLDirectory) return false; + } + return setDLLDirectory(path) != 0; + } +} +else version(Posix) { + import core.sys.posix.dlfcn; + + void* loadLib(const(char)* name) + { + return dlopen(name, RTLD_NOW); + } + + void unloadLib(void* lib) + { + dlclose(lib); + } + + void* loadSymbol(void* lib, const(char)* symbolName) + { + return dlsym(lib, symbolName); + } + + void sysError(char* buf, size_t len) + { + const (char)* msg = dlerror(); + strncpy(buf, msg != null ? msg : "Unknown Error", len); + buf[len - 1] = 0; + } +} +else static assert(0, "bindbc-loader is not implemented on this platform."); \ No newline at end of file diff --git a/demos/external/android/bindbc/loader/system.d b/demos/external/android/bindbc/loader/system.d new file mode 100644 index 0000000..c721100 --- /dev/null +++ b/demos/external/android/bindbc/loader/system.d @@ -0,0 +1,55 @@ + +// Copyright Michael D. Parker 2018. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +module bindbc.loader.system; + +static if((void*).sizeof == 8) { + enum bind64 = true; + enum bind32 = false; +} +else { + enum bind64 = false; + enum bind32 = true; +} + +version(Windows) enum bindWindows = true; +else enum bindWindows = false; + +version(OSX) enum bindMac = true; +else enum bindMac = false; + +version(linux) enum bindLinux = true; +else enum bindLinux = false; + +version(Posix) enum bindPosix = true; +else enum bindPosix = false; + +version(Android) enum bindAndroid = true; +else enum bindAndroid = false; + +enum bindIOS = false; +enum bindWinRT = false; + +version(FreeBSD) { + enum bindBSD = true; + enum bindFreeBSD = true; + enum bindOpenBSD = false; +} +else version(OpenBSD) { + enum bindBSD = true; + enum bindFreeBSD = false; + enum bindOpenBSD = true; +} +else version(BSD) { + enum bindBSD = true; + enum bindFreeBSD = false; + enum bindOpenBSD = false; +} +else { + enum bindBSD = false; + enum bindFreeBSD = false; + enum bindOpenBSD = false; +} \ No newline at end of file diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index 52136d4..b830026 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -201,6 +201,21 @@ void instructionPause() static assert(0); } } + else version (Android) + { + version(LDC) + { + import ldc.attributes; + @optStrategy("none") + static void nop() + { + int i; + i++; + } + nop(); + } + else static assert(0); + } else version(WebAssembly) { version(LDC) diff --git a/demos/external/wasm_imports/bindbc/sdl/dynload.d b/demos/external/wasm_imports/bindbc/sdl/dynload.d index 0aa3b84..3a15c97 100644 --- a/demos/external/wasm_imports/bindbc/sdl/dynload.d +++ b/demos/external/wasm_imports/bindbc/sdl/dynload.d @@ -14,8 +14,8 @@ import bindbc.sdl.config, bindbc.sdl.bind; private { - SharedLib lib; - SDLSupport loadedVersion; + __gshared SharedLib lib; + __gshared SDLSupport loadedVersion; } void unloadSDL() @@ -664,14 +664,14 @@ SDLSupport loadSDL(const(char)* libName) lib.bindSymbol(cast(void**)&SDL_HasColorKey, "SDL_HasColorKey"); lib.bindSymbol(cast(void**)&SDL_GetDisplayOrientation, "SDL_GetDisplayOrientation"); - version(linux) { - lib.bindSymbol(cast(void**)&SDL_LinuxSetThreadPriority, "SDL_LinuxSetThreadPriority"); - } - else version(Android) { + version(Android) { lib.bindSymbol(cast(void**)&SDL_IsChromebook, "SDL_IsChromebook"); lib.bindSymbol(cast(void**)&SDL_IsDeXMode, "SDL_IsDeXMode"); lib.bindSymbol(cast(void**)&SDL_AndroidBackButton, "SDL_AndroidBackButton"); } + else version(linux) { + lib.bindSymbol(cast(void**)&SDL_LinuxSetThreadPriority, "SDL_LinuxSetThreadPriority"); + } if(errorCount() != errCount) return SDLSupport.badLibrary; else loadedVersion = SDLSupport.sdl209; diff --git a/demos/external/wasm_imports/bindbc/sdl/image.d b/demos/external/wasm_imports/bindbc/sdl/image.d index 8cf160e..8af6e81 100644 --- a/demos/external/wasm_imports/bindbc/sdl/image.d +++ b/demos/external/wasm_imports/bindbc/sdl/image.d @@ -229,8 +229,8 @@ else { } private { - SharedLib lib; - SDLImageSupport loadedVersion; + __gshared SharedLib lib; + __gshared SDLImageSupport loadedVersion; } void unloadSDLImage() diff --git a/demos/libs/armeabi-v7a/libcimgui.so b/demos/libs/armeabi-v7a/libcimgui.so new file mode 100755 index 0000000000000000000000000000000000000000..5dca812e96fa3fd8221c264798d39798416bea16 GIT binary patch literal 3111272 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

_At8{<}X2v(%m8jm~aB6m;X*buXz_bl5${!qC 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

*x6KmdI3m&B#S}du*||fXIq0xSICt@W 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 {UxgxDSs?5a+sKB!Gd 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 YHu^WdvPp93c$EetCF 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

A0O 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'LL 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

#3}j*GT( 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%0An`Q7_OeqP^ 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£?MMXF+K%Zdl^yW;%8q46;l^ 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

a< zL99t2V)o#zTF*SugY|nGfvo#9Xt0cgZ*QUXCO)^Gs@e z7O#2!Jk>*|X{^RaLb|wgCR+mm^Gu%zfuYT2TKyB>S%vY1ci-Jd3UA@#<*qQ_FTn;a z&ve-Db{@_~5~1=xffH9JVaWh*s=1#9P&*=5S&NQ4Jlo7H>?THews{|oH)0RgR+-}T zO>k+Hxr^INFb$(DZ#<}}jeR(gXm<5bh{#s(%;Xa9&)O&_sHVcJ=XmEYvTuX&Hbp`s z@FSw%MmkrYIp2d$JP54EvqsaG)b^p-OPvGT?}lYPowcZl44yKDfK=-%Ljgz zh4vkiBTExAf_br(YFTXFlq2!dKC=F>B5#P(TApMU!pr-B7<}crMa^2WvZeb95Y*35 z@V0Jz0z$sl*Fp|=THVJT%4D5BZ5WjFYnoF}R} z$GnVzgyQCQE1~_}tUc4czl=~2^6WdTGMGvx?EOkrsmgdzTw%Eoiq;3#-MTGb$*0q& zRKl?rhpLZyfVTVk#8{zD8V)%3^_2TVnH`xutoYVtjl$OaH zgUjk0XcZ0OaBQ*FDt3o0X17hhq!@YU;m!l?HaB(g9_mjRX$3$|X7rB3qDVcG#XA5{ zmPZJAYcBhUYoMzc;1Sh&=hMyuUfz<)r+CK`5hsHa3<2};R$QK;p!t&C8w7WFp=Ad^ zw!*n0w=aCURWd+4$}2 z0uX)~#(EIYIYXw)M)6#a0;?d#?pkD#>A|TYUvt{WHnMzjYrfku^N>ygH zDhdTohFYXju%Yzu)3r)D@=*?TmwTK^iW5J2)JptVi1$-i;n(>ZiT(71`}8=UNG_-< z5i&2G#cBLJzry0`3fERu`11d#(0!speX6ODWF+_NWr>3!tr6V6QSa)idSCq?^}0{g zt4}rclFT)M|42~9EzQ49l{|8}xiRP1cd?KV-^DNU%$l>g@&{&^XS3m0ahCdhxhcw# zK|ExR`1w}F=0gCt%FR9qr{+w{$`K6HA4WB`jN)l!-RdIdS&Qe^(i^Nx^)BM$!Cw`R zF%`A-*;**a$kb4GVisyG=YSaz#nOWheW8GggcFrj6v=ft8bpFS57e4tqzDJu_83-O z%lJP}1M5YlsG?Y5e|WZ*OxCkXZwRJ}#D7suRD%Z8D&IR{a4y>y9PQV{BCy*nJ8N;> zn9L?zS~1dVXhUr1u8UJ7<$tbRnD^(AOZP7HKF`B&on%xub6h=vu1oawVzZgIVW{k5 z?ec~9;@>f?p8@=t#Y|xg09fW}hZqhEi5eL&9|BmR*N}^i$#YTw+2bB6tcerdEdm~w z?DXd~T;`2UOl8RG!JR1Ep4q`7+1xx0(~!`g>2a;F_F!HH<{IWOUX`qKm0%7rbwDQ? zI-1TVz(u0pvXj_@8Nd|^o9z_Ey08mM4@(oOF8&s&058&pexP#t(rICBc`A|++J6eJRKhYpyW6M!=u^|I); zR$NPKX1=mA!e42Gn_Uh=X1iPTsn}>J(X>{B>PH32cMcR7?<^mbAFDvQNtL0j9T6x* z8@={bDaF3qr<$%@s0!|J6`*3b-VC*F1VW&{?>R8rxHEup z!fzu}j=1b3>6z6lV3s`xJ>lvDqhZOo>8TsUlKPt;wp+7IU!_PU$S^;W;x%9!i0QXj zN4bTM*1F$>8*B(XXG7K2fqV7RZt+V*x1h?NIHlEA`IF4AuEw5bhO6-ur65r46QIcK z>**#@Q0O7$5PY5Cr=59|u&y>;ybujpdp_*;QYX#4!AB*Vr3&mS=Q*3KG9*XLvQog1 zq=UGuD}PcY=cKzg-S}m{4Y#Gt&lHlxb_$daH^7IYd8vn)m`hKa3&Ii^7 z*}8U>-xO1Fi7Y}26r^WZ9b$w6z#=J>YUr9H^F7OHdC|+(=hWqG8*d0stcgv2^)OC3 z|57K;>w*-lQ&d!fOL;E$-$u-giDC0=otV&>sUsQdZ9cIe^lya8)I)dEIM<~xz1|E; zYlx$_3hb()uC@m)*Lm!yEEg)vL7#pm0ls3B)Me>crJ9z@MT)F6Z$HOesH3?cqlEoy zij^7L_xs9RhY!hNvryDUe?KHY?j`iTMtyo(jVN1i4%%0bxvs zbPN!|{sEoXYdPFYJq;$OGos);$7`6O05dv4R?f-3n#ya9qVmdqlA6+{AzVgx?ljHx8fIFN3M&!#`4DNB`P738cTul& z#1I@kuj+Zu1 zx?VPPxQj45b*-G(GNs?z5IY4@$B=&&`C$TS38u0tBJdqMY6T}M&3s)3qp+d3-o0A9 zkXUh^*g_M$8h6+*!Nbhv-VtpTc)6OPwHxT{>FlY>lx)hLL%wZXAOj`zc|4oSo(?nZ z+JH=EZT4C;HwudXmyUsG*{D61`pO&@>p8^kUQZn5z$#UN%ow-^si zgov#gH)qt{rl>=SO3}*6eA=?%hKSkDtDa(Xs2*x1oBU6@zG8rx zNn9mu_csp|cF`2ARC056bCu5fVcj5slsQ*XnOZyrin7cn+#{id^iHnvklFMMTB>Ef zRLPEJ4h8jWgXYG(fUaiHflhaSwOHh?WYAhf?y zJ#1|bsQ>J}3cu|!Z7>5giQHJ;)LSG+W{u^^7&~gla)pW~D#ahmWg5#jcr|*eVJMpg z!CGBu(wvR_lvmj^QXh~5*Qw`J{-SyfW**~R3m<6W7!3@d8jjUydH@nK6;d;GXoj&k z-il*h;AE|1X0MQh0K5q-0sL9!;d8XJBr?E&Qqfa;Xx+^kju=*-*M@(*+Ov`c^NCn( zX4rV({Xd>LI`*Dbb8<>kW}zy2Y%d*8NYM5vm%8nJ94w=7Z{ADKQ-VW1Z?QM{FnU;2 zSGmKfQ04eNi}n9T>8Ku8Lh`Jg-wcZnS+1UZoS7%yPbG%qk>16egA9aA&5XxD!5O&! zz5tStnA{k?9GN2&F=EtC~hD=Y{ChdX)xp1Drl=e(+noU3vQY zjeWHa@=eDr`-NKZZ86vY9&4Svd$ou4{y2?aU9+%(7K*C(Vdi#$(8%1uv4LBN*@W}d z-vERwGVzy5;z%4vam`(if$KAo&-Wp8vWMib@s;bv31+UUkRhch+7(e+!rm37JeM#O zdM@_*z~W`X$9$QLO@m)#GbD6Y74ZW`@t4NtoGh|l2063j#vJ(|v5;hes`5`4wA^B#J0~;FXx;PRb z{BMp6lyP$%sR|nNAY?Fyzt>xHs@}+w8K{74)C2RXt8TTb%b>cGN#>B)D=vABk~@;D zjR}n8FKbXjW-ViKHwMEle37RxRrZDoRhGvyNtO2!kBaH74G11{c)Y?rp337XJYL4+ zbnUEHJC6`px+*s|7zzan2hGwhXKRxH-FEa^cc$^lto+YW43whsKN+X_pJ-<8LqM0X z-v#T{7AW{HtPTI*N@HtN*$Q?`IFx4YPOjFB@sC z0WH`F7UE#b<;=x9Yv$rDRaE?gsF;OKSN~az;SAZV{%R zNx`)YH#Dp`X9X4>Cfzq|Ni>3nt>*KK?{9x62q$HN`3mMjS34V}fY!h?&Cuu zEO7f{@cm#_8@;E}#yeuyAH^lapV-jbE9SP2Np%%28DTFUCmvACvt+ixEVNtDvo3^m z>`e`9lk3DylDS8B1uT3Vfi{kTFmKcmI4S1NZM2FLyqDx(g#Gb)z!?Q6m=N&@v>#En z*4ScY;KlWi(pRx%wchrowN0jj>1OwO7R$DLx4EBGZuCf2(K(Ov0drWT))q2AToO)i zCz*o%(3wIqOfAI69_!49Av_jXH>n1?yYm@nym`K5K9`}uh%f4PHMU`=(3CCyl|$?q z=B{VJw{rBthSdQa4U=!t5^GHy72!^I?>e!^fy8%mm!|5u7d}b@sndCOWC2}3fl>OI z_cq_aMTsHq+$_<6=}=KJoGpW?*c%3|P5C2ma?pW(zr41V@wR5}by?PvIS1um80ZBQ ztOdQK4_e39fqb^oXa$xxYQNMxw6D-CvIY9 z6tmoQKt#$i{}h5__-s@2v9Ov^rV3Btj)_9=lpw15>snH0K^J#3g#zX?ArUU~kbSG* zBXqSFp@F)(nKvO+FrQ?W?O`8*3x1)|`AiE-KpC z&k)flXVk%=ujUA5&B-xsFJeHBSSu~RIF{GA_}hTJ+VrGl0NT8(7Llb+R=1W@x02pM zma?OIyy#?g#dbGmU+BhxF#CMQf2u)FgN~Dh8O-Q z!~1`f;a`80;j%xX%R@!{`fkP>l384d)A<(3dvqf^zoUV}*L-~Ci_296FlvaV_^YgM$$1HoFQ{>G+J<$jS;EahjVoaf)fN}M3dvK^+`c!sd43aS5@8CKF&K$F}y4B z)M#vGw^vT&zg@)j9c4vGgut?PN*!swz8GCamv2we-P;rNgs+wS%JqJyv^(ISafFD! zx^EFA1uMw5<)k^4%#5=R8rPE*>HV()((V8utee-{;eCbgh1;m>z@VNC!a_)7gyvG* zSPFGOWtV>4NE@RiUR+_#mhaP1`twkGnUx15m?y7rL7?`uP_rY<69{~WCf;R|`<#HX zr-c;dKk-SCl|zQC7&c!45z#oahEP+S7t6^a!Cu~L*0v9(qQ2u{ul*?VGWqgQ)7snX zRFxA+{3Tl$dp%RAIxFe>Ne4@hx5t{c??Sgl!e~w`1mq7G$#W9QF>2u-X=N*ZaZ$RF zfkd;?AG{Q;RQHmNT8g9hBi7WAg@drgAW}YBi*y_7e4b>WA@birLcIE0{Lo8$`(4wl?tJ&U38IwG0yvyG>d&X}vN2$R`Z) z8u#~-3hc-d_F%sr8z!CIbQZp6&z&uslz9wKoYA%mh-`kmQ z0D{foX4@h6_2`un&ObOuE`A}ifXKd3qkThxt5i&0KFRNh41dOq1cvlY{l?A)?> zHh403oF&UCyX}j;R8*5sNknU&Pip%mXh5RP#oCfNbs3#4HUD6!Fj_r&Rx!#b+KVQ$ zt_dO^1SE4rA^wl0SnSHVdYF@!fnXZj&SyvBTc8X<(2H+^NS~;SKMuRJ*MYuEN^2O~ zW_{dmJ;m&4%(cBs<;(I)FKbL+)7u(3UhNe=6>H4I2aN4ahw8@eZSIqE4K~GV-WgE?QWCNDM?o=O{R@`7AbC;BEzqhxzwB{}PM6S7o5RJ&q3}Ep+7Mt;D(k@+@O-4?bRFb$_^Q z$fO1*;*E(lO|#-PXE8j-e56g)EON4R{23C~aKq{DXAfx!;T;#+iNiNcC|U#x>{HXg zw>BNuho*p`xs@p^pL^6PX|r5rhf~cVnQm~6vNmQ;{b3PYCi?_z^R0cdmdYk-MWz{y zGi~=Y`=7y_tGGTXR+*DfqW=OWma|;G5QBz;}>t@L=~@PUU=*VdBpW*dD~YD z_x~zG<62kiMDvQs2WuJTo=X0L7V8$xZ(?8uhQchfPY{EeCqz1ZOh>r+5`hXf-XV!* z`k9|G>B^o?Q{ZogI{Ex#KnnavhBLT$WTBRio+2|qHvUm z9nPERUojShCwUjut>NDe-uL*X1Zrz_JGJQ`%z4yC!wTU67hD$S%TQWa_y1oS8#<|t z|56}U`}zNuNpB_B!nYnoF}Jp8^}E&` zzlFC_Z;Ez$5TN<@iUev#_Z|M-79a5z`a-nT^LqdH`+o%cfQhwg)vndftA*SW_fx$@ z{fVo^8~@MDA2%j9Gk?U0%s)*SH!^qB#A%s%1rsx`C>WDBsi2nq>VE%So=lgsmi^;i zhK|S`GcJ6^`0;8XCOw?5gv%#go;x~sRA%3Cqb7~X9ZQ3K#*GF~g@09X`4sZ|u-rZ50>l9r`%;I6Q;B5celi zAQ^l88SJK~Qu=fhLr!5gFR*W%+XnVjvka(Oqky#IXauM?(g~CE^7Duzgg&BHF*RYi zrhya?_9C#;mkn*5%CI7rP1NO+HQ=Y>|J}Bn&ihDPVZmr>4l!7bxn?`ZYl#!RyI&}5 zc3xsD!0(wr^rDtenkk_cm0TjX1#q~V3tjOm=)`uhqKkyh1|b{k9uOaI@V-kTgmz|O zpfr$Q!ks@DJ(iOJ8hVq07~maZqZW*o=2yVTU~pQpNAJi6HEjet->%aAm_=ypG;Z)Q zPhlDq!q^0VR@gB0(Ux#^r^0mW2P8WnFeY<^>IBT&3oqgOhcwzUr>coI$m!IQnc?*? z2N8Nw&4awQF>k3pv??wj6y1Gk(b(4Px>S8mHk(dB48K#=RdO>SQOaFO{V&*=(bhC^^}NKxfSnQVYomN;za872=krVLKH&1&X;h zhzSWSop7H{tN;fU75b~Ga7QkAb^gFJ4}!LkIe58d^l}_{%*@NBhngcc{m>PapbN5C z(UKC;;lN+mTAO0&X8q;z%n-Ktytic*B!DUWr(uxItkziJl134XAfkxn+&9R%l8eIL zG%Wk}ca(6H;f=yuC|7rjCoS?CaqvZcT8;h$iiTNIoYNZ62H^@Y3@0~m4WT?p;3%3a zZY>%}H}}QD@KH-Jk&TN-A}6TS07zgYJK;pbp_3%snG@;y0S-|3qm4TWR(ea3-?gOY zuc)21tub^A@;a7KLXBW*n|Zl<+0pz&1E+$Hq$n<4P}&LSVniKgEn-i!4(HAEy1Ki) zezw;7uBMPsLW0u0C-RQl0|OxkFp;%(Y!RYD!hpWCuDwXCFi?%xkWrNS`cO^hN}B8?F}3u zG|x{^o$Q3~0FQF?I}r$ai&W&*o$U<*uVnzkMBQso?zA(Rk0^V^^^VMZo z8_k_S8!I*EtPNMmTE%=2k zc$Y265Ir!gia~S;kORv5g3{2?+&1BoV4D(MhxGAfY}G-G^V{eGAN;q-!Fq6?x;cYY zFieW&5DSq1LgpDpO{X@&rp8R?nRG|x0ZP%}!{mXE2k-8#@<;h7SX7Aj&2Pyo7%{02&dPKJeCst{@hDp zpwc``h8$DYCW|NQzO|WFlQNJ~%nlNA%w|6AxJ>2EQ*Gj}g=gE3&ybWuiZ&7??^K%Y zWbbLVfE*kC0e5w?Xjqon(kRPpAH{iaGFcZtfalRW`sbc0q zJBQkugEbXBNJWKg)|SuX}+}tp1z8@Wd=iF-9R=J3VO`lLcs7(wMAia%b zpu3r!Llvz-Y>O-_l*5Oh+E?m;EsA?H4Nl6XAzS)E3up^-Fg2ovV=Lg( zQ578g%?ehqys-kA*ZDdw_oxb198-a^Ot7*I7^*7w4-zN2esAJ5C_uF}4-6HtWgC4v zmo5xemnieVP)+%^Y|h#>PoLSLP|!lxndK}Wg5?k&3gc|0*Hu@#+*Ufke$2&_DdCuRS1DeiYOO6t#(lWmx#!#OpARJW> zgwF0baF+U`@g`Zu$&*->+Tr)RY(Ky`bi1Tn_xsR!ADSh8*|#WLO#~z!HHP}g5L9Dq zu@Cawr2kpz)l_&M((5?u1d?uC)%^^)EQ%J}rp`I$eX`!Y5kPf~50cAQ5S#BPXq3Nk z4l_$f4-K1c4NU{$Z4AUioXc6!{uZRgUx-fwRpRrM!Vw~?0iYgP08TOQ`vAFj;vG@p zSaPQz=W;klMXqF0rLb?A>z$>8$v$KY999`Ve4syYrQ8rK7^>Z)D{Z36E%MII2Hm#f zaKBi5QuISxv{*NTr}#v8pPdjX<|Ag*sEngZ-*-&uk8EjllbX`=EtQU8CvD|0o>Id;%peRuoyeMYWPt~$yB zSx-X}dD@!0Yw9A2sX2u8V0oHl;%2VRoMJw=a&;$++ zK|+5xtulbsMtO>F9A|bF zuoXh@r2<5-GMQ=iGbJ$jNjv4J%V3rrHrSQlN!fL0BW@pvub23y41e*ROI zd5+v;%_cHe4fQXV5oOdOkx`5yjSS9)2}V6u^-Fa^!tAstE2RhmOI4|#FSA!x0~4hR zCBqEzPATE4WV^|Y11S~>B7{Waq=U1_DU4}b^CL2~&@iiwSiR-?KU}7c*(5LJ6t6M1 z9vW{W8EG-RNbxGu#FNmW6wQ=?733)5aGS8-4=YBV$|swz;V*4E30-D|jSJPryq;pw z=fAfzZ&?-;(MI;4vm}S|-lv#o*@BHA9TvD0vk2hKYC3%qt_Eqy!LlnQsw!5dTW#Gf z%y*Pkm`j*+->^>b=>dNwqEg~$;`i+x5av*;BMl{BX{B8v*+{nq=2xv=H5plxln?ic z)1cN>LqsX2B8_caFA4c;rIn8yMbPa;^Fc~v5TfTYi81e_MJljt5gs*ASf&TF(9y{U zqLT%VPCjHD`!OR#9Cnm6JVP?j%6*{sR|Aa&Yn^a0UzLBH7My6W0l!dTB+R`-Knxi^ zNsD4~%8dCk4{;7U{S5hx6VGU2BNlL*?G8ggcEvH669KxTe?R(8(f^iHtr z5A?n$zPO^y{#U_&*iS01W7@BZkM9&mk=L#R-D~2*hq1L05Y-!m=OtFSK&Qeo8QOCS z2QhF>6uX2oorxwToIzI%;&>AbK>0y@my+xPdx>FZ z6pXvC)A^&%;>i%mtSBid%O0d}dG1ePA)N2mYmc(!a3w4wN}fVAFpO1$LCiPT(y7@- z>Xbq<6=J*A$(y_q5HCG54>`mBEkQbP2^m!h-qLKejHUH8I_jDEq86lN?z$mr8mb+* z?V2%1L6B&c>l|zVMRfTXYrA@b1Kp{4c(In7rAjex9v{ClUThUj5J)k7i~+*;2<6Zo zhgmx#U<|K}6@4X}HB_gg`k7wW0nor0A;Wxlyk*_yrLiKdC{G3L!z$A{G<#@InH?LvVmE@ZZhmAIW`b|kR?$oySw3I)@z)WpU2 z?WhSa$1_#a3~ItgJ)>d#S)#gMN7GQZNqb*sQ(8Y?yBqahLVFuJ9l zK=P`FSSBWUq4Ns8Cd<7L*Q*FuKaWu%;0^RyH1cD@I%K#F|r? zdA1LzMvQILBTPPey%-Xj^cXj)D+Q47qEM{*P%%cNm1tHwNFf}ELw?UPSzFVvmyEGk zgK|^wB3oozRqwXBGK4u|_>K>lpEZ2!lLWL1wlz=MHj~ZsJ`#v=spR!UC=qU6^plAY zYX^_M4rZnvwtEKft8Av*pETD3=3P#d7qhA64O&vcu3@1V{!IG8TBVUTVqybd<;g`$qgX*p`dR%5W65Ba(+1KqI4g=I(DB z_m|_#GKB1Hq?5es**AbBUc`Ytsls;YBWo#6GWXF+M|jw&%rM_N-vVY>s6aQe$Fi}c zNcM@Kmq!_0I`D`bHJQrSJE#sc3YUnfkvxV4Uaqz9sl?!J>XqRplvh$#=%u*$HW_pz zZ0-gitR9~?(jt8_HA3_X;iaRvtpG*KqvG(E(PXKIw>!>%?cvP*00}R5-sEGLh);Du z^qX$B+x`&6#1dV)*~TPr#6`ciHq2rS%w!NbS4jD>QG7lWgq0_hJrcUjDa&!VUpHE$ z6*4b2jFc2vJgxOpUTGL93Qo#%Wb&Y&_UpS6$Mf6 zeAE?MxA`E(2qz3A1R&GA#@Ehf6(2K7y$A=YZzY!NHU_vDp?(|x^fx1_=nJn&kU?k$ zZu4pZ(MWmJL5wJ6!q!dnvM3*HrZvj+3Yj{YHDoGaqrEEA@F*W_rnSoSvaM;Yt*Isx zHN8xxQy6VP(_{|wCo8ZRo?szf=OE6FIEbJ3A$}e=MjzrKVY1qG9#cCn*mfSHo!m$b z#6ybtU^6|gO#5u6$8Dw>V92zOOhq7bJ3k{v=v$j~i(75n75B^I;Da zU1XkU9P!)@S*&ivR#pIn*Er%dTMB|e6@r(7yyyA1jemM}f2Czmiv{gTfwtRro5!kw zn#(|Kr`s#2V>|!!*A3KeS8St-?E;X~4Ub-@Qieg%C5p)kz+Chg=Cf^Kld?WX)-Hxe z@03z}wq4d^TR0`^UCu4R1=S0E{H!>fPg&iH5LuE6>H9N~Cv>uM;C|C?JE@6L!+s_s|m=3pT^N3j7+Y1eVQo zqL1BjCS9OBo;{LCnT zsZDQ!(t%q+PpY^=wd8uIy+(2k4jqE_Sp*V|E7Kdo#6F`^3M@yc{za&mR5tvZFh<|; zOsu|Jn`C)udETR(5BO2ElolAM)#n~Pv()T^6kg}wNBsMQe{b+_KmQ)*ACo9JNoemL z7{$pfHcdz?4wOjqC^rA3e#Y)TE)MBF2vD=&NgQQTx3R@pe59EV0TeMcox->$Cu`~J zZmwo1K0>{r^pYm=x8YHQR`?dTiZE-I88j}lE*0Z_DoTNexbfiCY*@BpIpm%dB-%LK z2%1&BZS*7pJb#IHvHQZnLWDV}+U$6%8HZJ`39i;Bv$~*?FCq|Bz*m{IA@lYmG}u%m ztdKoLaJY`Din7r~fo=?GoWwWnP?VamR-nFSRbEvkfc}~cFRu=v4%LWr6P;LnX;%Eh zan4=ppL=kZdLsp?n`2*%VEkzEdGw?nI%5jqf>>UN6H|{DD~5nGYEJ+&iWSotXD46v zykQx1GM9soY;t^&0tW6PA5DIV#UV7)x>JNA!3)i7vVi%+DT*#5wFLJT&|bIHJDayC zzvecw+!|-TNs029rN0E6u+OUSTL9tmAjKG~Tj}+JR5&`8Wp1Gm2jsq^&@B|=FYL`e ztI+pVg=|Yzg(wgi0 z>q??*)}yh_a5<(o4d)d}doDFUMJ(^Q3Fj6>Tm#k$MloE&BRO7YbORQGK=2}aR0BFL zv4KYH!|9grN$FDcfT=@Mp<5u>hGGOdhc(NZBO#1Ch4dE4Ul#kx=tSYbASPJ^2DQFv{QJz;q?ul08(w2qM2B2Aa>R*~C?|0wsaYX) zBR+636u(w_;3MZJGi%o&hR>FKG4A z4g|Y07%V`vg)Fm`0XN&+;BUiyPBZu{`WJwOJ7d>ouVV$S0Ht0p!VBrkOz;h3h3#?* zQYguTZQ8%;vH6UM)SBt{q+l;2Ryk91T|`c2FH(JCC1i_;_((*j2F=SP$sma%k(Vc% zDrb^8n1#%TK90X$aiFuU^NlbBY+{5wJWlf^)!e}j4d#VM z+4Fuy{QY4tczqTpq%kmJ8RxgyOP4@c;-wS5Ka&vyk9d0|2XFyI=slC3!K5MUlYknK z5xd2N`n2oB?+OC`}eGIG*7!X`H> z8t!>YK8w$6{Dh$aXgSIrve(jCiTRTpSg0s#W;%m$9-N;txPg|NpL1D2Zfph~{*_y- zLAe>%$3Yyqqcn$%y9RRMOAN`$tbTmK)*8{ZEVDoZqTwvaEFAILloM>Vz&j(u8^9*7 z9rUkrB~6$+o55tiqJLhy`OoLLZ}q7gmmI67iM-bI%$b_Q64A8 z@Rmc;7nQ)?h)@~G$u5y`UP^0!Or_cmvglN;#OAz+FT!DnavVQ=&r@Bl#~AUewpr= z(ESBtrbShf`66_pjNp+ne;lya5BnLA%qa)uBSl^(i zH%#nKCPpR5e0r|?)I`gKwn-GsFOVHC8eu6^Lo1nVV1sQcDnMip{qCEVC6}8S>Hb1Hl*+Ibc>}M@jBIq<6$Ryjwyu zE3(UqOsj~gADOw>>*8*z3>Dk;O!^4Nlsdxzaopt$uUmx%5oR-IS?`zV=C1eg5H0zEHCVm7h=q{8!sUpjh7xgMbn40OYIvA1qPfF z@A7PW01@4cEVw)KdnU=!rBA0SPRvr(K;Clfw=VX#o1cS~jU3&{q5Q;dSrTpXEaS%^6=Qgs^| zsJzc!i%PS_pf(WZ0bAriceZ&TW?;+ld#ItoxKSiHq2zsH{mI*DVS)xR(eREVk4;*T zAa@A%{QN8n{4BhC=eR8Q`&mBpv)u1z;oX^kzrN0CId{Zop>VgccEs(%2j*3S|0hdK z(~*cz5HCwLfrv}JKKcsd5C^r}HQZuv`HAiqE2N9dgkUr}!-W!wg+(A`;kDrKLlY+A zU1$(aC0nterdfGSj@irXlW<-ToB}g;_@5bkB)F>>F9M8vjE+ALa!2*-zrh1-v~% zxVT}g!C_W9^U^iqSCUq(ZNa zw%xPL?bm3!o9}B&ue_O;UaVHNsck0Dn5+I(8xbYbOU^9P9TrW?plG%qj$BQS8@(`C z`|)bs;B4;j5QS*I1hQ-wFcILpndVvh=1CU(lw54q%=e`JA%yCj%0CIC$oEAahdnGX z0D@hgH8Dy|3H<%Tn@K4)J1hiQaN`;}>3O{N#g#PDwP z;{T+sn`foZKjmdwo9nZkDQ6fLbeX zU-RGwQL{=w902q|!4I(lUtJ1(#BT=)x)7Y$Bmjp9MetxXnT~;hp>y)jM9ikOC8{zt zrpHy9#SB9S^S1S!Y^#ij+DJ|I)W1z-tB0ka!L=q};!Ymdzhh>7^Qg@sF)ik7ylEJJ9Qwk8y177)g9 z0Ec-n|FA^S!8EOa=96jmnyGuO^3qN7jr><>*I+lgiXCaReqe=iUbWFTyP4J3i0g)U zcfglG|85w_^iFLMg-UB2R~eD6{TAT1`JwJh5a8-#*Q3_SkUeCBuUZu{QNy_+TWEz!JfzjiZ=)p71> zP{ro++S+MlNDfX@oYjW{T-BEd3wdptbUb_4sMOnAD1!m62ED+x*}?{-t0AZ)Z8di@ z_gV@`G9UYpQO*)DRecAMWSLhuszdOSwRAlZWf7+dMw#>q(iw-xsH&q|2xQv~j6^2U zMxN-lAsgHFH~B_R1UXv>K^RM?0n08XT03@7GQHC?V06Nu`Rr=V?RI7^tfMpaqKZ;e z8f&cVrw~$dAd_u(Yf9Wm^I&;@ApSCFWK?i!a9VJ(%$6jE$`=61Dab-LT!I@Ki@Ya1 z4N6$x%m3x^@Fj&|+Ei=-0&~Pb}cOI7o zt$Z;RAn!TO^=*l*Hql;LaV9Fz`C5+4EM8z&77cGx&6%tQ=W8IHno{C_dgrK5Il%wk zR1Qm(99Qb0L?ydz$9eX`iDdIBnOPf8?8k(4@H}u_xFnxxe_$#MWz}&AN=fr!rBW#U8Nty-yA0{3lIbizk2}F|mjODC)op;+nVwl~ zn1TH&CIhGUQZ03qco$nMh#ULQiMydX<_4In9gMpA6fHrT+kl^&2WZ%i&I`veiSp$M zw6~VzQ^ji5vt$!OGF#y!V3NXx!Hdeg%N(ihn+huB>1q|ntKvo$u z!Q4fYCjswq;ou}heElyC5o~f%wNOR1!JeA6olP^?`a4r(@n)>tc}@IJu1C~(n-Cdk z80~}d;$>&cnzZ_vGD0=AHLt^1`?**yDV1u$z57 z;-T{hJ4jI&$m$@B-@G~n96b`GxtFFus*llFz4)}Ic>ZbZp96%(W)q1mq>Y(dxjFJ= zc@J46z8+^c0?fv^Qs3GSqIa>ZFu?CjVPs)nWt2^v>4i>~)qvlQGZ_Yy9fIu3WF+r? zxr89pa#A@@q0Sr5z^n;{OwklDyMpl_qJ{7&5ij;knWW56JLVAX|r_>qJ?2 zITJ`8u1vyYhQ(E+TBb{ZwM#u;2>Un)C%tz{F_4=t^nBNp2oE5}Uy^oDm2Dwpo`md> z32B!((QdQXb+Lt^tJO~12GYH*Iq)o$Qlu57Vbe6XP6?ZDgFZLg4x>>;TaL@J4q-69 znN!f;qM`6%44G%a&Ci$ES7^;Ny>u$05H;8t-cAmCgY^{ko<-XE74<(PT~^D)%s6gs zI3jT>6u2?SmeqyAM^<2S9&w=T6Q`70fCE)M(NDQi>TozKY~GgxL~#h->kj4OpT;q} z3>c}knep3}Vu}3`!o%j>$ub+8Wuf>LjAZC3j=D@P$IfaVgp69SY=Ir9ml=M?R4oQg zOeHKiv5?Emsbe!b_F~q*(ZC=BeLfi4t;+*8hQcTuxMiZ;HIX_fH@Ige2QNetW{(NT z&>v2=_E58BGL-QQ16*#N0-Dp2l4)BmBFO>ltY#yLoEUnZLO5S^P zGG!1E#XH8>$mC`_rJ=`HLWt;$H646N?Hve(58!vOWU^M7cL~mpT%3qid4Zt+C{&I; zo3-s;W&Jc%oM&T>;UjQ2$YFYZ8H&=q7P5tf0-Or7qgGE!ADcMzHodTL=72)|=bht7 z7=|4JSB1*y@cHBvv4=$SJX78LI!R=c5TCBNKW)tuQ{2M4SKoe~#7a_>z@Q$Pq#-vq zC4?(bMnx$QK%wPf7sJvfk$EmVY{ZN+pDPsay$QwfCpC;u^**KGn2G zGUL#l-A&kylH8Biu;B?OlLT!zK+C%)$s}hs^4^}&!16<>X<6Awv)IzwGosHc|0cd` z1L*=>s43A84JiSZ^&+))v5zXyFNXzp7fC~6K2u#Og@@R+;05J(3H{`Q+T~_hyw%?Z z%2Gg;`^a*4oP%%@uDJskem`l0@B=u?|Gcde7eE=Khrq`4S6e7_2JnGUj{?d)kcUkq z#pqMUCL9cBPB-8-oO77`e~l2XvCx~$y8n0Zt>BGP-O0$!u+=Ftszf|UtvUrgfa!m1 z3Z=-yRJZkLc14d$=^2|6Ra>g3rWEh-9UB4-^NRgSz7@uY8wT$x3x42CRu}oJ+8P!y z%*_iY1$&tH6XLhv)4~D9ir^aevzu%m1bYVOmU!7RI2J3UF*6D8bU@2?&5}ruYZ67t z5f6tA?55e^M1aMNs6r_HK5NTrW4t??Em zr!!C5Z-F9a&qRp3s80M;>0zfr@ARxEJ!FB;snBy7Kko4&J*G(zcw=Jqd2da`5R*D< zrd_CK+eoN{@d!D&c(#r5p!cj`n*w;rMDek;b(lU}P=_#&+Znqc<^{rjWSPh6u&rY| z%6-KzOq9+(7)?6S&GuKgh*>tQHStcSv-b6r~7@ znGS0bw39cj`SP<<%uAh{ewiS}%*4%g!uc@OZ59jZQU+mByRVnx=61hp=?ysa9=6Yn z1gk+Et^>-Ks8Tl3Dla?hl){m7kS3WBawKH;3iD1TASl48gxZs>2jwOjhTXqdhxP>w zs0rOIw`1uIBh%c)}FR#^MJHw8jM0vE(Nsi|(OKVPV1H!y{Sc$6_O}xanVPqGbFVw>?VZlbgfh z^A!7ey8S%8E*pJ(rXSI|@|*+@zu4_jQ-mK>WBJF?eH?MUc3dl_n*BBU(Mb|WTATfF zK<&pSV*!_O7>gQHDXe2m?Dy%?C0-H5e(RMDPbmiNW4sGA z9bdQ#33o%?NRSP_#G4=iZeeU~p2GdYnyR*66*XJx`b+1J6E%6-nVae$ij)9N>nyYF zs%obs;h?XX#XP(M+Q8gLj&^GBFvPHxrrViqb@d)xL&6rDupRq12`m8SDVy+&OCX0U z3pcHLLea0T&pimeC);@0Cx<;uzV4YGHZ9My2OC@zA$PIpNz7H?1}W`er!{XU^43A| zm^A|~13trfl#re}=;`Izl6PSM#{VAvb zrZcA;?QA6Jyws#h^=fWbP8DYinFA!%aY>8(r1wZV1Ik%4SuPvaWaeb@1;J8t5+8n? zbj*imhy(Qc05NY6G!fQgMd-I!A_@Q|D(NP=Y(s*kIw{$^$l z6chpr1o-)D@KSdqINf}772SyQE->>&KK5cR4FU3(b!1dJCt zwDJ;45ipqX;eWnTD|9`$Qnq&@ z*7YOAxuLcj>#-Y-`5*rQOh`A?1Lz;GB>Sv-eAW$jd3J|hLFh3o4zj;v?a^k%@ud{0 zp}@EBkHD#U`DSYQd1Z*j+KE9Zk56kPaXX6z34bJ|qUQxCOLNj9RcIZ1HQR7$!Uxf2 zMV`tG&eb!LNgz+c!W?`f)qtrVHVq@#=5uCx#9lBvuRNAwzqdW_W^T6l4w>)k5^Fbu zv0}eS#A#+)q!OE@ZWjBsc%1OXoy$0E1Ehq^?Q|&3p5KFJ4o`4`$!uJYarbwGROu() zkr*jpF;?Yy47SvgyaHWhE{yOugD?}8kZ2;02ep;${~Zjrb;^jNQLdl7+x~9R?n>x@ zmplMtsvNobl@DhKGw-PZJ70AW$vp(;7~4C0L_vj059=c7J4TXF-}nh!iBX(iHUTk`K2B~P8eva z{I#A93O+-_ju%{g2$7rB+gmZ=C!A{fLt&hO(#HN@*?ZRth?azS7UJ4r?pJ3JDF}yJ z;w5jkVTBY~$W8zqYcLh#0d-A%6j$6jkH-O-&3kGBF!S^Z+K74g>C^0MnOtmp=IIPrGE@pQY&>8716awgePzgz*XG>LKUI1$rb z)Rc{lY4*UCqN+sm5ILNM`87Xfb-gI~$fkq$(JG5UVJ5ZvE3;66ZaiN@VC?C2MrdG3(N+;75C0oay@!HSD5{R-r>-58g*R20JGcR z7u{ux{>5yp=awt?9^ySKPi`EtP{9IPB%- zA7R|~WC>rmw+-TI)k(w!hG3IldYuOG$C^}#)tB!z zBWgdtCHS%s%1^^G2)C+nm@dymdT&sQc>tlr?&c2iQVwXQw`DbB`soOhT%&Tl)=suB z9}mr&hw4LMOmjCM9@ZP9TaJjM`S39CU_;~}OJNQ!t{t;+CyaPFBOoOYvHS!iC&}=7 z&o~=+H0#J@;v)nAra5vkq%Y=iKJC64c~zn>d~2Wf8pGM1&fFo|7xPP!J56-nV- z4pk_KKam(RyuZNav%NpVyd0T7YCCwodC_(_-K_IFyuZF3X!EF#kp1<;-uW3qV^a3- zBjDSy76G>rd%qe1m8{EYW;O__Lcn?-0ee9J1Thw|YhIG|aZf4&A2LXNGuGncKJ1f- zJ=#f2o9=ZSjOCR5GrPLCBGMzFBh9;GBWz(7Q@xLw5n$$L+5|I8lEQFj23+yn_at2d@=pOEL$IhDq6Tr?A7)qxt{~$~SQ~66 znHkG+09Uq>#|062QjUt6%?!>|&gI5mjILV!<`^lQ4J5Ko2cj^3t~|0ONF~@FZWdqwW zbHMM{O8Pz)cOCjcuM#5x?H8q+@^RKSK-ZBa9&W(uTQZiOznkPrzc$V>iB({wu&l5Q z6~DymT7p||#2XReY`!-_qOUi?y2bI3V}0j%=n9J!c&MdjuB!Z!jVh+?9b?({U`L{o zKI6LHpB|lWj~;P5!$6HNRJeng?)LICu$=%n(sExqJ0POeFPypkf005Y=(U8GIf=>C+?;34$38pr{C_s3_7z z6*FdN1Rcek0}ToyDqvPbL{!GP-{0D&1L`>Hy!Uh8Kdv8}vv=)^tEyJ5TJeUuFybEt z3r2l&AW=rHPUJgW%nB@Ys~(Q7NWmr;N)DHmPA0~Qp#+Qevn;~cO6$*Ttlw1q_auzY zFE{u=glD1pwAOgwubdUvaPF@gkrH{}lde1cFfSLq&~OHL*arZ+qZkNaWni>7IQY`n zzJP9a^93Xcf5W{1levw1hzcRm2O6hzgmG3T$NfYFg^ub+%U>*&<6{1_xIZ~YgYNmW zpiPlilr&X>Pg7q@Ba=jdl9yyy@(z}z5 zIl(n{5_fD`fe0@nP6{_!DMG$}mfc!7i7TiH0Hox&AjfaQ@}c7JulQPXM&h=7S2u3U z4`9oa8txxl@;So|_btKyL`huj{Ue_#ldsIDFqjG6kr|d$hNjxDI-a7A?671fI->`= zEmI6>yIV~lk599NaP8Jwd)ViXpl#g@#EQ940fRK=9e@3vW`0RTyE;EJw^H`ZH z#zz#-$9(`2a*M{7T1W>27ily8C7d zI_zNvdgtV*+la&$<*x2g-U3LGt(mfIBwKf7y91GGIpX3-tSS;-mf{-zdhC*4il{){ zJyiEB>TVk5CI!Tbxbj8tjbo}5z0qGawbhpHPT0`7ovL6odjU;;k(%TO;-v35rr{(w zZRbz{E8$c~^l5l%JGBHA13t~J2x_KTPxdrnlY!~Cc`WZKGTW2hNn!d2z_#Mb)gVVc(nQ<6t?$+UP_jbcb%{IYuepU5QR|#mB$^$iz!YJsE2>bluDS#JJmw zedw)8ZgwMZ0Icn}?-6ldpIJ(Tw5u#>F-aXGZqJ!9EH3Ae)IyZRQb=v7kAqJr2M>q= zv~r7!h5u0`Zotl#wcQ6)PNzyKmL*Ds9|2>!@6;c;j_$H52PP`kd7SD#qxXYhzVx%B z#E$j(R%h@Dz0d?HdTnt)@_k85n1u&@cW<4U!0nHq5Ksw{9~tdak>&9-HAl!yG3S)pn^8D0CmM-WJHzK) z!W9@7Hom=+)ce_Lxy30HRFFqB#M=*xP&^Ol*N5p&K3Eyxr1pn;Pal}_0@Mu@_sTQl z0iOD{hT2JWA2wvUurikf@Z3fb7T7XeO|ectXjJB#xfmTW*$ziC4aAAFSXT4GVCD4u z6D#NahDl+!2o?O6ZU+HTE0^Q}gFsz369{NYw%3xp872BmRIOQk85M|ooND<)Xf9SA z&8<>39|z0$W2l4SG52M|c&LC0x|$u+0vdsRh%1Ct0L2B^OHb}93=yiZO{<<%@oS-Z zj`&X*1}npFivu)5S$`dy1`&<^O^li)D*xYuZJVmu1||fzh270Dk@&;h4y+=^v#l0E z-i(j(6CrkeKq}bL6gu(`cOK+?luFNOoaB4q6svw=#ktyB$?sNlWnoNs_B6MXuCOSV zuyW8O+s+({^E^66O4Q#Oq^wGye(D~fN_I99w*1=XrOfv^MZO7yWyQw)W{h@?DnzaV zRs9)jUMEr=%)D&p?zIegZcetoE0ObQpCuNW%OMo1P=vu}jBU-4{98BF1*Fx@-g~%l z<(DElIkSuv?+!Gw#UIqX!zv-B0X55^Ke)Pcs2B$6nGsGxHx1|Y4cNaw%9p*1H%_4T zZHZFLDJ8WnN*#~g{gI&vIb+)CS5nZknD?F$uh~A>nX8Wi3iE+*y>QAk+LMsYw_p+k zgD=LV7iQC*)6mJ)auG_SN$m(y4+t z0si>@fg)#OQm(PSbar3T7b$rD4XKc>Mx!|8&nShT>fUTD1Jy+K*#@Wf?i;de`TQv~ zjWZsAfW6291>TaVGixyY77u=JEN?Ej5yGXCGigUaVVi@$FUN)6v^WUjtXm-Dxs=TGf7;&)Tsj;h_gKsC&1 zlAzn39gS-eI|Vte9?4rgdo0A* zKP2XUJB{+UPAIFuM*G#&rA_QU0f%z+*tlyLuecuMAIryud`u75Y>~$3>B?vfzBv}v(jn#0AkUuHygES*aApGix&KiOTHK`rxJZ4Hah!KHEAMqZrZ5(l1 zhuM|qmL^Q>mSHJ9D|$Cy9k`7SWQ5I`K&jg_jFGHrV%`Q0CZA?NzKDF9+Ste^pBiwD ze>_71+&nj(xULDF^no+f*<3f%l6)3?C3fx;!?3?}>+ubR7c%D}l+ z$9}N6@v@A+A@pK%JE`;Y0aC8}tO@?LhOv;o6trM`k6?#_bVWIdzFk6uqqUIh!^$h7 z79BXAiJWgM`p~d@)%@V4y8F#sUtCSo(+`N14~HdU!0Ljt;vz1GzecO{Jb{Yevioq7 ztr|PHr{1UAFkA3AZpjh12+g;_?gR9_u&rh*W1U#Df-c+Nauxy}C~ zJSH&dr6GSpwD|Nen!cR+=_y$Gh;U=(tkPLz>w_qL&>>5TS(k9 zg&1lFR1_>8(qMKob~4oQp3}=}b_&kbQ+w0G*Uggr`LG2n{yA85P`NLT`o|MtLg~j8 z<=RUw1rl9~{u`0t$rdG$Y}9YzkC3ANG5+KLp^U!|_`@|gC^!lRjQaZ%@1IoS>FW$R>QIB9YRU6p+a2 zpXmn06K_30m`_z?p{_p4awv%#NaRFW*OH2#JPi%#mV5Xut9e?m2)gy9yQ}DKN;ueA z4B;@PEh8-hbLe#L#%)m15(`~M+3>mdh{7v|Sik|D-pk#_(_k~Q$QVVcYff+9IL)qI z_bBMn>!+30%nw?7Ts2=!&8fol1wzR&{N-}!e|(xyZb#!9Ca$F*y!WU}7eMYkA5tR+ z-%Txb^t5t|{#V!?6W!*V18yhn)2BJser5z`0wAXMPKz5`z$SG@5iS4Pg1bo>{=h0) z!U2EK^4YA4e%s33{fF9&+4i!PTXt~My`ukNkbhBzpWV}bQ!G$};`P5+{-8Ld|L&gG zd4Xbyg49?Ee=pA2#_H;+CFH$jsvLV~33i0+?1rG@UT1jr5iUU`sI^c7&3BThacbDlcctn?KWLpns^s;RPRyV>$*FVaCF!iTVj^Z-`!=GD7Cr!4*&g9 zvp)m{A}y-FqeE+-y1Q>{5Ui!M<-YWih}HQ$2DH9|Pa1@svem8i#b!E^u3VP_106B58s7hM&pZM+hg zQ|oKTX+6npm>8^g8q66&gTGVKMzNkVxk&u}V!i%YYh(Ucu?2su*oHq)%qDNQ3Vv^s zSK@uelm)*zk`>}!i8(rGcKT^{m?g_qGbNz?dz?l^|B)_c8X8UIuKrsx4*ab(#(rzY zi+^jz-*`RM>c3uf-j|AC>E(0xAXs_;TToyVh0|`zglt1tGaXFo?$%5e!-+t{Ddn~S z{~Elu(w`UV_(=0iz0=m(2b(>sIWvl>ecvSx(!Z&9q6j17TW%-;~E> zBp&PXn8glbZ&h&MdKI(sKhMCbCG0*vAC%{Azyre|o-rkH?<8~Kcgyj7at!J4k1c%= zLdD~a6L2O|y^)3%~n* zsk>ez;8Ik(W@=eYRej5t>bBv<96B`G#I0~zF2$(H(3v6dVV%^G*5YS{qfcsiXqsXM z-HA*?-IMV0$m6-l4-vLU-~4gF?*|0ZOttZ{+PI%KT85YS*7z@wd}1Ihe}p{|tV;r2 z^iD`qW4^1|t4^o4YC&`h<6n0nb|j!^he%~QIuE73bIfCRbrsn(u&ZFM|Kq}Pcu4Ls z;ECwVv!b){o5T@7FHa=|Yp66}x~oH1oKAAK!@BP$tWWd6R3A6+S4c1dD=yYU_RynP&>cxoI{T!4>W#xK zRKR{zXIc%VGh69Qd(FTyW}und#whZldLjQ{Ny6g@#5EC|R5#UxGZK92rB5dM;Zu7E zJm?Y0USM9f19}a3ln2!Ym|{UXHt6eH!2l!{a4QljeqfU*pyfzAgXh{g?%mg@@8|@- z>f%@kDWGH1yRT44QCg5E>~U%BtgB?GJd7~betD>pN!UJ?@uMavjw|a-RE6Xf0w9*><2CUfCU71YeQmtLy&Gh{$ z60}*QCf{u&tCYDG#+GHJ__9mny(g1YxsGnv-#6*Y6DrB9{JMR7W@o9vDgk{1oV8YM zfK$()@x?UWE=+s_{8V(5U%spYfBFF5xPw1wfIq#!ca+U4UOnOG%L8XeLJM6RwmR9sIj`7_XTp^n^aQOv+e5HJ@l-T z?qY|rG<(A^MA#y=I+)W1>h9@QtWU?R(Zi(> zO6+EY-i6lB!!gm4(6O?g^<=1nyDvcH2CrKtG`;Hr)($V_xZ^Sz z?iRTYyM-XlKsEU?K1QF*tLe$drPv3{rpf!tWGA`ZUxdvqVUinml=V&K#f zzQv`iO9{C9={Hos%oKrI`Wb@w>;m++99-4;RGEe1>j0nCk-}&f#3aofKuNUbTbiCQ zN4rpXTj0^2bQ1e1?1W&{+YbKU`<0QMqlVC&S3^~m=$P#g7+zc<*TomHUU(?*{dq2c zvrbfC44XoQ_=xEY&cw#=ytvM@oyjo07hVwKAsSkP%O7ws0Ncgr+Og9zQm*yw`uGg< zR5>4qVQ5hCsS$g&i>cot62puN__VHq(Y^~4FuFo#$D_Vk5yc>rnw`k6Tx_W#_}HH$ zbN*e=gmFT>Pp#=LJFZQyI5e_6&?z+Q0z8!`{EiFt^|2Y|?AS@o;4K#?+XU0yC&6_2ll?e%3#XAplM^V%LBOPv`R&Tg_=@h6 z_&(sL-;2$sq7w#V=Y$4q7l#6Lr=s8` z@Dr{t*fqE6>-)kb!3|Jo83{z)x*I? z*Y=)uIle27rX&6m7Hx|{Kfb_U(%whAuniUbxWK-(2p<31(MLP|(uXJzZW8K-4Gbe{ z(oJK#1r=T9#8gh%%(gTVs{{x&b1Mx(6WrSdv1aa8doOmInUkMQaK*>Bm|#^>Onu|f z^J5y&S4qHHB`45Szr;i{r?&xi^a0tI7)H8joPS7Sa9M%nM=%jHn22U04ubh9;>VpJ zH|!lw0_IGBV15#Ffr3^SK^#*JAf7I!R4W*D!2bNG!M-5n`~gLr2!b_mCVw4=@k<2R z<}TVhn+?x)(w>3cMBv_v$5VJb8*uljg#;G1Z%sl2ee>SF$v{DLN6_W>6#ZiH z`7y@>gCiDDN8h>=sxEOU;r|&$6Is{=KHL)t5`g_eLi!25byo`F!7C`JQx{EBxAu}4 z3Pd!qjP6!7k=|GS`3}nelX`=e(=Yaa>Vke~^-A;IlQpRHdR%KJp*n*am;2^C+#FYO zhkA|Xu$dF$u=xtdkg0AS#ToQ&bY}EY&Q*sC%;)D}SVD(IyA(Q3J!Jod90R5ru!<`J zi25~3rlXhNk+`2e70;8MWXs@>iO5h8LYq?(r6BTx2^aFA3s@3rWhvJq5;>ffS_9Gt z?QhPfI^qp$Mv~RouM@ajm#Y$WZfnqBIY=OJ2B4p$+?RB!#QeccteqRg=r_~*l`O=~ z3<{ci3GHNPHHn(yeKPBEJD&V$*nluADl=N9LqREE(>-IPg?%>(GVxr>LDiar-{OJ&|VgP#Q)znz19r{fo` z2S&n%x!9#g{23JbNnV|!LkG&0+T}@w+_)w82KitYeL1S4DIlP{8cE6IFo z(05aIdyW}kXpfv%uGRHUh*(z3&nvg9gI%FloyFpMSBq=Od8n!7yZ1l}ZZXe1i7Fao z%No)S=Oi~Vs~+g{0X64_?5jfnwb<#sq8{8(fJ%)$w8Isl?ozCym%w{cSauN3?g4g9 zmp)7)o#XWbE%rs{VF5+oK2yW<6MciI|39c8KyCkpdVs-c>R90Ph2V6x;FRiiBLjEy z&fBALV2KiPb2JWg_4aEVa#|VT5u6_pN0hrq0K4yGoZ2qn*M5cfMsDzKE-rC((+l3) z>D?5bn?{w)P0;dXx_Q3LT=E0yKE!cI09d{=Rl2(>Yey!fw=$QSz}(5DW;;NB8OszX z|0s~hfpWNl`!w-vMs`yzU7m)9-77WaDE0btWA2mG7{A~Jo>Vof^Z}UUb=U@LeVgv= z@hRBcHg+p&Y02T+5jVWr4$SwE!E9R2B6G!ewhln0VyaLd?B9?xz{uCX_D7e>43oG< z{12YJwA_kp=k}$(622iCw?%YC?^ z>ib{1R_eA-so6fEfTY{vgX0+RRE%dZGddSqpcqG-J{u7INOkQ0nN-n?#={`F+?2-F zp{^V^&3gO7fj->Vr{Nm14H?jbMK5(fAwyULSJVNnDM*TS)8w@PMLKl~cf$?ycP#^Q3)&-czk6Jfq-^2Os66$@> zdk?x9cpv95{d5W&{Q6of$4{on2Mo|zptp~vlvVBdZsP&K{Q#gSj2}1z86Y1P35zbV z;O>{%(@htPintiA3-G|b8r;1y_u`be!UaA=(iVc8Yu!D8H(1A!^O!GJ820M*+-D2- zV)qI&mZ*VZqJ3G_c)_Mz0~}#X#_>1zPAy_|(aPVH3_8CRxS~wUH?B$lJP#&}ydVD! z9D#p@M4puxb#dwhd43QbUzLYiTDrT)kebp8^qtnaJn ze#?bE^=;FIZ5ETRE^FVG;GXlu&27O!9PBT-K4nwr-M8$ZGFmfTW4?v81lz8nob%5IpI?JsJ-t##)rnj zBzFV%$0calO6*_=_gM|Aykb}@ zdXhdU1zezwcbz2!VcJn7tjHVV)5&DjrfKV53hGw9EK!h0P%*W|1sY157NUCv-vCGj zF?7{jOq)`v?c9GX;9UiHPv*K;40s9Pdy(ugD#}Mpi*bF0Mxem_?74t>8YX|KNRgAq zLRL?fDIMEkK3-W+%GN&6eu!h|VME*}=fnFZr#xFld>=NMO0Kd>SOQe?vH9n;N~E&? z^Gf0}>ilH#o~k-#tBxBhIs*S^8@_`R9r;NeK|iii74J^2FbvXQK2selD*8bkZ&dX| z5rnGsBdBA6>Ub0PSylZwYzlSUOC4>(EUs53$J~7>I!^}rUg+KdROu2EBjxBKTat9c9ORlUTEsx z7V<9yJ?I+oHa*N@lL4_?;2N-(w~_({fJ-PQWhkcrixCkEjbYjHE#8xHRB}`&sl&4~ zbmCoOc=-_bB_69SVV)&mF2Q}|sOougAsLCic5trURY`Lb1-~Nc5bVNqm#BRfkiNSL z5so;Y0WQqbGRDWJ4Q$(J^{%N~p2P7s&<^nWCNFGimmbI{d#lIHav5-2h(!ufw-OZz zO{RSEfh;$TG{>#?lFHj_gw;hSJ&!v%>Y^mP%4Z@5^YzfslH@eNc|D5o;_iHkBWN)Dfs7uJd^Y)McQ(!xSt`h6kgB6&;6Y z&|=~t{3WV?&Fk+dpH1+qfwDHLkMYF<#T14)a%Ud?s@l2@s6Sxp-L?RsTS68%hwkCi zV;{BES&Z2Ba@vM9^@HAVT)Hba09AWCRPYz-$B{>T)FDmJiLc7OnqMD7^IW$yTr%@h}i=3Ue!A4 z-XS{xxV4`2$Qv`*zM-FI+Ds-)i0-Tx^T#ZK_%Y!hB0$Q&K~Pf4ui}$RA4BPbzQ4?O ziat~in)(I0-Ud4nhBa6A&27LBaoi=(O)ByyD;Ql7`-M|H!e#d)W5iu($g#p}ODFngU@2sDC-P8|NMQr|$l zBgM(%8XUvQ%6*RljU@8d;abi4Bi*NIDE2rk=ov6UhfR2LjEozW0wqStkyEY!Q+JH0 zb~AeXVs_qVpcaqWGuW>RlkU)$uMFuRM7+vSac?jQVoJB-T%9IIuzpg6P=>g@n7TSd zx3dWdpURy35jf}j#{1W)bYGPy=6^4t&S?nNQ^VlLe^N`53{Ta%H9rm^U3w83vD#Vd8l?t!63OWCr!uxK6_KpPXCDL!4h7tn2rw&9fLao*#z3w;_ByOyr7%;2}-Ohc!r zlv|9t{_tX^mpOmIE;d7O`$IYo)nUtZu$C}F>rD)c_(UJ9lwqxn=0+K){Z5U z&T({yEjVz@ zAZM(&as00IQ=u)j^{=#Pls6x?1)hyKQc93FsHB4e4vM1Nk*bIc;9hfpaTNo|Lw+B1 zR|R`&Z>lcDLl8zV=!TAiLl;ydo!K5kcy?U)#Vt&yiH4>aa%y`LTXo^ezz)Yn-}}KF z^(8f}696M%u|+NaS<9FrSxM(5+&`h<9O(fVj&Pva8*z_ z0nGAQ#?$E|Jd&x9;n=FFpCKupiX=CE6!v6&BM<(`3T2DUKuf4$e}7a*-?@{_V^cez ze<(+*;;6gn;Rv1y95+gAcin7y(1V@A4eC$S2U1srVX1jEkZ^I7;r9WYK|K&GBY>u@ zufQY}nG=@aoJZng>NG{W%|J%y1`AxR9EvXT?{W%4N6ycP9{88itvEO8&|3e>H1Rll z)1e5i^Pv?{lVY$)!n45LX;82Is&Mv#nJku@L2L4QgU=sWG!T})4eLe{$+f(Z${Pkh zyd73({Px4_vm#f>h?ty%d6di_!yM@i$o`EboO~&j%U1Q_B(BTTbpQ*eJ%=8M?n^K8 zcRBhlKettlS9P$z>bN&7=HB1J?zT%rG#qa$s3q((^h9wB0jStk{mIgs9J&mqySHn= zqLRiD1j@6Mw4a%@HOwW}n8Bpqb_t>}(qRO?4GDFaR{0RhD-DvnhAxX|y8ACFH?jOM zbF*~|OAQ|>sOd!fYW{ZdhiR?<3J-=(RL86Ih?pmWTDy=tmn|*d{%r5ZFV2Df^W{EfQjK+Nj@4W=iHsvJY= z(pjsOf5ppeXrzq-dzGCr3Ugjul~8K*|d0W-&0*iD^WhIuF$oTE$NWP#2wL_fhD zFbvVvO}FR%^)`(QV|nd(zhM9#Y1;AJ|sKbcd5P7R8g0>xP3e-iL-9K3jmh+Xbbfi_MK3 zokLTa6Zk;sbcz5BTWN8e298+r6BDyweo6hZHDYHF(H}7=V2+tEyQ|Z4kQDbC1e*JUXOMbnh z^6vo|A07efA;5!Mhz|eG+L4+~Dz3oSD9_c{*%J4&Ur7~b|1PC}SevE40C)MV+$Xge zN(ElrM<4(lFIS@Su83jXIZp7`X1m~P`_{_M;hXQxS%v>z9M3b0duj&<@)wq)le?B2 zoar9woC@HSV8PqneO)^a{v%=XLY;-#wTt-699N6eF5!% zM`vKrK=MP`fx>1&=g1v4@=!jQ02T6RCesG#ae%8_OJcv#!5;7%KQx%-0E6O+8~CNVmP+&HFlZoqNXr1+U5ZT%6eYJK7A8dH4qKTb z9r<`O%+Y|{Y{TlQ8H3o;yvYj7B552FyxHx8d|+?j&>b=t3b`|n+QRZ6x|?sd3lTj!0uH6Q?5fjG z2V!tQUU{z0>nyjI3rC%z0-x5=_UP3Aut$@1xPD-JwxPR`U>a=6&*(uV3tg>`Tn<)mAE^nYi6dR=wu~>YlJER^9$i{V zm(YHF&L7E$+_!QcYk^SGxO>zi;4=}RihZq_K9d`t>jTlt7DV@w-@4=w?`*K0o?Y>@ z%(0<+kh`ixmov97pD$!M3A6{&g)7OP2RBRH?XDmXT*hy!cwc zsY@O)ySO-zJ~-;;klv2-hjiT=XtW5`OVu~f)G>~YDP#!A+=g&AKu5V5mc-q66o8Y6 zsJDQU_|OdsnwygD;Jnvk{Ij+`y>`7yVa1gu`h5beTJFDshG`q3|9h&c%0TnfMb9qf zD_4bk(z%AZ?YLU`KR&VdF|lBLn@?N`zJkY0`6)0oKmQsg^ff$)9v9ALx~rK|-mEX{ zK>_y0r^tuVSnKTbO^<0c@i@GDmOzC(RfsY7tFGUH zxwzPx=ditS1&~Kq>fKlK17M`ywN(3pb#Y+WJyFy6e!1>x2z+&{SRKpm;{6PtMi0?R zH}>&L>)~d4xN>~7iuPNf%C@kydxr;b0pW6MN;-#N*ube26?43uxqbdCi+LE||Hkx1 z{JC-88<7x9_J}8()5wav=#x<>Db%luTuPfy3m?!z1eI)*%{q?a4pHnrwI~-u+!b6M zod2u4DmkWjJNkz3jE}k(+yE`3%pV(HE8D`KWET4D0?)s73jMH4_&i>p{gnQ`SZoZ- zMCt_h5!Bh}{-)5V4|$@D{3*Tp7NbPGe`O*mqZMJrPhk(n5==Bs%A2h9DQ=f4;*)g( zI&LA3kyHuPmg>lHrIvBD+d)RFBNpTZkuOSv7`k%2agM)Lw3f?RACjUKPLO=?yZ4KPF8H zg&j`v{U{Wm_qAqr)*H!L@coly5v%>sU#|Eb;|65HZYYfxG9)q)8{{l<4RLeGC2`Ik zE2VeU0;-o=I;fo2GeG6M-b28RBat^|sPQ4hY}ba#b$jV)!iAiI4x>mr6pViNIfnQ) zVM=!5C=SVJGRGar_=0H4hpOzKlVWf1;5s3+Pcr=pjC_;OC*byre2k|@&VMGN#w{oXpibQbFWKDxkt6; zq)cImBzJb(;Tj#I`wIwb(WEkw@;k^_Zv;uD9u8O=cuw`&`!)j;blfH;;W9{J5!hLH zpign<(0i%A^Mn>pC)zRtSS~tXsSGBvR>)ln`ISTH5Z=`7x(uSw*D8^jU#%HFr=zdc z$>;R7e|er!vUaU+hlUkxfT!D-8A!G|w~iDPm*{$JH??*oG?MpBxELAy(%?tXgBc0{ z2>%hAB|)2jSiTYAu$WI#Hf|PuKiYi<{hh%$=rARZBO3{10~xCO$fCX@1g&Ku+!`;e z^!>z4qm9o~YWBpz444x_dohjFM>{ell+qG2Z3Ua&L8Zr1X)hcOLzY0ITub9QgMAa2 z1|QKI?jtvG13c7ip*7`XE3KgUUYI;beX_d+rdBULMtm(NhinYu1DdYo7E!7f6G<*& zG6Y}Vqr!Bzm=?Gq^PH^8%b5$rqMZ@UQ9a@z(Ac2}r>$p(1L^vsM)@^&_n`$%6QxXE zbN4>hf{n2`3oWvR{x8#OYUq%N`kwtvQM5nw7w0&Wm|6g)_`92L_^hS-97++4e3Xj; zKL_Jdo*8?yhlzovjOdM6&Zh25f&sB5TD_h& z1UfZwkqb6W9JYxTmCI*a?;;GH$uK_2DD?#T7M*$|R%P0vd(HRbm1Rbrj`;C!77=b+sb z<%~dM3xt&hc|MiO|7?|`I7gY`>H+KUDxQx(%`F2ET*os9_smQXfUxNhw;9cP4RIxR zHn$(;j#+HYj_d)Ut^uf2h<|q@=&d)GBKSpy?iRu_0&CJR5ufyxWU9S~)qpvd7!{Bd z!B|&il>0Uczb%#tfsfhIT|!e~TLL36>^%xp^*XM{leOY*kloMN`8gT7ED~^_DC8c{&@Ucno8|@ z6u8`{NJaoOnnvX5O+a?FN)TuiOLZVT16)MYAADdma%G9{*j^;QQ&(_cuu&Ig+UD3v zFL+y&iF$M42wP~miG}uyHG2CICCd(<*@a4#g@A2Pi^eGd+l zM=gI-_YBLfzI2<0xH2o!*mPI>pJYi7SW5WT2R4Vz62m2#?OGlz@Z-1m>Yw1ok5}G>BE@UB2_fjRhHAz+vq;!@E1eCSm zn)Q=FPwq)hCOmADi|qeI4;6gz0__ux7x-|Yx9;6xgF3~%MezcPr-zmhjTK5>Zuf9T z&80xT5!hLxlrK|Ii1JMpp9Wi8tB^%`r0sm4=~N2c&y9=?Z!o-O<;{6 z%Af6vC`d|<;ychSHb-eDv-m!<2C4HjT!Sp}4@8ys6)JMe2w5l9$Zhne;br(Eq*O2W zd}fTN7&O`QnWa3Ha({IS1%tJnBCu)Lx8o$W1vnTaiQf|vZaV`h0URY9#fG>X-H!`q zQsEwg$*+PlsEd+p8i~WW2d0(R3A>fjI(KTbfrz-~mQx3Z!{?35siQ9bKGkG_9Ded% z4=0|QOs>1xt}erM?3?_KQkku%dvCssOzKOpm@hjZ;*s}qF%4YnpH2LVD6@MR3|sEa zOnhZju=8fyeC4`tZRM7t6#%o}w)(9Af#tppz#$t!?gvrfmIBR_5s9+k#*%W14i*8E zT@Ei=YM~z!=>dz16WF%P$jmgnsW4!70bC%oBQr+!p6*5Ph)%sh=tD#$hBItKh6jb* zZl>VTU?#NF2wZ-2AqX961c`{n{EGn0Llgr&NDG0nZld-^ZWq0RuL;h92cWC({pZkf zu#Gv)KVsa>$^t3}3ZJoPfdYXL3}fszj4?#UBn%@LRa33qa!}qpEe0ktv*tkV^H&kK z$?JeEZwe&=3M_%6RO(g^jl0cUNjV_i<(MAjmU2wD;#o;N841%1-O=h>i6OYO z$-JQ2Q-c??C*0n&95PI2@(8Us--63AUUHz8_?K0P;*~UEE{?f{wDMQClbbBqLwvWo zmr~o8jI6G^rgpRt&p^rU3kIiG0;wUm*~cMN*If~8kZT#vF;FaZ*x(Ewm#bq*u=n5@ z=c|0-ixkms22+|7+_ zC+|4ZQ2&((zlLF{3fqD%x3Zb|SmataUr(z1zBUVM?{K5+=Yf%$&hRNqeDW-6#q%mH z>>n9PYGGS#PB7d%Btj$JieL8* z#22T1h~lo$&-V_^gT*x-bh}e&Fyll|m=n+mPicMTV|?W=mIf|Fvq}H%|By#Zg@$mN9$^xNQIn zp5T)LGMjiEaBXjIAXUiPzk)<|kp=`dHstwE<^+ge1N9HPq!E@IOw{MaU`wbcK$P+| zBD>x93G^D ztq1vx-WuZ;>dSDqP@*;R1MW2>*B@wTi_P4g5jUWk_O`V%LMP~QAa%vomT>TAC>jvI z?5L0o(d$}H9SNR6(Kkb9H{#B`i%v31B4(7JNjMy;`n&q9TX!F5BpD=C9s^?n3=-+z z#u&h_7rgOe;Juqqc*J4FWTMXXN(|$t`$(z{r2s!7*%2*W=NL5^Y@dhqm9JAgWiZEQ zNz6T;PX;*0s{f%96DYr)UvBWKBNxLg$dZVAGT$Z-Y^~!sPo19O+jj(G>(Qjq!dRf} zSMnLeeI+(|Z&HeC@8ZqA*xP+2LTA)SyL_Z}LEueAsG*8vI|XheoP&@y>t!A4gqYKn zv6MK@z_hyOaUYxvrM;4}EQj|QQ?`9|cV38;!)h_zvVaTagVLt}R{m$tfYCpNA4r^uepY0nez%kIm^8*$|kb|3LE zjg&r&R(g&kQ};A8G#^c0rE6d4!yH>PXa=feYW;EsG8OOx$EBRP8HO6)Liw<^yG`#9 zbi^>uS`V^xwUf55 zd^6W@YpYTZ5AAUejzFo5!Cwa4Te_^c;!?r#Y;uxsG{CpI#4s2)C5mS|M6J#G&>|FZ z)NN-p%*83YJK$nD7`85wq3X)z@61R>= z@-do18*uN%dq7`cI(~>%#gxkn5f<+wbbz==^L07dK)Y>NxA08ri60Y(Y#nUH8e@-K z)ZY+fCo>1*-xg?~(ofNcYvFXky@-k*nG@RL+bx5}gEla$s206_yCQXS8K7?Aw$;N$ z3s0<(Ptg7({d)Sq+s8ncw;Oot2D6+uvqEdv&3eGCnr#7H-DMUhZ(L`86MJtw3*eF- zVRQ{xKkXF3L|c?!kYHatUZ~nDu^P^D-!L>W1?=l77lzGbEZb0e&lT5fSttb~`R zIZc7c`w$5%>VGx`OHCgd6W{V*kZ|1!Ag5&ITWHKHxhZc`C^LFpVS3nA_G-8=e{x^K zebIGv;jjn;>*01b0RhVCAk2zkRoIJfwFpT;BfEx~gyQBV<({}(iQ_^pELvl!z$`H2 zmZ*hEfx9QET??5{sEkk_DDPp0M()6Y3W0%tSJCpI=zYJZC~6jJ^_8IL@;^}YouKII zpA==rZLC}jxX&@dp3n^%Cj^;Ve3oMD{3n_q+5sz~t;UxEfRO`&$%Xs?VY|o4#GZYc zOt}tbR)*`wQYagyL&3$HmH9R!DrT__MI~Y{1g?0d`O`E|&GR;U4<}~t`o!#gVzc)W zY-Y{rb7$zxspTHiysaE2Q*rlplRf^ZVBWgJ*P>>e1fUC;n7XdjrtY{xW80-`NVh7S zz(>I0s9@rLPuT@3`{mEdcCTD7KWo%xj^0My)hhemA1k|9W%vE0tbAZ-u)*9hMCQ&0 zYICPHnVqq|(GsyJ5>t1ipj2(@;=_!QJ)o-;uF+US5QRvMZD>TX6uJ-3f_UU)1jkr1UsmFUzzP6L#7UVCT8O? z1-=9N4gK`5*oGY-T^bCp$kYIWpnb@l80YBKiu&wy-6mO6`?$*DiafN`w}AmJX(`vs z0D_YQR=WO}yTX%lvrtK>3HCaBFg zv|4nc^7ihsWE7g1hlsI+-kqd@^}(ZynjrDkfFC!$nGN}xCx{-uKBc@NBj4lwb!#iVbkK(NzBX1F++4+G4{KgfI7(tsY zNa7IpQ7tiqXi9<~CT$rFaWHa>8(FiB34sP&4jH1@Iz) zswX~WiHEzj)f1n##Qv@+}`o68_2qdVcBbG9IG**6f(X6Gt=8rTWNkHG{&(A3(hLFGQ~> z{NcFO7xV#78&Q>yS_a%Nzz%=(U*{xZX-K;Kh04rAB-uj7e_~s-5!-?%F@)TeVnBVv zGvk^KH-q>u(!ymMHV+kWyH|eYlD<}ijHUxSC!?AUYzzF^x`(o)u~tIKByNAH?eU%T zsFv0SLXtDgby=|rUAVs}`|niHXBhE6P|Un9-=l)p)lBlo!qDx@B0bbX4*hS$w zOw-X_PR9F&`)7@W;(({Y7j0PR5H=Cqo_spPux9Y7nL9um z$52d6z*ai9N9fx$z8#C$l#ghrL#Pixj>tPwZmuzJ1Z=gt;aHLB8yMjf!74#gzReWj zZDmC_GvW=5{T|pkv{YyP4~tR?fJ%wm63jaguWs5ET^6@8G~9EF$SpW z?YwoPThwvMAT z9AJp`Xj+99CrgGqKxY`_TsjJWeJ`0r_}6f=sk<%jh>+0KiTJ--wbLrAMJLSt6O#GN zptCcoKCo&MmCgZj@K$CZ6+>p&Rx)j7AN{&ep!fgZMW9*mFzfuc=+UlH#^1jIxBh`* z=%o`6^%2^;H%Bh~vQ0+P+K$wxu#4hwh4Hr*ar~joQzIt30q88b+AeIX!cS4SZrJUa z40_~}5^>L>Xvu-~Dm>LR6u7cW26PxuRDcqRxw@?l&5XGwH8QQMVXNl47Z6$Zat|S( z$aT-#^TQWOn#M`+T+Il0?g?tFM~yi`1%G!-iF>TGP-FAtAaub$5lyF?xhbdVs z1kw+GFoyOLGC|gQATVG{Z-$Df6qE$TI=KBn3GSxvsDJD0g%0c2hdTJ92PF#BaLb7; zZ=#oN&K z3S`qmUUcS=U7n4pVL4gEv_lCPA)NSQFuIgBP}4-dw=aZK=5DoCaXqIMjsG}(DTg6g zj~6BmoG;`$DCAzdkd?p60nS%1jPf8U4NoE!?^o)}7nUMg zgVvU5*RcpcqwYSMphKG+LguEO$qW}SgjHdojihO)6JkyJhYHH4uAIY#>@9f&(t;!A z-4u|cEP8u2-{`~|e?+;aptxOGAA?A$ zhffOWVrOb->&}k4C)qDzFo`*thcpsS5AJ0f4D?BhtF-z$K1%UxK!XiLjC?k_6f=eS zIn1Tx{6m>3G)0C`L2*p3o7hJj<=10(pK&Vz4~mLmX%z+X@m@6DjCG-lr0xq5_bxc6 z2gH9)3_>p|eq28C23A~0ZsK4fypoLVXF`qoT*2hu#50penExg+^US~3b8I4x!U8ZU z1Xc3Z=xWX)Qr6M;t06#%j-H(CrcMM=xT$IJDs}v3%5hm8;j$rNw|R<0^Igqv5@29v z=Rs&go_+Jzajd$;42k^l{mMQb@pQwr*iDFiuDR$FXhJCq(^?R4-LBMmrI$5z8f2lVL~`{Zh~bnmYI zG36h8+`-3i*ntJX<)Kc6MPH+y&GC9x%)%wu66>psLv4(=iDeWX=`AOK9|+Qr9dq0q>}Z0M++v{dPjaKsa|w8&Zt zyb>`O>V#%kg7BGHrdBwf+c4KB;B z#M&}LlcyaE^(`u4Ki-=Sil#(TXcP3*m`dc>e>&!bzr)hN ze0xukC$*o%ojCPL2Kq1qtrtd7ih&-VAQ0*jdX>#M(~@oqXa@Hw_Cv}N7}(~y&(M|B z`}{yT((OW&j9IVJAeGJE3B)q>Btb!}9aHI!Vu@P)_qhFiMP>c>pXdBqd|6@OhgJPE zHhZwaw7JJ%ApSfP+$gw7?^lNZNSIO6g5MUCR*hzDpw7#{InBeHS&ijxAGiii&unlF z*wO7BjfN3KI#d@k>b~Y~$f}!@6GJjNy0q%zHb(WV{sr8%A;4Yheu}$vCOi(2mgF8! z;4gYJPqqBcOT1yFM^$hd&DWKsOg}>q)VD#&Ut+&H5Dk4dPn;u6JLOzKPQxP}eSlM8 zL`_TT=uaIXckXzSh~PpZ>eus!9W{YtW0Z^dtw~n!BOKo)_!?PH{l8SV4d^u0emetd z5e5Ul3827l_dv}`-KR143{B5voFlp&1j@&E+3A$$-h?34)(_qrx>t435ov?0hoc`R zea<{|roqrs=eG0qPCFCx-A1xjN765<7cbI_tgy?*!oe+JHepfh%0Z&foj(q*oXBM8 zc7rY3cI229w(R8d5x>q4`uqjNcKTwUU%=_d#RlqNHf!jJkc;QWz&=7q{urLbY+%jb zWv6BxV$zrTMl*b!zP|n#bQI*l^M_G7W8G5JDr83nsdI{`*nAmB}hXvpNww0M*;jdsGJPFRT;C`ZXfSL2z+h?!-eY3#nuMxhZk zD7wH+@Jqmvue;t6MF)Y?UCwv`*Zy3(HH&BRzMRV~H5W(O(|zN`zRsWuA7Xbfd=VJa z^2&YwQsu}W;d9ZZ`eCH0tIf)zj{PI;z_~Jy!{?ik)yxj}J`1?6!lPSVOs%=kjEuUu zc@g~zRos||!xsk$FYVYbN#o{xZ63SvbDW%Eai51UN;moezU%OQ3bWR{$lso13Jdvw zZ7?KIcYa&4WBc^?%`XAi9o=#}3LCq3fTeP^)J;T6^Q~B+BJU=+?R=V}4b9MJBI7mx zo?53!PC{;iJx*JDmTS4=HKtfUOg-pJCAWyq88$WZFz`IWWC~6*J!i_`I42&}rdSaxy zM<1@q)0X&~`(h-$yXE4zWw4Jdm#ZnAQ^@xTbTj71O{L6ecaxmgU4woFHV7tN-;VE_}rgkz=!AzbgZKr7Jvp>UdZ99xmuES=MgIzbGt_BUeM8tkejVj_W5SzZ);GY7>MCUvj;p3TOsTGf7@_yTkHEpvzY+SS}QP`Vk$+OCIY z&|d*SXM3{NF8;N&By>!0;XE$2W}li_AvQM59FP?=<< zf79}jgTc%!38*4NIK5t^gR`;oBqH_IzHLftpW4TF8vw9|0&lICK?z_L^Da0Iz=a~~ zr?)}swvlE$gTFwo(iNqGX<2U$U{dwTYWsMkgrlkMW}CKFZkg3)-~FKjF)y}UJ4n@D zswllpE(bQbc?Knz#XY3YS2DH)O};r((J>wt~0Lq3H(3C#;9*?y&?||55oKfc0IYdpo=33Ghw*H{k2+RwQ!#iv|5F z0B+941i<+z7npiRQ3AyKKu?al;uZA($z#AG-~A&$G0=S=PUlb3H=*^=*H)561~4k} ze1mRb01OVdD^H*U`(b5kfgaESSoJp14@c9K~(cP-3?0d3QR(2^_ zvQC2HM{SZF`n2rQ%1ZWB;gMHgVVh33Z3^$?ZJ&CkPkPIMyVEdQ5}UFN6Zn$KkYE?e zozwj=30onhJv0=JyO++1x(ARm%PBJi>at()_r&MbzyA57X@be$va&+_EMmT2z&48OA-U&^7SVJA7!S*xJ#<~G4wV1@e=*W54**e zK$Kjo3aO7;&M8^ij&75q<2(DCC^}F)(o(Fql5ONw~gi zLojCP^T~kXOS#vXkxJ^HP|>8ju1|ysiX|+*vN&67BO@%(Jnp7tp!9mG)QTnRM=zRD zv_l@EGrfNmJdSuBc&uUJCCd`M&T6_&CPs~842c?QxF=u?=DYQ*wG5;>2&@~yB=62F zq2&dixD;9ph0Y>yExl);(^FBTqz?yp4Oe<*i{h9~6|=gh8)T*Cm*wu1G@XS*Ieg6{ z>6iquVKs1#B}}MU%xnGZS3hSnZ?(f1b_rmtu?-zOa(Sp` z>ThFWX#5Xr{7cN)(`AW$&`-batqDxh?P+`b5nW7Kwm(Osq`Zg1OvRbU5$++(`VMt3 zAVCLvAx!5;hbybp6HWTIaRO@_EsZp0X?oQ%Z1g4#mf^phIIUqxU)MrWz|wmxv&=W% zZ(T?ZZ4y+=#$mzDLJ6$ao<#SrHHTHE>8@a3Go`BS>a*rlMiMvvMoPY0tQqk*5$s2VE(5-#FvQ-IW#P`b;(8iEyZdImhl7 zxf1&fr7U&rCB#Hv&sD+OtDuTHyvVwzaC7jzOgrM<;QMQQrxzGja%+1BhFr#_Y=|c& z$FO*NB1MR8J-yYlI1(}U+F11bxqrYC)}ecZx;e<>TSG&uYh7Fg0wqE6Ifek4#c-ok_U4AX0^1@pC*8*j7?#~1gv&Ml9zsZccW@ah(>DgB9dOF)y<@8oer&@Af zpDs9{u@}=(umsqrxb=jd%95u8^@jO52Ru=U#d&`U*J^GHb4PP%-kGQE2Z2`x%6eEI zmAVJdE>pQ}jJA=?-A#LFKS2!KN_qlVx1!IOJ=3QT;?8#-`raqd@SF+wa$J23=qS((@vrZt7Eq18~(*6dz3?M$H&g|*nzasfWN|%Xic6-FPfP}** zWs1+9;nPnt==k)(K6_XIv&qr^gZpA?0Tbo;pyPdEQXEYUs&$mlo<&_8H`#7Nq&JU< z7qaC(H@ntJQ@n#uCm^YPcg4 z0XY^~8?oSJE8RtfGABlZ1QdgAB@0Rjpkf_bF}CYHEYo0ZyvF!ix_fzNFIPPC6q8oh zBUC4YkDkcEsIk;NHx4Ep%i(cN@8f54Qa!;+=7eAb>zG1J?En=(Xdehi+hcRs(YMD| zk>lnP-(&!|XFf|e%UuUk)P}+>(8!8MeT;Q-cM_`>EeEO9A=wJNJ~Xot?;Hp5Y^Q&k z`$sKSPl->1vNN~LZTk2y3^*yS0+jC=4UQFs1TZbn08^nyZC`#2zKG#j@ntGs;HzB0 zIAjTx&I&z-&jV0sfQx7+JclP07r84LTLoAojcpMa188&yoVZT&YHof1j{DOYU>cG ztpR_$wg(lVaM7Ma2ZBxKa>C)RD(JbD3Vx)5+TngBMg9JL2@}(*#Q7>QlanVm+}|e; zV(D_k*JH)z5TUjXf1n~ZIt_OSrR?yiXeQdMtYMpK*iD=1(C)HFe-Jg*F--htngcyaGD#pZ1*PWLKTsGRqr*bcN6tyayig0fqnzmazSudj(ADpgB+Nlnzi-z94fg&qcs5o&G++m58c z)q1XGbhuvE@Y({aI>?ZM&c1CQ7Ez!Nq)nKMtpa)OBM-FsM)D;0t0FwdsS|G@o+TRC zb3!Oi@>e?Yc%4YfPM@;L*D3HR{n$J$fn!||w)7Jr*yB8OqG@sis^>wcX>JATSWWui z+zGDY1Uo19KnUU3D5bwx$Guz}bwhW>xu{*kh~PMsl2@zIoFk&U4v_ay_uYkHP{b9c z0}I`CnG7*!KvvQDe~|-$c1v3-X$}>+UTz2R)Vre~ruGpX94;k%hC7`S;LNMR{uvwx z;E#{t`oLGc76wlpkj7`=d9dzvI4+RtSX1Plv6bc9!+p#&BMUj!U4J19=}NAFz2xmt zW8xFiZR%s4sMle*lO3>ewF~2p2__0!pI*kH#>i0b*e%}}^Ts1F-3{iRMTEbLDD+KYi=0y~?lDww~%e0J=mw)*BOF2mtuJa@oA)%F=!wwKCK8?RSD z4fWzpggIM?73(lS(0z=AJr#N3eYr(w1ybPiiZtt+iZJYJLE63C2k3gXBwz5XGRr8_ z%Wb10d6mz~vy40#ZuN5ST9Ks{uiNc)NignDXo)FUf{Qh*ooV{rz+uqx3TsB@P-Zvfn1qILDDRP0?|VqcU-@7Qj<)9D>af7N3-jHk; z-3OqXaix6aoM_;2Q>WCd9bntdTs%`0tnSv}vbY7Rv^OTGZXIM(C&J;11&0gdLcFF~Mmr~QbeLMCv;quX8UOO2_IK0N?WF+%)yB}i>JRPD z{!DBYOA&;2kSm#=v_yndb-CG2y8L7Vb-8AwzH&W;!vV<5ml|L+4U9nKa(T5Fhd-t# z%F*AeTqG6`MckhUFf~0%L(7$d^yM}DF{B7hgI&?jW-^=MzZIG*;_fMq1e!2v`G8v9 zWG%Z4+3C{uO~oRf03?l< zzC7F`^(7<&x}bv$?XoAJq-98&hsZGaJ<+D0FVNvi0Yx#JdCI7DkxNs;*tJ5y@v>rz zE_I+m$~;DO%t50%%0|T+=~OkUqdsI*Yw8;fc&<-BtEg~w;o3F6_BRUYo_?dx806DW z0AaGv)8$zrDw+uLDDO*a+JP zZ@RkFheJzzT|~HmyT}+7OUPTtZO6?+7PPLeZ)r?KCcdxJzca!E-~q|7l*X=&aToZi zKKONR%vjyu)UU?6dio;$P93Y1sYQoEF7u^gZ!_?L5xIra#h+i^ruVbn=dz}Y_? z>1P%he)9DIQUWmQEPa)Ae+~{2SsEU*_9H_ny#P7~LDYRnw!;Y{1#N_4I)|NYXqHji z(2bUdG~Nhc1pl8+y0Birj%Ho0_)m&88$M=4ZyDcy0R4;kY<7(R1$U309ItAZA>HCG z^DYvL*7T?@E8CEX7fJwTOG*MYAd}Y}P=)VXg)`_%3F0rr4~Sk4uJ}0V`PsR6V~Jsw zkLA(ghLS+#kDhn>gnD+vw>z0A4#&|I*5_>mdt{m1#^L)ie{b-2FWi>*_?wM>{>?R` z#)hKwJ~7CCRyzLk(ve>(9l8IPO8?fj$Ngf@e{0(-|Etp5f3fs$?Rn36a3}vT)S7+z z-^|$1|ElzopOkiUp&%x^uV9?rh7sG(7ESb*rhWTQD*1g&uGwe5H2hy^`xlqoslQnI zw@%!G|Elzcxqo=tC$>zgkzAuBR0EM+(hnKw`bnz68~+!MIQy*P!V$xV7Y-hO_Nd~~ z6VEFw89A}=%#ml6Od46kz6SsPyF7(K&KmX;yqrFHi4!7cjvJ>&s(p%#P{J9L z&L|#JJi74svqw)lt9UGJ9(VRx<3^4t9zUUQ*x2FY&mK9vV8Zaxg=2@0E;wV-*x_S} z3n!j^_LwtA3>!IiLgAP(=blwKZhY|>lSYo2SU6_n*hy0grX1Ge^#6yw_l~cs+V;K) zletL(0TNoImjKcdKo0hTO50Qw6+s1r>?BmBDC)7WLsdku7YHC?MLeho2Cyqwu@N{b z_JWEnc2Ru3zp>U%0)pqc_r2%d_kBP256E6?&Na)Jqs=kK9J5$c!;p9mZCr-(kI(bsX zA<=t_df-uk(2U*G5y=PR!NMj_IcNBk+-XyCM;8b%|4v@EKPq8$3MK~Bd6a%nI0iQU-%BSUf6f_~n>TXQ zg~Aum2{sBJ&Yc_#trEK3b_u&U@u*b@U3Sl;Ca=U`PTtiaZZk*h*G(bO2)`6U#142P z@f8Xs+)>KM6yy&GBxL*jHhO4hU7&I)TNR%11Tx04?!r>4 zrzjX-S735xsO%}Ge5QxGmoQXLmd%$8lKL%cL3j1RzIfv$>_wK+0UL$)QF!IhY8V-# zNhyQqdTw2lnSY>d3)0yOv2%PE=OIq0+mo>3oI0aQ8dGke<_>bhi}L*uImF{BB5^1i z+e)-P_flm?!6A7M2B{YPNVSCR6sr_&oK^H#pXM77o2tZ2v(@}d1a(^8t{Y}^*2 z$T-~cDr}#2U|BhopB7zNHY>VFbJsG*y8ZCFpA_kA2Zn{x_?(APe_If=$!{xHBtxyc#J$Y!<+ zC-qY|y=kKEvV7l-{5&+>O-C660JK&A&E4rGz6qaqRMG*n9lgd{vv!YCTDvE|CSz6A zW%63OZ2+Ziq`lsfImcEkW~&#hWOqA<#nL^brQ;)f(h4`d3ttesvrm;l;^s?B%vAz9 zSN{fd{wzrmn6(qzmpXd)mAy;8CI{me>(8g(CxOKC_*7?n__Uv@{g|MHS5bC{kffdC zT88?oQGtaeNs+GD>6jKK;NMx{_H3rw>fARC$IBbLPK`~+L{B8>`4s84Ir^MknLdBH zBuGg@pD(J~T&q@CSZI5F-hQLE3xba|;9bGTH|XQfFDV=F!QWEtCaSf>)#f85kvz_} zesoE2JsiypQTdYcW_AS4tWYy=l{d3M)$k^;0&sw(Ht&+XC?6vIK-0&?;`4k82mUT6 zl<|_Xy9D1;3l9VxX|m4;9j#MGo69GgSxU9_iH_!RKd)F#Q5mb@%HwiY^J4&S_ax`I zF}^=l83XJ_eq+3R28YHJ++cNk`Lp_y2TAlZ36m_LNx7^Lrhk#Wkcdz?{bmJ+yXD|p z6%cF(Y)j9#g9U?exq^3?C+v>k!S35i_Cn7AE>d-{s;XL8i>q>jYS@;ObOO)26=B$NArVkhplpGAgDtZO7ar|X1r_uk0<(BlvIGBvAJ6mGIW2i3a@DuR)H1u0yJOr z9jow0Iab^iRC`m^?kLBKH&ks$VzE9?=4itZTp9ZagqyG8`_})OOAS}4bmg6J}>;*SKN4GJv zbGQ<^#KNB!0Gfpe2zVpmcDj|I3TyAaU`;2{4!pRzxaLZFAL_V*Zm-{y-Eb|FcbvNB zyO{f&&y4ff+vngcwnk)=jwqAhB=@oL^!{!U1kcrM^u;SJQUkr>c``RR*g_~CJ&B|5 z>#5ntunVvTWfrThZdFEVHqSsY{b2VwR@@N`{*ZA9gSl6Qdiav4*p^0YfuA-Uv$%J# zBuS) zAi;RDVG++!hwyz_57m>pm_x{qr){-l%ZE@8tUA0d!x`J zk?tqObfSMAG=j*gi|0iVofw~)53yLMqZV=QD?M^jzHd|LN0aLx{f^f2+%q(Aiso3% z<7w_$9>LGkqMoEhUC68|zvv?uM}s4WRS=|0XJgV?gY)H_)TqCNhKB{tc#3BH0*$?0 zB@~`t=yIL|%d{JD0{}p`jA=K6EmSG-O}F`O$t`_`IU8>V&P;G812SSGkQ^1XCeylz zVT}Zo&4?|=svH$Q_cJ^70C<~z1RP`+#5j$5feaKEAxDRngVQ_AaV$lFG=hUkmke~Q zK;J6ofTZ=nb`JuiauOaa(=CcRHx>My={syhr;PcwF`vc%D6=s)_u{zwsY*6~&ARzBR+Xc~Wmdbq;^1rVkI#pIewcOEJ=$Bw1MzfC4F4K;Y4q-P&vsJV7YgeL`yO^=VW z{bXGyZ?%KBlX+|G(rUpeVQ@u~ggT>;6*5xz9`UR|7Zoh-(HQq!#IYUa0%8fr?PdwN zQI!+gWh&zoy}N>UnW>z>DDauR&=)y+d=m#t2s?MtEza^1=HZ;ine8=OmcwdL)|xMAi?-5XkqN8s02krr__qMJK^>TOl#(@k@$Ln z7;#4WFn~RgfjE#cFm5cf*>JI3d1gtg%SkNGzI&t3}9Q_Zgzz9}gJ-{DrJ zt-c5jxBemmuUwo_+a>QzETUROMtyuz+NXj({WGm;ov<$`+0DxmU7TM#4M|$7&1^F zDbu8TtIn&2cRCO%Fc%tc7%=6Y-{!c@0lMWDHj=9Vc`THcQjm7N9frZR1I zrJ%YPd!SF&Do`jJx-VHr&h(NB2-Uh9S_8?Os8K+?M4YRD z)OmdcQqb4)JgLfknL#K-e?7K<&4%o;1WGS9#Mc0M!-W9f|XSMed&+4Zs`v$#;py#QBaKt3$ zLVXVK>r3I+wZgBA5Wgy6Jo!4novZ+NJ~kA{bhlb}D6QqshCB1iaVOA-Ukh>PU8~sA z5vIX-&U5b_5O+L*YN|8Yy?Z_d#U3pT13SwcHe z4w7n9#p!Yz%gH=*oiU3trW|cJ5<%6`c9fGFe|1Cxtcde&yo@K7f+7H4IU<3DNP4`- zAkqLNK!8ZTVa%T$BR>`2!WOoJ9|@JkAcD!krWZqP5;+YHpC?O=;`tywGZpwoj2_u3 zuLBG^3}#$nGlePKwgJZOA@Y|?(WKPGr0M)lBr|+uCP67~_l3m?F0p~=1UDyw1qr8k z9i>UQuq>;^dn&t@vP`bLMQ{4zLJT(`1ifRtk!JB3$>NOqG^*o4xDz!CnD%#q|3?>M z!eUdl47 zINEMcwm6x;&NAFh@~xFUE-V)i>V?loyDKi0wTf?;HeAZ?d&$O|mjRBPd1Di+xE5 zR0IC_#D&@JF~rIf7Z&k1s=o>(e}XEFiHo?+ACrsyEbQPhYpAB$Zw8&l+*(!*%z24r zW3Tfd-=^~rwO_#E6}A0RiDaJ&_w$KlnEWM9qR72;w)5Riu+KUh9-7g4meC5sdED~P(>4y_lT_p zfei;o*zYZ7JOkW^jCC=i`H%@Tit)23z)~GR*QRe3e4B~g3f>s@>Rf8@o=bN-Tl_@V zm_H^YkA>j&2*Yi#?`u$OdJ?1P8W}ALV6-5~wMHhj-ItVJokZFPjuz{!nhoAwz$dk% z96r%h+-Csg6yDV5Ixic1b?q*$2hhmSUF`gb3{M_XIV<3C+dUNURX_pCrc>xM$*s6V zmkAux&o}MOBv@hCOz%ic143fl1#-)_fPOz(g8=_;L&J zC$h`1pPF7ZM)GjNmwM;;!MWmV!N)&_A79~1Yz}Mf*}K<~OqG3acOPPk?IGJC=EA5h z;}9DhOyOvwlxPiJ!q$XzT2c4IG_#D(s|sWJep*Q)r%UgufNp-(P#t}w3iKUlqkEa% zo@0e!Bn%2={TXzWY2a2aRuygF#BX8r9Pv*W*#hevsxpyD6O$vZSzJ4b;Qfebs8jIar+`ZlSpy?KTCbJdJJX7V za<^A4#`iESNH`-cJ{hpxlK|Udz@`n}0sJE$2hek`v)G;ub5%&T8C-6g&inu?n%czb zm55 z+1^$7IOh16g0SsCEoX?j-z6}1xu=5lc%mv7lmD>q29N1TIuCWLxp-0@gjZ}#L)|~P z|1Swq{ED~ar+&011~oij2%PR-_Hb%tgsH_LYppZZ1!e#C4VB1X8!Uiiz#@EZaYQS#LO_)uN{vOyMy{hvZ#bXD7+|Dj+Q@^H zpcAJc9j*fnYe2S~Bg=O4S$UN4AK+;S!$YXWC7HI0g%DfJ4L3F^lcV%J)Lh-byd)qi z_oRVrpnH_h1o$gyxgp%JYOz0*D=>K5MvES}pJvk@=2s)gpuLI)O|_1Ne45$d3bXqn=*ALWz)haKjEafUV0VUAv!zBaKxC}FOcckt)VU9>I)Z0S|Mq)fe0iGPKx)bO#1&Lhgg9>}RMS`gBfZ zID2_>et{p9VJf-?hYy%0nEFIAnEKcSFvli=MwDNRwR##%?Fgm{FNtWD)s)l)K1geT z5SyV&FC{SY*UI|}vAtA)Iqba!oPV%78GwefhsdyYG(8MoPE3dR&ctj>=(#MB0sQ`e z==ZTZJ{)cfe`hLxvO5CNkVAqm7<;NP!#n9O6~zH;ka}UCiqvf$_x()I zX-tMI`aRlhHMOz})@+UAX!rV`o+X^JC}+#jg;vJfR)gan=)3Cp9U}zpcD*o=wC})5 z;KpDH{P2@xOar%Ez<)b|!D-^ls9^fv-2{cg=oP#ABn zVbRXE7ntF%1;_BG1aEumZJ?Gshd4>{6W!XXF;rV#4qj?9bS^GF;nv7pR|HA-)>VcgyKqS~BX|2`WOk z?0`3FFC3^02CnTK@jFSk;dXcTpy~|82^`%fhK|M?vKa5SqxqNl&;CZ`N$5k0iRkZE zK{KKM3>Ar24fKjClih1TK^72%jQnRWQL~Q$gOLPfWj-&JRpQha9%3LdDu};6bzavmdC8aM+L8^_373JBb;A2i-#EM(O;EZCKuYSe1T133|9Sh2I~a zA5Uc7tyPB(7AHEmr!u&;pANPM9WV+s>4zZ#_>0tNpc+d6m3fz0;SIpkO{?ne{xGe| zyXi9WysZQmE4aPdy+vwbrhJD6^d>V_76{0Do(6PRVn9nObDm^B1Ntx+5WD;?z9F$5 zfyH3U`PvbpHM1j(kX26LhwL6okvXG-D>QfjZAygkYf{+Wz7W8L1RnVM&o5JztJh^1 z>k`Abx-ugz6MJQG6yJrTusDjx0R9o27)*)z(Ole{K>l?`5huFMh8sg&@Eqg0#JB0| z`v;r;;B8ZTn}h(Ov4jMkqLDnE7)jv)h~bYA1s-7(j5VIhboNXIU7)os$`GQ{AIiFYO#0zQDdtW|J>S|zuL*TC!(-GhD$XB7G2hsoE;Io-By3>TuJn~+^j zcR?AJePra<-R&aIUK%AaK8o<6lVQZnggCIpG-z&zmOYmi-)rhu1KQEnHcD&+6)xU=NbyJg%XLC7KS*6@{sl|whsb-_Q9?#+7+z-ZCG*rlZ z-=HIkBwQt^xiq!JH%M;kGYdJ)4W!S<$SY%6ru)L2El0cS*@_Qh;YT5Y$yKP;g=_7y z^%~`_3)w~Re6*ga9i?_zJzvd07|F?pjnHciw}KNjZ%wu1jd!FvD<2>kn8S6v`ON_(PGBbCd<)FfL4*mR*I;zAO@_Hd;o0erwgVoT0J~L z<(sX=hOU^L9^fYBTgwYKSz(&nkX-VnuXDR1)9Mh8)_gsKIokb%PK)V-$w78=twFsE zEDn}p4a?FM_WleEs7g(NLrZkQlRT(Vt4E5 z8pHqA1ET@NN|MYUowO8CbHz!nl5Pt#kBP|!XJ)K*EIyp&xm39LT5%SZT#bTEfIhg5 z1pa+)1JGwH=##?b2Hd8}8EK}87EokRAk`=!l2PUMsWJCmaQUb8%^Yr+%1ljO#rBmg7L08khtJ5WPH2le68c*=WiREncL4lvh-++R1bA?Z4=SR{mihYs^wggUGJkCaU&I_B=bHi z&%i?k;2CwBSc&0?HhtFJ%_7N#iG0eARay8}o8rJ;GtR!4V7m_#uUXc$ce@RjV{YB~ zEW8p}8u=Fym#b!HhT80I`4T>0!l|r$wHS*a-{}}%pG$1p=KK2G)Q#-}IJN~nw5Iu< z%heFOVt~GTAXZi64jwiP)#Eu9 z;(Ic;_HylZPU$t^=y&~C=GI936DKPZ~4B7q4Fwj4;( zaUq30fjD$=QXh)Sg69rA8-ppUq^z{S>v`an;vTMsFMJB*vlb|x!Vnqk!9ZCWdYNq_ zSeVNzwsScwAOo`9WUV~H$Ms2&gi}fgF#(x^$x-}PX&EGgo|?jdpRPt0;lJI6pykc| zQ%Xb~&+_RgFJcMk*UGh6Nq?x@iai9@n6dc>3+ zFvU5Ql1HYB>**gJ`b{;~V!;%QL?O>Qu^B_Z9R8D%TE{2N^oLB>;_U`_+`Y-z(H@C7 z$TSZdV)Asg0(5_!QkJ!Go?0lS1w|`|)}sY_cLTvjp_6atWQ(u6RR^$hu)Sn+*xI(I zi>niS)1T>KHRjUH>L^0Emu(`!98YkcYf0XL=|?t#!AYs`!sj+5sXV+AXKXgb|-ndeAmhuI4DRvOx{->FqE`5GNlG zAo${GqSWs0p|*z4?#0t&_Rer?V4VaRW|00SkOZG0ZDsE*Gpx(uV7t2V9r25;@puhT zj6KOKbozFbJONiR7IdN?7)#ea{?a_(o@Tni0H<vk?+)fvL$R_;|=G4X?| z{j@SM&_XSU3b2q_#TM>0DjqYPSKZzH6<)QW`I92DQV(^7r>o62ZqLCbJjZAd$st2> z_XryiQEG zm=883GRq&zJtBxw@&<8a8}$Eiu<2Iw+k&JxD^v_XKqCp=1_?M zSHd(}f+du)flDdK${a&3oC=1fc#$2|$)MwkC0J9J&l=hngq+vtFK=!!u-F*SYVM$V~I%c9Q&E zVk{o{(y;0V$b;67~!m%I7YvOUSt zR>0*k_((JSZGIc)I3|~sJ+88!L(YZLQX5Edf+4|zUR3e3)yWL`$YhjOlF~!W_;9Ll z+=uvr+ z?R+)S0c`-^`PH*K5e0{Zi)X0%+Ul{yIgS(6)Ro-cng+imXv&pNiYB@lqOygQ9jp`; zyC%ilb>!pdhGNdreL;?vZn%BP&sB?=ns;R<9GQ2E(-3GMia#w;T9@}H@gI45;F@~3 zT)%ekH3PXrzuyd6x;ZU-sT%&6My#l8x|=nQyX=Npkb5h6aloflX=aTp4oquj;gx~= z6()ff^KsnT9-CTg$yqQ2%sN5TET#Q9#2~c
!uGdojxBf2+Ljd1g3jQVajo32Yl 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

TW^3)ezJ^s369MWJ1^#2-67^tu3+~UHC?H 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

M{BL{yiO>7|-T9(# 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 literal 0 HcmV?d00001 diff --git a/demos/source/app.d b/demos/source/app.d index ede93b5..003922b 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -203,12 +203,10 @@ void mainLoop(void* arg) temp_fps = 0; } - SDL_Event event; while (SDL_PollEvent(&event)) { - version(WebAssembly)ImGui_ImplSDL2_ProcessEvent(&event); - else ImGui_ImplSDL2_ProcessEvent(&event); + ImGui_ImplSDL2_ProcessEvent(&event); if(launcher.event)launcher.event(&event); if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) { quit(); @@ -278,7 +276,8 @@ void mainLoop(void* arg) } else { - ImGuiImplOpenGL2NewFrame(); + //ImGuiImplOpenGL2NewFrame(); + ImGui_ImplOpenGL3_NewFrame(); ImGuiImplSDL2NewFrame(launcher.window); } @@ -632,7 +631,9 @@ void mainLoop(void* arg) igRender(); version(WebAssembly)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); - else ImGuiImplOpenGL2RenderDrawData(igGetDrawData()); + else version(Android)ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); + else ImGui_ImplOpenGL3_RenderDrawData(igGetDrawData()); + //ImGuiImplOpenGL2RenderDrawData(igGetDrawData()); //launcher.renderer.clear(); //launcher.renderer.present(); @@ -652,15 +653,48 @@ void quit() version(WebAssembly)emscripten_cancel_main_loop(); } -int main(int argc, char** argv) +version(Android) { + export extern (C) int SDL_main(int argc, char** args) + { + return app_main(argc,args); + } + + import ldc.attributes; + + extern (C) __gshared + { + @section(".tdata") + int _tlsstart = 0; + @section(".tcommon") + int _tlsend = 0; + } + +} +else +{ + extern (C) int main(int argc, char** argv) + { + return app_main(argc,argv); + } +} + +int app_main(int argc, char** argv) +//int main(int argc, char** argv) +{ + + version(BindSDL_Static){} + else + { + loadSDL(); + loadSDLImage(); + } if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s", SDL_GetError()); return -1; } - SDL_version sdl_version; SDL_GetVersion(&sdl_version); printf("SDL version: %u.%u.%u\n",cast(uint)sdl_version.major,cast(uint)sdl_version.minor,cast(uint)sdl_version.patch); @@ -692,6 +726,21 @@ int main(int argc, char** argv) return -3; } } + else version(Android) + { + //gladLoadGL(); + gladLoadGLES2(x => SDL_GL_GetProcAddress(x)); + if(!ImGuiImplSDL2InitForOpenGL(launcher.window,launcher.gl_context)) + { + printf("ImGui initialization failed!"); + return -2; + } + if(!ImGui_ImplOpenGL3_Init("#version 100")) + { + printf("ImGui OpenGL initialization failed!"); + return -3; + } + } else { gladLoadGL(); @@ -700,13 +749,14 @@ int main(int argc, char** argv) printf("ImGui initialization failed!"); return -2; } - if(!ImGuiImplOpenGL2Init()) + //if(!ImGuiImplOpenGL2Init()) + if(!ImGui_ImplOpenGL3_Init("#version 120")) { printf("ImGui OpenGL initialization failed!"); return -3; } } - + ImFontConfig* config = ImFontConfig_ImFontConfig(); ImGuiIO* io = igGetIO(); const ushort* font_ranges = ImFontAtlas_GetGlyphRangesDefault(io.Fonts); diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 5615f0d..45dd06d 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -1392,7 +1392,7 @@ struct UpgradeCollisionSystem if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(0xFF))) { Entity* entity = launcher.manager.getEntity(id); - if(entity.hasComponent(CShip.component_id)) + if(entity && entity.hasComponent(CShip.component_id)) { launcher.manager.sendEvent(id, EUpgrade()); launcher.manager.removeEntity(data.entity[i].id); diff --git a/demos/source/game_core/job_updater.d b/demos/source/game_core/job_updater.d index 47d2423..025da6e 100644 --- a/demos/source/game_core/job_updater.d +++ b/demos/source/game_core/job_updater.d @@ -37,12 +37,17 @@ struct ECSJobUpdater //pool.unregistExternalThread(thread_data); if(jobs)Mallocator.dispose(jobs); version(WebAssembly)pthread_key_delete(tls_key); + else version(Android)pthread_key_delete(tls_key); } version(WebAssembly) { __gshared pthread_key_t tls_key; } + else version(Android) + { + __gshared pthread_key_t tls_key; + } else static uint thread_id = 0; ThreadPool pool; @@ -105,6 +110,7 @@ struct ECSJobUpdater void onCreate(uint threads_count) { version(WebAssembly)pthread_key_create(&tls_key, null); + else version(Android)pthread_key_create(&tls_key, null); pool.initialize(); thread_data = pool.registerExternalThread(); @@ -116,6 +122,7 @@ struct ECSJobUpdater uint getThreadID() @nogc nothrow { version(WebAssembly)return cast(int)pthread_getspecific(tls_key); + else version(Android)return cast(int)pthread_getspecific(tls_key); else return thread_id; } @@ -200,6 +207,11 @@ struct ECSJobUpdater } else job.execute(); } + else version(Android) + { + pthread_setspecific(tls_key, cast(void*)th_data.threadId); + job.execute(); + } else { updater.thread_id = th_data.threadId; diff --git a/demos/utils/dub.json b/demos/utils/dub.json index d8ecfb1..5302fd8 100644 --- a/demos/utils/dub.json +++ b/demos/utils/dub.json @@ -15,14 +15,13 @@ "../external/sources" ], "dependencies": { - "bindbc-sdl":"0.13.0", + "bindbc-sdl":"0.19.0", "ecs":{"path":"../../"} }, "versions": [ "BindSDL_Image", "SDL_2010" ], - "configurations" : [ { "name" : "default", diff --git a/demos/utils/source/ecs_utils/gfx/buffer.d b/demos/utils/source/ecs_utils/gfx/buffer.d index b11cb85..bfdad62 100644 --- a/demos/utils/source/ecs_utils/gfx/buffer.d +++ b/demos/utils/source/ecs_utils/gfx/buffer.d @@ -2,8 +2,12 @@ module ecs_utils.gfx.buffer; import bubel.ecs.std; -import glad.gl.gl; -import glad.gl.gles2; +//import glad.gl.gl; +//import glad.gl.gles2; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; extern(C): @@ -64,13 +68,13 @@ struct Buffer void map(BindTarget target) nothrow { bind(target); - data.map_ptr = glMapBuffer(target,GL_WRITE_ONLY); + version(Android){}else data.map_ptr = glMapBuffer(target,GL_WRITE_ONLY); } void map(uint offset, uint size, BindTarget target, uint flags = MapFlagBits.write | MapFlagBits.flush_explict | MapFlagBits.invalidate_buffer) nothrow { bind(target); - data.map_ptr = glMapBufferRange(target,offset,size,flags); + version(Android){}else data.map_ptr = glMapBufferRange(target,offset,size,flags); } void flush(uint offset, uint size, BindTarget target) nothrow diff --git a/demos/utils/source/ecs_utils/gfx/material.d b/demos/utils/source/ecs_utils/gfx/material.d index fbd88b9..1bde9c8 100644 --- a/demos/utils/source/ecs_utils/gfx/material.d +++ b/demos/utils/source/ecs_utils/gfx/material.d @@ -6,7 +6,9 @@ import bubel.ecs.std; import ecs_utils.gfx.shader; -import glad.gl.gl; +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; //import mutils.serializer.json; diff --git a/demos/utils/source/ecs_utils/gfx/mesh.d b/demos/utils/source/ecs_utils/gfx/mesh.d index 20d5855..e953778 100644 --- a/demos/utils/source/ecs_utils/gfx/mesh.d +++ b/demos/utils/source/ecs_utils/gfx/mesh.d @@ -6,7 +6,9 @@ import bubel.ecs.std; import ecs_utils.gfx.buffer; -import glad.gl.gl; +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; //import mutils.serializer.json; extern(C): diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index fcd6a88..93d009e 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -12,6 +12,7 @@ import ecs_utils.math.vector; import bubel.ecs.block_allocator; import bubel.ecs.vector; version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; else import glad.gl.gl; version = ver1; @@ -637,6 +638,7 @@ struct Renderer if(threads[thread_id].block.items >= VertexBlock.max_items) { //pushBlock(threads[thread_id].block); + prepared_items += threads[thread_id].block.items; threads[thread_id].blocks.add(threads[thread_id].block); threads[thread_id].block = getBlock(); } @@ -667,6 +669,10 @@ struct Renderer { glDepthRangef(0,1); } + else version(Android) + { + glDepthRangef(0,1); + } else { glDepthRange(0,1); diff --git a/demos/utils/source/ecs_utils/gfx/shader.d b/demos/utils/source/ecs_utils/gfx/shader.d index 5e24d9a..e941289 100644 --- a/demos/utils/source/ecs_utils/gfx/shader.d +++ b/demos/utils/source/ecs_utils/gfx/shader.d @@ -4,7 +4,9 @@ import bindbc.sdl; import bubel.ecs.std; -import glad.gl.gl; +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; //version = ver1; @@ -67,10 +69,12 @@ 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"; const char* buffer = data.code.ptr; char* ver; version(WebAssembly)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr; + else version(Android)ver = cast(char*)"#define ver1 1\n#define GLES\n".ptr; else ver = cast(char*)"#define ver1 1\n".ptr; /*switch(__ecs_used_technique) { diff --git a/demos/utils/source/ecs_utils/gfx/texture.d b/demos/utils/source/ecs_utils/gfx/texture.d index d4e2089..7affed3 100644 --- a/demos/utils/source/ecs_utils/gfx/texture.d +++ b/demos/utils/source/ecs_utils/gfx/texture.d @@ -6,7 +6,9 @@ import bubel.ecs.std; import ecs_utils.math.vector; -import glad.gl.gl; +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; extern(C): diff --git a/demos/utils/source/ecs_utils/imgui_bind.d b/demos/utils/source/ecs_utils/imgui_bind.d index b6572cb..a65b6b2 100644 --- a/demos/utils/source/ecs_utils/imgui_bind.d +++ b/demos/utils/source/ecs_utils/imgui_bind.d @@ -22,7 +22,9 @@ else : import bindbc.sdl; -import glad.gl.gl; +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; import cimgui.cimgui; @@ -210,7 +212,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons() // SDL_CaptureMouse() let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't e.g. trigger the OS window resize cursor. // The function is only supported from SDL 2.0.4 (released Jan 2016) - bool any_mouse_button_down = ImGui::IsAnyMouseDown(); + bool any_mouse_button_down = ImGui.IsAnyMouseDown(); SDL_CaptureMouse(any_mouse_button_down ? SDL_TRUE : SDL_FALSE); //#else*/ if (SDL_GetWindowFlags(g_Window) & SDL_WINDOW_INPUT_FOCUS) @@ -291,10 +293,11 @@ void ImGuiImplSDL2NewFrame(SDL_Window* window) int w, h; int display_w, display_h; SDL_GetWindowSize(window, &w, &h); - SDL_GL_GetDrawableSize(window, &display_w, &display_h); + // SDL_GL_GetDrawableSize(window, &display_w, &display_h); FIXME: you see io.DisplaySize = ImVec2(cast(float)w, cast(float)h); - if (w > 0 && h > 0) - io.DisplayFramebufferScale = ImVec2(cast(float)display_w / w, cast(float)display_h / h); + // if (w > 0 && h > 0) + // io.DisplayFramebufferScale = ImVec2(cast(float)display_w / w, cast(float)display_h / h); + io.DisplayFramebufferScale = ImVec2(1,1); // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) frequency = SDL_GetPerformanceFrequency(); @@ -310,89 +313,460 @@ void ImGuiImplSDL2NewFrame(SDL_Window* window) } +__gshared GLuint g_GlVersion = 0; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2) +__gshared char[32] g_GlslVersionString = ""; // Specified by user or detected based on compile time GL settings. +//__gshared GLuint g_FontTexture = 0; +__gshared GLuint g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; +__gshared int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; // Uniforms location +__gshared int g_AttribLocationVtxPos = 0, g_AttribLocationVtxUV = 0, g_AttribLocationVtxColor = 0; // Vertex attributes location +__gshared uint g_VboHandle = 0, g_ElementsHandle = 0; - - - - - - - -bool ImGuiImplOpenGL2Init() +bool ImGui_ImplOpenGL3_Init(const char* glsl_version) { // Setup back-end capabilities flags ImGuiIO* io = igGetIO(); - io.BackendRendererName = "imgui_impl_opengl2"; + io.BackendRendererName = "imgui_impl_opengl3"; + + + // Store GLSL version string so we can refer to it later in case we recreate shaders. + // Note: GLSL version is NOT the same as GL version. Leave this to null if unsure. +/*#if defined(IMGUI_IMPL_OPENGL_ES2) + if (glsl_version == null) + glsl_version = "#version 100"; +#elif defined(IMGUI_IMPL_OPENGL_ES3) + if (glsl_version == null) + glsl_version = "#version 300 es"; +#elif defined(__APPLE__) + if (glsl_version == null) + glsl_version = "#version 150"; +#else + if (glsl_version == null) + glsl_version = "#version 130"; +#endif + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersionString));*/ + //const (char)*glsl_version = "#version 100"; + import core.stdc.string; + strcpy(g_GlslVersionString.ptr, glsl_version); + strcat(g_GlslVersionString.ptr, "\n"); + + // Dummy construct to make it easily visible in the IDE and debugger which GL loader has been selected. + // The code actually never uses the 'gl_loader' variable! It is only here so you can read it! + // If auto-detection fails or doesn't select the same GL loader file as used by your application, + // you are likely to get a crash below. + // You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line. + /*const char* gl_loader = "Unknown"; + IM_UNUSED(gl_loader); +#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) + gl_loader = "GL3W"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) + gl_loader = "GLEW"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) + gl_loader = "GLAD"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) + gl_loader = "glbinding2"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) + gl_loader = "glbinding3"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) + gl_loader = "custom"; +#else + gl_loader = "none"; +#endif*/ + + // Make a dummy GL call (we don't actually need the result) + // IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code. + // Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above. + /*GLint current_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);*/ + return true; } -void ImGuiImplOpenGL2Shutdown() +static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object) { - ImGuiImplOpenGL2DestroyDeviceObjects(); -} - -void ImGuiImplOpenGL2NewFrame() -{ - if (!g_FontTexture) - ImGuiImplOpenGL2CreateDeviceObjects(); -} - -static void ImGuiImplOpenGL2SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height) -{ - // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill. + // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); - //glDisable(GL_LIGHTING); - //glDisable(GL_COLOR_MATERIAL); glEnable(GL_SCISSOR_TEST); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnable(GL_TEXTURE_2D); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +// #ifdef GL_POLYGON_MODE +// glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +// #endif - // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), - // you may need to backup/reset/restore current shader using the lines below. DO NOT MODIFY THIS FILE! Add the code in your calling function: - // GLint last_program; - // glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); - // glUseProgram(0); - // ImGui_ImplOpenGL2_RenderDrawData(...); - // glUseProgram(last_program) + // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) + bool clip_origin_lower_left = true; +// #if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__) +// GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin); +// if (current_clip_origin == GL_UPPER_LEFT) +// clip_origin_lower_left = false; +// #endif // Setup viewport, orthographic projection matrix // Our visible imgui space lies from draw_data.DisplayPos (top left) to draw_data.DisplayPos+data_data.DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps. glViewport(0, 0, cast(GLsizei)fb_width, cast(GLsizei)fb_height); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(draw_data.DisplayPos.x, draw_data.DisplayPos.x + draw_data.DisplaySize.x, draw_data.DisplayPos.y + draw_data.DisplaySize.y, draw_data.DisplayPos.y, -1.0f, +1.0f); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); + float L = draw_data.DisplayPos.x; + float R = draw_data.DisplayPos.x + draw_data.DisplaySize.x; + float T = draw_data.DisplayPos.y; + float B = draw_data.DisplayPos.y + draw_data.DisplaySize.y; + if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left + const float[4][4] ortho_projection = + [ + [ 2.0f/(R-L), 0.0f, 0.0f, 0.0f ], + [ 0.0f, 2.0f/(T-B), 0.0f, 0.0f ], + [ 0.0f, 0.0f, -1.0f, 0.0f ], + [ (R+L)/(L-R), (T+B)/(B-T), 0.0f, 1.0f ], + ]; + glUseProgram(g_ShaderHandle); + glUniform1i(g_AttribLocationTex, 0); + glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); +// #ifdef GL_SAMPLER_BINDING +// glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise. +// #endif + +// (void)vertex_array_object; +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glBindVertexArray(vertex_array_object); +// #endif + + // Bind vertex/index buffers and setup attributes for ImDrawVert + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle); + glEnableVertexAttribArray(g_AttribLocationVtxPos); + glEnableVertexAttribArray(g_AttribLocationVtxUV); + glEnableVertexAttribArray(g_AttribLocationVtxColor); + glVertexAttribPointer(g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.pos.offsetof); + glVertexAttribPointer(g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.uv.offsetof); + glVertexAttribPointer(g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.sizeof, cast(GLvoid*)ImDrawVert.col.offsetof); } -// OpenGL2 Render function. -// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) -// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. -void ImGuiImplOpenGL2RenderDrawData(ImDrawData* draw_data) + +void ImGui_ImplOpenGL3_Shutdown() +{ + ImGui_ImplOpenGL3_DestroyDeviceObjects(); +} + +void ImGui_ImplOpenGL3_NewFrame() +{ + if (!g_ShaderHandle) + ImGui_ImplOpenGL3_CreateDeviceObjects(); +} + +bool ImGui_ImplOpenGL3_CreateDeviceObjects() +{ + // Backup GL state + GLint last_texture, last_array_buffer; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// GLint last_vertex_array; +// glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); +// #endif + + // Parse GLSL version string + import core.stdc.stdio; + int glsl_version = 130; + sscanf(g_GlslVersionString.ptr, "#version %d", &glsl_version); + + const GLchar* vertex_shader_glsl_120 = + "uniform mat4 ProjMtx;\n + attribute vec2 Position;\n + attribute vec2 UV;\n + attribute vec4 Color;\n + varying vec2 Frag_UV;\n + varying vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* vertex_shader_glsl_130 = + "uniform mat4 ProjMtx;\n + in vec2 Position;\n + in vec2 UV;\n + in vec4 Color;\n + out vec2 Frag_UV;\n + out vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* vertex_shader_glsl_300_es = + "precision mediump float;\n + layout (location = 0) in vec2 Position;\n + layout (location = 1) in vec2 UV;\n + layout (location = 2) in vec4 Color;\n + uniform mat4 ProjMtx;\n + out vec2 Frag_UV;\n + out vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* vertex_shader_glsl_410_core = + "layout (location = 0) in vec2 Position;\n + layout (location = 1) in vec2 UV;\n + layout (location = 2) in vec4 Color;\n + uniform mat4 ProjMtx;\n + out vec2 Frag_UV;\n + out vec4 Frag_Color;\n + void main()\n + {\n + Frag_UV = UV;\n + Frag_Color = Color;\n + gl_Position = ProjMtx * vec4(Position.xy,0,1);\n + }\n"; + + const GLchar* fragment_shader_glsl_120 = + "#ifdef GL_ES\n + precision mediump float;\n + #endif\n + uniform sampler2D Texture;\n + varying vec2 Frag_UV;\n + varying vec4 Frag_Color;\n + void main()\n + {\n + gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);\n + }\n"; + + const GLchar* fragment_shader_glsl_130 = + "uniform sampler2D Texture;\n + in vec2 Frag_UV;\n + in vec4 Frag_Color;\n + out vec4 Out_Color;\n + void main()\n + {\n + Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n + }\n"; + + const GLchar* fragment_shader_glsl_300_es = + "precision mediump float;\n + uniform sampler2D Texture;\n + in vec2 Frag_UV;\n + in vec4 Frag_Color;\n + layout (location = 0) out vec4 Out_Color;\n + void main()\n + {\n + Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n + }\n"; + + const GLchar* fragment_shader_glsl_410_core = + "in vec2 Frag_UV;\n + in vec4 Frag_Color;\n + uniform sampler2D Texture;\n + layout (location = 0) out vec4 Out_Color;\n + void main()\n + {\n + Out_Color = Frag_Color * texture(Texture, Frag_UV.st);\n + }\n"; + + // Select shaders matching our GLSL versions + const (char)* vertex_shader = null; + const (char)* fragment_shader = null; + if (glsl_version < 130) + { + vertex_shader = vertex_shader_glsl_120; + fragment_shader = fragment_shader_glsl_120; + } + else if (glsl_version >= 410) + { + vertex_shader = vertex_shader_glsl_410_core; + fragment_shader = fragment_shader_glsl_410_core; + } + else if (glsl_version == 300) + { + vertex_shader = vertex_shader_glsl_300_es; + fragment_shader = fragment_shader_glsl_300_es; + } + else + { + vertex_shader = vertex_shader_glsl_130; + fragment_shader = fragment_shader_glsl_130; + } + + // Create shaders + const (char)*[2] vertex_shader_with_version = [ g_GlslVersionString.ptr, vertex_shader ]; + g_VertHandle = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version.ptr, null); + glCompileShader(g_VertHandle); + CheckShader(g_VertHandle, "vertex shader"); + + const (char)*[2] fragment_shader_with_version = [ g_GlslVersionString.ptr, fragment_shader ]; + g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version.ptr, null); + glCompileShader(g_FragHandle); + CheckShader(g_FragHandle, "fragment shader"); + + g_ShaderHandle = glCreateProgram(); + glAttachShader(g_ShaderHandle, g_VertHandle); + glAttachShader(g_ShaderHandle, g_FragHandle); + glLinkProgram(g_ShaderHandle); + CheckProgram(g_ShaderHandle, "shader program"); + + g_AttribLocationTex = glGetUniformLocation(g_ShaderHandle, "Texture"); + g_AttribLocationProjMtx = glGetUniformLocation(g_ShaderHandle, "ProjMtx"); + g_AttribLocationVtxPos = glGetAttribLocation(g_ShaderHandle, "Position"); + g_AttribLocationVtxUV = glGetAttribLocation(g_ShaderHandle, "UV"); + g_AttribLocationVtxColor = glGetAttribLocation(g_ShaderHandle, "Color"); + + // Create buffers + glGenBuffers(1, &g_VboHandle); + glGenBuffers(1, &g_ElementsHandle); + + ImGui_ImplOpenGL3_CreateFontsTexture(); + + // Restore modified GL state + glBindTexture(GL_TEXTURE_2D, last_texture); + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glBindVertexArray(last_vertex_array); +// #endif + + return true; +} + +void ImGui_ImplOpenGL3_DestroyDeviceObjects() +{ + if (g_VboHandle) { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; } + if (g_ElementsHandle) { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; } + if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); } + if (g_ShaderHandle && g_FragHandle) { glDetachShader(g_ShaderHandle, g_FragHandle); } + if (g_VertHandle) { glDeleteShader(g_VertHandle); g_VertHandle = 0; } + if (g_FragHandle) { glDeleteShader(g_FragHandle); g_FragHandle = 0; } + if (g_ShaderHandle) { glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; } + + ImGui_ImplOpenGL3_DestroyFontsTexture(); +} + +static bool CheckShader(GLuint handle, const char* desc) +{ + GLint status = 0, log_length = 0; + glGetShaderiv(handle, GL_COMPILE_STATUS, &status); + glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length); + /*if (cast(GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile %s!\n", desc); + if (log_length > 1) + { + ImVector buf; + buf.resize(cast(int)(log_length + 1)); + glGetShaderInfoLog(handle, log_length, null, cast(GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + }*/ + return cast(GLboolean)status == GL_TRUE; +} + +// If you get an error please report on GitHub. You may try different GL context version or GLSL version. +static bool CheckProgram(GLuint handle, const char* desc) +{ + GLint status = 0, log_length = 0; + glGetProgramiv(handle, GL_LINK_STATUS, &status); + glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length); + /*if (cast(GLboolean)status == GL_FALSE) + fprintf(stderr, "ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link %s! (with GLSL '%s')\n", desc, g_GlslVersionString); + if (log_length > 1) + { + ImVector buf; + buf.resize(cast(int)(log_length + 1)); + glGetProgramInfoLog(handle, log_length, null, cast(GLchar*)buf.begin()); + fprintf(stderr, "%s\n", buf.begin()); + }*/ + return cast(GLboolean)status == GL_TRUE; +} + +bool ImGui_ImplOpenGL3_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO* io = igGetIO(); + ubyte* pixels; + int width, height, bpp; + + ImFontAtlas_GetTexDataAsRGBA32(io.Fonts,&pixels, &width, &height, &bpp); + //io.Fonts.GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. + + // Upload texture to graphics system + GLint last_texture; + glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); + glGenTextures(1, &g_FontTexture); + glBindTexture(GL_TEXTURE_2D, g_FontTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// #ifdef GL_UNPACK_ROW_LENGTH +// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); +// #endif + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + + // Store our identifier + io.Fonts.TexID = cast(ImTextureID)cast(sizediff_t)g_FontTexture; + + // Restore state + glBindTexture(GL_TEXTURE_2D, last_texture); + + return true; +} + +void ImGui_ImplOpenGL3_DestroyFontsTexture() +{ + if (g_FontTexture) + { + ImGuiIO* io = igGetIO(); + glDeleteTextures(1, &g_FontTexture); + io.Fonts.TexID = null; + g_FontTexture = 0; + } +} + +void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) int fb_width = cast(int)(draw_data.DisplaySize.x * draw_data.FramebufferScale.x); int fb_height = cast(int)(draw_data.DisplaySize.y * draw_data.FramebufferScale.y); - if (fb_width == 0 || fb_height == 0) + if (fb_width <= 0 || fb_height <= 0) return; // Backup GL state + GLenum last_active_texture; glGetIntegerv(GL_ACTIVE_TEXTURE, cast(GLint*)&last_active_texture); + glActiveTexture(GL_TEXTURE0); + GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - GLint[2] last_polygon_mode; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode.ptr); +// #ifdef GL_SAMPLER_BINDING +// GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler); +// #endif + GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// GLint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array_object); +// #endif +// #ifdef GL_POLYGON_MODE +// GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); +// #endif GLint[4] last_viewport; glGetIntegerv(GL_VIEWPORT, last_viewport.ptr); GLint[4] last_scissor_box; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box.ptr); - glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); + GLenum last_blend_src_rgb; glGetIntegerv(GL_BLEND_SRC_RGB, cast(GLint*)&last_blend_src_rgb); + GLenum last_blend_dst_rgb; glGetIntegerv(GL_BLEND_DST_RGB, cast(GLint*)&last_blend_dst_rgb); + GLenum last_blend_src_alpha; glGetIntegerv(GL_BLEND_SRC_ALPHA, cast(GLint*)&last_blend_src_alpha); + GLenum last_blend_dst_alpha; glGetIntegerv(GL_BLEND_DST_ALPHA, cast(GLint*)&last_blend_dst_alpha); + GLenum last_blend_equation_rgb; glGetIntegerv(GL_BLEND_EQUATION_RGB, cast(GLint*)&last_blend_equation_rgb); + GLenum last_blend_equation_alpha; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, cast(GLint*)&last_blend_equation_alpha); + GLboolean last_enable_blend = glIsEnabled(GL_BLEND); + GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE); + GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST); + GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST); // Setup desired GL state - ImGuiImplOpenGL2SetupRenderState(draw_data, fb_width, fb_height); + // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts) + // The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound. + GLuint vertex_array_object = 0; +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glGenVertexArrays(1, &vertex_array_object); +// #endif + ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); // Will project scissor/clipping rectangles into framebuffer space ImVec2 clip_off = draw_data.DisplayPos; // (0,0) unless using multi-viewports @@ -401,23 +775,22 @@ void ImGuiImplOpenGL2RenderDrawData(ImDrawData* draw_data) // Render command lists for (int n = 0; n < draw_data.CmdListsCount; n++) { - ImDrawList* cmd_list = draw_data.CmdLists[n]; - ImDrawVert* vtx_buffer = cmd_list.VtxBuffer.Data; - ImDrawIdx* idx_buffer = cmd_list.IdxBuffer.Data; - glVertexPointer(2, GL_FLOAT, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.pos.offsetof)); - glTexCoordPointer(2, GL_FLOAT, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.uv.offsetof)); - glColorPointer(4, GL_UNSIGNED_BYTE, ImDrawVert.sizeof, cast(const GLvoid*)(cast(const char*)vtx_buffer + ImDrawVert.col.offsetof)); + const ImDrawList* cmd_list = draw_data.CmdLists[n]; + + // Upload vertex/index buffers + glBufferData(GL_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.VtxBuffer.Size * ImDrawVert.sizeof, cast(const GLvoid*)cmd_list.VtxBuffer.Data, GL_STREAM_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, cast(GLsizeiptr)cmd_list.IdxBuffer.Size * ImDrawIdx.sizeof, cast(const GLvoid*)cmd_list.IdxBuffer.Data, GL_STREAM_DRAW); for (int cmd_i = 0; cmd_i < cmd_list.CmdBuffer.Size; cmd_i++) { const ImDrawCmd* pcmd = &cmd_list.CmdBuffer.Data[cmd_i]; - if (pcmd.UserCallback) + if (pcmd.UserCallback != null) { // User callback, registered via ImDrawList::AddCallback() // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) - /*if (pcmd.UserCallback == &ImDrawCallback_ResetRenderState) - ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height); - else*/ + // if (pcmd.UserCallback == ImDrawCallback_ResetRenderState) + // ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object); + // else pcmd.UserCallback(cmd_list, pcmd); } else @@ -435,74 +808,43 @@ void ImGuiImplOpenGL2RenderDrawData(ImDrawData* draw_data) glScissor(cast(int)clip_rect.x, cast(int)(fb_height - clip_rect.w), cast(int)(clip_rect.z - clip_rect.x), cast(int)(clip_rect.w - clip_rect.y)); // Bind texture, Draw - glBindTexture(GL_TEXTURE_2D, cast(GLuint)pcmd.TextureId); - glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + glBindTexture(GL_TEXTURE_2D, cast(GLuint)cast(sizediff_t)pcmd.TextureId); +// #if IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET +// if (g_GlVersion >= 320) +// glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd.ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd.IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd.VtxOffset); +// else +// #endif + glDrawElements(GL_TRIANGLES, cast(GLsizei)pcmd.ElemCount, ImDrawIdx.sizeof == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, cast(void*)cast(sizediff_t)(pcmd.IdxOffset * ImDrawIdx.sizeof)); } } - idx_buffer += pcmd.ElemCount; } } + // Destroy the temporary VAO +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glDeleteVertexArrays(1, &vertex_array_object); +// #endif + // Restore modified GL state - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glBindTexture(GL_TEXTURE_2D, cast(GLuint)last_texture); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); - glPolygonMode(GL_FRONT, cast(GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, cast(GLenum)last_polygon_mode[1]); + glUseProgram(last_program); + glBindTexture(GL_TEXTURE_2D, last_texture); +// #ifdef GL_SAMPLER_BINDING +// glBindSampler(0, last_sampler); +// #endif + glActiveTexture(last_active_texture); +// #ifndef IMGUI_IMPL_OPENGL_ES2 +// glBindVertexArray(last_vertex_array_object); +// #endif + glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer); + glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha); + glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha); + if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND); + if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); + if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); + if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); +// #ifdef GL_POLYGON_MODE +// glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); +// #endif glViewport(last_viewport[0], last_viewport[1], cast(GLsizei)last_viewport[2], cast(GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], cast(GLsizei)last_scissor_box[2], cast(GLsizei)last_scissor_box[3]); -} - -bool ImGuiImplOpenGL2CreateFontsTexture() -{ - // Build texture atlas - ImGuiIO* io = igGetIO(); - ubyte* pixels; - int width, height; - int bpp; - ImFontAtlas_GetTexDataAsRGBA32(io.Fonts, &pixels, &width, &height, &bpp); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. - - // Upload texture to graphics system - GLint last_texture; - glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); - glGenTextures(1, &g_FontTexture); - glBindTexture(GL_TEXTURE_2D, g_FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - - // Store our identifier - io.Fonts.TexID = cast(ImTextureID)g_FontTexture; - - // Restore state - glBindTexture(GL_TEXTURE_2D, last_texture); - - return true; -} - -void ImGuiImplOpenGL2DestroyFontsTexture() -{ - if (g_FontTexture) - { - ImGuiIO* io = igGetIO(); - glDeleteTextures(1, &g_FontTexture); - io.Fonts.TexID = null; - g_FontTexture = 0; - } -} - -bool ImGuiImplOpenGL2CreateDeviceObjects() -{ - return ImGuiImplOpenGL2CreateFontsTexture(); -} - -void ImGuiImplOpenGL2DestroyDeviceObjects() -{ - ImGuiImplOpenGL2DestroyFontsTexture(); } \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/utils.d b/demos/utils/source/ecs_utils/utils.d index 8ce5cd1..144d24f 100644 --- a/demos/utils/source/ecs_utils/utils.d +++ b/demos/utils/source/ecs_utils/utils.d @@ -58,7 +58,15 @@ version(D_BetterC) } } +version(Android) +{ + alias pthread_key_t = uint; + extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow; + extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow; + extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow; + extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow; +} version(WebAssembly) { diff --git a/meson.build b/meson.build index c31b93a..94b9c64 100644 --- a/meson.build +++ b/meson.build @@ -23,6 +23,8 @@ tests_src = [ ] betterC_opt = get_option('betterC') +BuildDemos_opt = get_option('BuildDemos') +LTO_otp = get_option('LTO') comp = meson.get_compiler('d') @@ -31,16 +33,41 @@ comp_id = comp.get_id() args = [] link_args = [] +if comp_id == 'gcc' + args += '-pthread' + link_args += '-pthread' +endif + +if LTO_otp + if comp_id == 'gcc' + args += '-flto' + link_args += '-flto' + elif comp_id == 'llvm' + args += '-flto=thin' + link_args += '-flto=thin' + else + message('LTO don\'t work with DMD') + endif +endif + if betterC_opt - args += '-betterC' - link_args += '-betterC' + if comp_id == 'gcc' + args += ['-flto','-fno-druntime'] + link_args += ['-flto','-fno-druntime'] + else + args += '-betterC' + link_args += '-betterC' + endif endif inc = include_directories('source/') tests_inc = include_directories('source/') -ecs_lib = shared_library('ecs', src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args) +ecs_lib = library('ecs', src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args) executable('tests', tests_src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args, link_with: ecs_lib) - +if BuildDemos_opt + subdir('demos/utils') + subdir('demos') +endif diff --git a/meson_options.txt b/meson_options.txt index fdf13a4..0ea2df9 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1,3 @@ -option('betterC', type: 'boolean', value: false) \ No newline at end of file +option('betterC', type: 'boolean', value: false) +option('BuildDemos', type: 'boolean', value: false) +option('LTO', type: 'boolean', value: false) \ No newline at end of file diff --git a/source/bubel/ecs/id_manager.d b/source/bubel/ecs/id_manager.d index aaeef30..db15b26 100644 --- a/source/bubel/ecs/id_manager.d +++ b/source/bubel/ecs/id_manager.d @@ -15,7 +15,7 @@ struct IDManager /************************************************************************************************************************ Get new ID. */ - pragma(inline, false) EntityID getNewID() nothrow @nogc + EntityID getNewID() nothrow @nogc { int current = m_stack_top.atomicOp!"-="(1) + 1; if (current < 0) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 0982531..19068cb 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -906,7 +906,8 @@ export struct EntityManager input_data.thread_id = cast(typeof(input_data.thread_id))threadID(); }//*/ - static foreach (iii, comp_info; components_info.req) + ///FIXME: should be "components_info.req()" but it's not compile with GCC + static foreach (iii, comp_info; components_info.m_req[0 .. components_info.m_req_counter]) { __traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember, Sys.EntitiesData, comp_info.name)))*)( @@ -914,7 +915,7 @@ export struct EntityManager .. entities_count]; } - static foreach (iii, comp_info; components_info.optional) + static foreach (iii, comp_info; components_info.m_optional[0 .. components_info.m_optional_counter]) { if (system.m_optional_components[iii] < info.deltas.length && info.deltas[system.m_optional_components[iii]] != 0) @@ -1344,9 +1345,9 @@ export struct EntityManager "Can't call function with system which hasn't EntitesData structure."); static assert(__traits(hasMember, Sys, "onUpdate"), "Can't call function with system which hasn't onUpdate function callback."); - static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate), - functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)), - "Function must match system update function."); + // static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate), + // functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)), + // "Function must match system update function."); FIXME: It's lead to crash on android build static assert(__traits(hasMember, Sys, "system_id"), "Sys must be system type."); System* system = getSystem(Sys.system_id); @@ -3105,7 +3106,7 @@ export struct EntityManager // has_work |= removeEntities(); has_work |= updateEvents(); - //id_manager.optimize(); + id_manager.optimize(); has_work |= updateBlocks(); has_work |= changeEntities(); has_work |= removeEntities(); diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d index a7dd846..cac07b2 100644 --- a/source/bubel/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -112,7 +112,7 @@ else version (D_BetterC) { private const uint max_alloca = 10000; private __gshared byte[max_alloca] alloca_array; - private uint alloca_pos = 0; + private __gshared uint alloca_pos = 0; export extern (C) void* __alloca(size_t length) @nogc nothrow { if (alloca_pos + length > max_alloca) @@ -158,7 +158,32 @@ static struct Mallocator static if (__traits(isPOD, T)) { - static immutable T init = T.init; + __gshared immutable T init = T.init; + + foreach (i; 0 .. ret.length) + { + memcpy(&ret[i], &init, T.sizeof); + } + } + else + { + static import std.conv; + + foreach (i; 0 .. ret.length) + { + std.conv.emplace(&ret[i]); + } + } + return ret; + } + + static T[] alignMakeArray(T)(size_t length, size_t alignment) nothrow @nogc + { + T[] ret = (cast(T*) alignAlloc(T.sizeof * length, alignment))[0 .. length]; + + static if (__traits(isPOD, T)) + { + __gshared immutable T init = T.init; foreach (i; 0 .. ret.length) { @@ -206,7 +231,7 @@ static struct Mallocator static if (__traits(isPOD, T)) { - static immutable T init = T.init; + __gshared immutable T init = T.init; memcpy(ret, &init, T.sizeof); } else static if (is(T == struct)) diff --git a/tests/tests.d b/tests/tests.d index d923116..9f69987 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -93,6 +93,13 @@ struct TestEvent2 float a; } +static struct CPosition +{ + mixin ECS.Component; + float x; + float y; +} + static struct TestComp { mixin ECS.Component; //__gshared ushort component_id; @@ -186,6 +193,52 @@ static struct TestComp5 } } +struct EverySystem +{ + mixin ECS.System; + + struct EntitiesData + { + uint length; + Entity[] entity; + CPosition[] pos; + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.pos[i].x++; + data.pos[i].y++; + } + } + + void iterate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.pos[i].x++; + data.pos[i].y++; + } + } + + void free(EntitiesData data) + { + foreach(i;0..data.length) + { + gEM.removeEntity(data.entity[i].id); + } + } + + void addOne(EntitiesData data) + { + foreach(i;0..data.length) + { + gEM.addComponents(data.entity[i].id, TestComp2()); + } + } +} + struct ChangeTestSystem { mixin ECS.System!16; //__gshared ushort system_id; @@ -648,6 +701,7 @@ else: gEM.registerComponent!TestComp; gEM.registerComponent!TestComp3; gEM.registerComponent!TestComp5; + gEM.registerComponent!CPosition; gEM.registerEvent!TestEvent; gEM.registerEvent!TestEvent2; @@ -669,6 +723,7 @@ else: gEM.registerSystem!EmptySystem(2); gEM.registerSystem!EmptyEventSystem(2); gEM.registerSystem!EventSystem(2); + gEM.registerSystem!EverySystem(0); //gEM.registerSystem!TestSystemWithHighPriority(100); //gEM.registerSystem!TestSystem2(0); gEM.endRegister(); @@ -693,6 +748,62 @@ else: //dur = (MonoTime.currTime - time).total!"usecs"; //writeln("Template allocating: ", dur, " usecs"); printf("Template allocating: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + + time = Time.getUSecTime(); + ushort[1] empty_ids = [CPosition.component_id]; + EntityTemplate* tmpl_empty = gEM.allocateTemplate(empty_ids); + + gEM.commit(); + + time = Time.getUSecTime(); + + foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty); + gEM.commit(); + foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty); + gEM.commit(); + foreach(i;0..2_000_000)gEM.addEntity(tmpl_empty); + gEM.commit(); + + printf("Adding 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEM.commit(); + time = Time.getUSecTime(); + gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().iterate); + printf("Iterate 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEM.begin(); + time = Time.getUSecTime(); + gEM.update(); + printf("Iterate 1M entities (update): %f usecs\n", cast(float)(Time.getUSecTime() - time)); + gEM.end(); + + time = Time.getUSecTime(); + gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().free); + gEM.commit(); + printf("Deleting 1M entities: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + time = Time.getUSecTime(); + + foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty); + gEM.commit(); + foreach(i;0..4_000_000)gEM.addEntity(tmpl_empty); + gEM.commit(); + foreach(i;0..2_000_000)gEM.addEntity(tmpl_empty); + gEM.commit(); + + printf("Adding 1M entities (prealloc): %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEM.commit(); + time = Time.getUSecTime(); + gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().addOne); + gEM.commit(); + printf("Adding 1M component: %f usecs\n", cast(float)(Time.getUSecTime() - time)); + + gEM.commit(); + gEM.callEntitiesFunction!EverySystem(&gEM.getSystem!EverySystem().free); + gEM.commit(); + time = Time.getUSecTime(); EntityID entity; From 13e6ed8fd529f62518abb1408e701da95a844693 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 6 Jun 2020 22:26:59 +0200 Subject: [PATCH 39/58] ECS core imprevement -Adedd function to resize array to Mallocator -significant speed up for first time ID allocation by using resizeArray instead of makeArray -fix: onUpdate called with zero length arrays -call updateBlocks before updateEvents (it's more accurate behaviour) -some minore fixes -fixed meson.build for GDC --- meson.build | 4 +-- source/bubel/ecs/id_manager.d | 10 ++---- source/bubel/ecs/manager.d | 61 ++++++++++++++++++++--------------- source/bubel/ecs/std.d | 44 +++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 36 deletions(-) diff --git a/meson.build b/meson.build index 94b9c64..2a71fc7 100644 --- a/meson.build +++ b/meson.build @@ -52,8 +52,8 @@ endif if betterC_opt if comp_id == 'gcc' - args += ['-flto','-fno-druntime'] - link_args += ['-flto','-fno-druntime'] + args += ['-fno-druntime'] + link_args += ['-fno-druntime'] else args += '-betterC' link_args += '-betterC' diff --git a/source/bubel/ecs/id_manager.d b/source/bubel/ecs/id_manager.d index db15b26..86a611e 100644 --- a/source/bubel/ecs/id_manager.d +++ b/source/bubel/ecs/id_manager.d @@ -177,15 +177,9 @@ struct IDManager if (m_last_id > m_ids_array.length) { uint begin = cast(uint) m_ids_array.length; - Data[] new_array = Mallocator.makeArray!Data(begin + (m_blocks_count << 16)); - memcpy(new_array.ptr, m_ids_array.ptr, m_ids_array.length * Data.sizeof); - Mallocator.dispose(m_ids_array); - m_ids_array = new_array; - uint[] new_stack = Mallocator.makeArray!uint(m_ids_array.length); - memcpy(new_stack.ptr, m_free_stack.ptr, m_free_stack.length * uint.sizeof); - Mallocator.dispose(m_free_stack); - m_free_stack = new_stack; + m_ids_array = Mallocator.resizeArray(m_ids_array, begin + (m_blocks_count << 16)); + m_free_stack = Mallocator.resizeArray(m_free_stack, m_ids_array.length); foreach (block; m_blocks[0 .. m_blocks_count - 1]) { diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 19068cb..4c543ce 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -456,7 +456,7 @@ export struct EntityManager uint writable_dep = 1; } - static ComponentsCounts getComponentsCounts()() + static ComponentsCounts getComponentsCounts() { ComponentsCounts components_counts; @@ -679,7 +679,7 @@ export struct EntityManager } - static ComponentsIndices!component_counts getComponentsInfo()() + static ComponentsIndices!component_counts getComponentsInfo() { ComponentsIndices!component_counts components_info; @@ -786,7 +786,7 @@ export struct EntityManager enum ComponentsIndices!component_counts components_info = getComponentsInfo(); - static void genCompList()(ref System system, ref HashMap!(char[], ushort) components_map) + static void genCompList(ref System system, ref HashMap!(char[], ushort) components_map) { foreach (member; __traits(allMembers, Sys.EntitiesData)) @@ -885,7 +885,7 @@ export struct EntityManager } } - static void fillInputData()(ref Sys.EntitiesData input_data, EntityInfo* info, + static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info, EntitiesBlock* block, uint offset, uint entities_count, System* system) { //enum ComponentsIndices components_info = getComponentsInfo(); @@ -907,7 +907,8 @@ export struct EntityManager }//*/ ///FIXME: should be "components_info.req()" but it's not compile with GCC - static foreach (iii, comp_info; components_info.m_req[0 .. components_info.m_req_counter]) + static foreach (iii, comp_info; components_info.m_req[0 + .. components_info.m_req_counter]) { __traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember, Sys.EntitiesData, comp_info.name)))*)( @@ -915,7 +916,8 @@ export struct EntityManager .. entities_count]; } - static foreach (iii, comp_info; components_info.m_optional[0 .. components_info.m_optional_counter]) + static foreach (iii, comp_info; components_info.m_optional[0 + .. components_info.m_optional_counter]) { if (system.m_optional_components[iii] < info.deltas.length && info.deltas[system.m_optional_components[iii]] != 0) @@ -929,7 +931,7 @@ export struct EntityManager } } - /*bool checkOnUpdateParams()() + /*bool checkOnUpdateParams() { bool ret = false; foreach (func; __traits(getOverloads, Sys, "onUpdate")) @@ -1006,26 +1008,29 @@ export struct EntityManager else entities_count = block.entities_count; - assert(entities_count <= block.entities_count - && offset <= block.entities_count); - - fillInputData(input_data, info, block, offset, entities_count, system); - - static if (hasMember!(Sys.EntitiesData, "thread_id")) + if (entities_count > 0) { - input_data.thread_id = cast(typeof(input_data.thread_id)) data - .thread_id; + assert(entities_count <= block.entities_count + && offset <= block.entities_count); + + fillInputData(input_data, info, block, offset, entities_count, system); + + static if (hasMember!(Sys.EntitiesData, "thread_id")) + { + input_data.thread_id = cast( + typeof(input_data.thread_id)) data.thread_id; + } + + static if (hasMember!(Sys.EntitiesData, "job_id")) + { + input_data.job_id = cast(typeof(input_data.job_id)) data.job_id; + } + + //s.onUpdate(input_data); + (cast(typeof(&__traits(getOverloads, s, + "onUpdate")[OnUpdateOverloadNum])) data.update_delegate)( + input_data); } - - static if (hasMember!(Sys.EntitiesData, "job_id")) - { - input_data.job_id = cast(typeof(input_data.job_id)) data.job_id; - } - - //s.onUpdate(input_data); - (cast(typeof(&__traits(getOverloads, s, - "onUpdate")[OnUpdateOverloadNum])) data.update_delegate)(input_data); - block = block.next_block; offset = 0; blocks--; @@ -1339,10 +1344,12 @@ export struct EntityManager export void callEntitiesFunction(Sys, T)(T func) { + //TODO: check if onUpdate function is good Sys* s; static assert(isDelegate!func, "Function must be delegate."); static assert(__traits(hasMember, Sys, "EntitiesData"), "Can't call function with system which hasn't EntitesData structure."); + ///TODO: make possibly to call function to group without system with onUpdate function static assert(__traits(hasMember, Sys, "onUpdate"), "Can't call function with system which hasn't onUpdate function callback."); // static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate), @@ -1353,6 +1360,8 @@ export struct EntityManager System* system = getSystem(Sys.system_id); assert(system != null, "System must be registered in EntityManager before any funcion can be called."); + if (!system.m_any_system_caller) + return; foreach (info; system.m_any_system_caller.infos) { @@ -3101,7 +3110,7 @@ export struct EntityManager swapData(); has_work = false; - // has_work |= updateBlocks(); + has_work |= updateBlocks(); // has_work |= changeEntities(); // has_work |= removeEntities(); has_work |= updateEvents(); diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d index cac07b2..38ad0d8 100644 --- a/source/bubel/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -152,6 +152,50 @@ else static struct Mallocator { + static T[] resizeArray(T)(T[] array, size_t length) nothrow @nogc + { + T[] ret; + + if(length > array.length) + { + ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; + static if (__traits(isPOD, T)) + { + __gshared immutable T init = T.init; + + foreach (i; array.length .. ret.length) + { + memcpy(&ret[i], &init, T.sizeof); + } + } + else + { + static import std.conv; + + foreach (i; array.length .. ret.length) + { + std.conv.emplace(&ret[i]); + } + } + } + else + { + static if (__traits(hasMember, T, "__xdtor")) + foreach (i; length .. array.length) + { + array[i].__xdtor(); + } + else static if (__traits(hasMember, T, "__dtor")) + foreach (i; length .. array.length) + { + array[i].__dtor(); + } + ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; + } + + return ret; + } + static T[] makeArray(T)(size_t length) nothrow @nogc { T[] ret = (cast(T*) malloc(T.sizeof * length))[0 .. length]; From e76c5ccdb2c448d3ff17ab248902ef4fa9f7d580 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 6 Jun 2020 22:46:29 +0200 Subject: [PATCH 40/58] Huge demos update -moved C stdlib function definitions to ecs_utils.utils -added function to calculate mix(linear interpolation) and rsqrt(fast inverse sqrt) -added some math to vec2 (length, normalize...) -improved renderer with possibility to use multiple materials (one per block, not perfect solution for parallel compute, but works with some requirements) -added blending support for material (opaque, additive, mixed) -added Android support -added gprahical representation for mouse tools (tool_circle.d) -added initial support for editing template components variables -better Component and Templates listing -added possibility to add/removes components using mouse -move CLocation to game_core.basic and reuse in every test -moved tools code from demos to App (now code is fully separated from demos!) -some improvement and fixes in Snake demo, with additional systems to handle adding and removing entities -added new demo: Particles. By now demo has several particles to spawn and support for attractors and vortexes (calculation is made as every attractor with every entity) -fixed bug with window hover and tools -improved tool behaviour -added new material -now window is always opened as maximized windowed mode -some minor fixes and improvements --- demos/assets/shaders/circle.fp | 64 +++ demos/assets/shaders/circle.vp | 114 ++++ demos/assets/textures/atlas.png | Bin 41948 -> 42614 bytes demos/compile_android.py | 2 +- demos/external/sources/glad/gl/loader.d | 4 +- demos/source/app.d | 306 ++++++++++- demos/source/demos/particles.d | 545 ++++++++++++++++++++ demos/source/demos/simple.d | 101 ++-- demos/source/demos/snake.d | 211 ++++---- demos/source/demos/space_invaders.d | 113 ++-- demos/source/game_core/basic.d | 14 + demos/source/gui/attributes.d | 20 + demos/source/gui/component.d | 61 ++- demos/source/gui/manager.d | 317 +++++++++++- demos/source/gui/tool_circle.d | 52 ++ demos/utils/source/ecs_utils/gfx/buffer.d | 2 +- demos/utils/source/ecs_utils/gfx/material.d | 19 + demos/utils/source/ecs_utils/gfx/renderer.d | 76 ++- demos/utils/source/ecs_utils/math/vector.d | 22 + demos/utils/source/ecs_utils/utils.d | 49 +- 20 files changed, 1804 insertions(+), 288 deletions(-) create mode 100644 demos/assets/shaders/circle.fp create mode 100644 demos/assets/shaders/circle.vp create mode 100644 demos/source/demos/particles.d create mode 100644 demos/source/game_core/basic.d create mode 100644 demos/source/gui/attributes.d create mode 100644 demos/source/gui/tool_circle.d diff --git a/demos/assets/shaders/circle.fp b/demos/assets/shaders/circle.fp new file mode 100644 index 0000000..15f46fd --- /dev/null +++ b/demos/assets/shaders/circle.fp @@ -0,0 +1,64 @@ +precision mediump int; +precision mediump float; +precision lowp sampler2D; +precision lowp samplerCube; + + +#ifdef GLES + #define TEX(x,y) texture2D(x,y) + #if __VERSION__ >290 + #define M_IN in mediump + #define L_IN in lowp + #else + #define M_IN varying mediump + #define L_IN varying lowp + #endif +#else + #define TEX(x,y) texture(x,y) + #if __VERSION__ > 320 + #define M_IN in + #define L_IN in + #else + #define M_IN varying + #define L_IN varying + #endif +#endif + +M_IN vec2 pos; +M_IN float edge; +//flat M_IN vec2 fpos; + +//M_IN vec2 uv; +//M_IN vec4 color; +/* +#ifdef GLES + #if __VERSION__ >290 + in mediump vec2 uv; + #else + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + in vec2 uv; + #else + varying vec2 uv; + #endif +#endif*/ + +//layout(binding = 0)uniform sampler2D tex; + +//uniform sampler2D tex; + +//layout(location = 0) out vec4 outColor; + +void main() +{ + float len2 = dot(pos,pos); + + if(len2 > 1.0)discard; + + if(len2 > edge)gl_FragColor = vec4(0.4,0.8,1.0,0.8);//TEX(tex,uv) * color; + else gl_FragColor = vec4(0,0.6,1.0,0.35);//TEX(tex,uv) * color; + //gl_FragColor = vec4(pos,0,1); + //if(gl_FragColor.a < 0.01)discard; +} diff --git a/demos/assets/shaders/circle.vp b/demos/assets/shaders/circle.vp new file mode 100644 index 0000000..6997121 --- /dev/null +++ b/demos/assets/shaders/circle.vp @@ -0,0 +1,114 @@ +precision highp float; +precision highp int; +precision lowp sampler2D; +precision lowp samplerCube; +#ifdef GLES + #if __VERSION__ >290 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out mediump + #define L_OUT out lowp + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying mediump + #define L_OUT varying lowp + #endif +#else + #if __VERSION__ > 320 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out + #define L_OUT out + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying + #define L_OUT varying + #endif +#endif +/* +#ifdef GLES + #if __VERSION__ >290 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out mediump vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying vec2 uv; + #endif +#endif*/ + +//#define VBO_BATCH 1 + +//M_OUT vec2 uv; +//L_OUT vec4 color; +M_OUT vec2 pos; +M_OUT float edge; +//flat M_OUT vec2 fpos; + +LOC(0) ATT vec2 positions; +//LOC(1) ATT vec2 tex_coords; + +#ifdef VBO_BATCH + LOC(2) ATT float depth; + LOC(3) ATT vec4 vcolor; +#else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + //uniform vec4 uv_transform; + //uniform vec4 vcolor; + + //float depth = matrix_2.z; +#endif + +void main() { + //#ifdef VBO_BATCH + // vec3 position = vec3(positions*4.0,1.0); + // uv = tex_coords; + //#else + //edge = mix(0.1, 0.96, (matrix_2.z / 256)); + edge = (matrix_1.w - matrix_2.z) / matrix_1.w;//matrix_2.z;//clamp((matrix_2,0.0,1.0); + edge *= edge; + pos = positions * 2.0;// / matrix_2.zw * 2; + //fpos = positions * matrix_2.xy; + vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0); + // uv = tex_coords * uv_transform.zw + uv_transform.xy; + //#endif + + //color = vcolor * 2.0; + + gl_Position = vec4(position.xy,0,1.0); + +} diff --git a/demos/assets/textures/atlas.png b/demos/assets/textures/atlas.png index a799eb7706feddc336f6f1e6e75f780dcbea5467..eea925e600dde7ea3133047620c037882fdd4b2c 100644 GIT binary patch literal 42614 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 diff --git a/demos/compile_android.py b/demos/compile_android.py index 2e3f967..75d6106 100644 --- a/demos/compile_android.py +++ b/demos/compile_android.py @@ -38,7 +38,7 @@ def compile(sources, output): clean = 0 ldc_flags = '--d-version=SDL_209 --d-version=BindSDL_Image --d-version=MM_USE_POSIX_THREADS ' #import_paths = ['source','tests'] -import_paths = ['external','external/sources', 'external/imports', 'external/wasm_imports', '../source', 'utils/source', 'simple/source'] +import_paths = ['external/android','external/sources', 'external/imports', 'external/wasm_imports', '../source', 'utils/source', 'simple/source'] build_tests = 0 for arg in sys.argv[1:]: diff --git a/demos/external/sources/glad/gl/loader.d b/demos/external/sources/glad/gl/loader.d index d640c61..8bc904f 100644 --- a/demos/external/sources/glad/gl/loader.d +++ b/demos/external/sources/glad/gl/loader.d @@ -35,14 +35,14 @@ bool open_gl() @nogc { return false; } else { version(OSX) { - enum const(char)*[] NAMES = [ + enum const(char)*[4] NAMES = [ "../Frameworks/OpenGL.framework/OpenGL", "/Library/Frameworks/OpenGL.framework/OpenGL", "/System/Library/Frameworks/OpenGL.framework/OpenGL", "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" ]; } else { - enum const(char)*[] NAMES = ["libGL.so.1", "libGL.so"]; + enum const(char)*[2] NAMES = ["libGL.so.1", "libGL.so"]; } foreach(name; NAMES) { diff --git a/demos/source/app.d b/demos/source/app.d index 003922b..808426f 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -4,10 +4,11 @@ import bindbc.sdl; import cimgui.cimgui; +import game_core.basic; import game_core.job_updater; -import bubel.ecs.manager; import bubel.ecs.core; +import bubel.ecs.manager; import bubel.ecs.std; import ecs_utils.gfx.renderer; @@ -21,6 +22,7 @@ import glad.gl.gles2; import glad.gl.loader; import gui.manager; +import gui.tool_circle; extern (C) : @@ -50,7 +52,7 @@ struct Launcher bool function() loop; void function() end; void function(SDL_Event*) event; - void function(vec2, Tool, int) tool; + //void function(vec2, Tool, int, bool) tool; float scalling; ivec2 window_size = ivec2(1024,768); Renderer renderer; @@ -65,9 +67,12 @@ struct Launcher vec2 render_position; Tool used_tool; - int tool_size = 0; + int tool_size = 100; float tool_repeat = 0; float repeat_time = 0; + bool tool_show = true; + bool tool_mode = true; + ToolCircle* tool_circle; bool swap_interval = true; @@ -93,7 +98,7 @@ struct Launcher float draw_time = 0; } - void switchDemo(void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, void function(vec2, Tool, int) tool, const (char)* tips) + void switchDemo(void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, const (char)* tips) { gui_manager.clear(); //launcher.ent @@ -117,7 +122,97 @@ struct Launcher this.end = end; this.event = event; this.tips = tips; - this.tool = tool; + //this.tool = tool; + } + + void processTool(vec2 position, bool mode) + { + static struct Iterator + { + float size2; + vec2 position; + ComponentRef[] add_comps; + ushort[] rem_comps; + + void removeEntity(IteratorSystem.EntitiesData data) + { + 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 < size2)gEM.removeEntity(data.entity[i].id); + } + } + + void addComponent(IteratorSystem.EntitiesData data) + { + 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 < size2)gEM.addComponents(data.entity[i].id, add_comps); + } + } + + void removeComponent(IteratorSystem.EntitiesData data) + { + 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 < size2)gEM.removeComponents(data.entity[i].id, rem_comps); + } + } + } + + float half_size = tool_size * 0.5; + float size2 = half_size * half_size; + Iterator iterator; + iterator.size2 = size2; + iterator.position = position; + + switch(used_tool) + { + case Tool.entity_spawner: + if(mode) + { + if(gui_manager.templates.length == 0)return; + EntityTemplate* tmpl = gui_manager.getSelectedTemplate(); + CLocation* location = tmpl.getComponent!CLocation; + if(location) + { + position += randomCircularSample() * half_size; + if(position.y < 16)position.y = 16; + else if(position.y > 299)position.y = 299; + *location = position; + } + manager.addEntity(tmpl); + } + else + { + manager.callEntitiesFunction!IteratorSystem(&iterator.removeEntity); + } + break; + case Tool.component_manipulator: + { + if(gui_manager.components.length == 0)return; + if(mode) + { + ComponentRef[1] comps = [gui_manager.getSelectedComponent()]; + iterator.add_comps = comps; + manager.callEntitiesFunction!IteratorSystem(&iterator.addComponent); + } + else + { + ushort[1] comps = [gui_manager.getSelectedComponent().component_id]; + iterator.rem_comps = comps; + manager.callEntitiesFunction!IteratorSystem(&iterator.removeComponent); + } + } + break; + default: + break; + } } bool getKeyState(SDL_Scancode key) @@ -184,6 +279,28 @@ struct CleanSystem } } +struct IteratorSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + CLocation[] location; + } + + bool onBegin() + { + return false; + } + + void onUpdate(EntitiesData) + { + + } +} + void mainLoop(void* arg) { __gshared double time = 0; @@ -237,9 +354,12 @@ void mainLoop(void* arg) case SDL_BUTTON_MIDDLE:launcher.mouse.middle = true;break; default:break; } - if(launcher.tool && event.button.button == SDL_BUTTON_LEFT && launcher.tool_repeat == 0 && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow)) + if(!igIsAnyItemHovered())igSetWindowFocus(); + if(!igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) { - launcher.tool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position, launcher.used_tool, launcher.tool_size); + launcher.repeat_time = 0; + if(event.button.button == SDL_BUTTON_LEFT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,launcher.tool_mode); + else if(event.button.button == SDL_BUTTON_RIGHT)launcher.processTool(vec2(event.button.x, launcher.window_size.y - event.button.y) * launcher.scalling - launcher.render_position,!launcher.tool_mode); } } else if(event.type == SDL_MOUSEBUTTONUP) @@ -255,17 +375,52 @@ void mainLoop(void* arg) else if(event.type == SDL_MOUSEMOTION) { launcher.mouse.position = vec2(event.motion.x, launcher.window_size.y - event.motion.y); + }else if(event.type == SDL_MOUSEWHEEL) + { + if(!igIsAnyItemHovered() && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow)) + { + if(SDL_GetModState() & KMOD_CTRL) + { + float sign = 1; + if(event.wheel.y < 0)sign = -1; + float val = sign * event.wheel.y * launcher.tool_repeat * 0.25; + if(val < 0.1)val = 0.1; + launcher.tool_repeat -= sign * val; + if(launcher.tool_repeat < 0)launcher.tool_repeat = 0; + else if(launcher.tool_repeat > 1000)launcher.tool_repeat = 1000; + } + else + { + int sign = 1; + if(event.wheel.y < 0)sign = -1; + int val = sign * event.wheel.y * launcher.tool_size / 4; + if(val < 1)val = 1; + launcher.tool_size -= sign * val; + if(launcher.tool_size < 1)launcher.tool_size = 1; + else if(launcher.tool_size > 256)launcher.tool_size = 256; + } + } } } - if(launcher.tool && launcher.tool_repeat != 0 && launcher.mouse.left && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) + if(launcher.tool_repeat != 0 && (launcher.mouse.left || launcher.mouse.right) && !igIsWindowHovered(ImGuiHoveredFlags_AnyWindow) && !igIsWindowFocused(ImGuiFocusedFlags_AnyWindow)) { + bool mode = launcher.tool_mode; + if(launcher.mouse.right)mode = !mode; float range = 500.0 / cast(float)launcher.tool_repeat; launcher.repeat_time += launcher.delta_time; - while(launcher.repeat_time > range) + if(launcher.used_tool != Tool.entity_spawner || !mode) { - launcher.repeat_time -= range; - launcher.tool((launcher.mouse.position*launcher.scalling)-launcher.render_position, launcher.used_tool, launcher.tool_size); + if(launcher.repeat_time > range)launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode); + while(launcher.repeat_time > range)launcher.repeat_time -= range; + } + else + { + while(launcher.repeat_time > range) + { + launcher.repeat_time -= range; + launcher.processTool((launcher.mouse.position*launcher.scalling)-launcher.render_position, mode); + } } } @@ -300,17 +455,22 @@ void mainLoop(void* arg) if(igMenuItemBool("Simpe",null,false,true)) { import demos.simple; - launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips); + launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); } if(igMenuItemBool("Snake",null,false,true)) { import demos.snake; - launcher.switchDemo(&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,&snakeTool,Snake.tips); + launcher.switchDemo(&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,Snake.tips); } if(igMenuItemBool("Space invaders",null,false,true)) { import demos.space_invaders; - launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips); + launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); + } + if(igMenuItemBool("Particles",null,false,true)) + { + import demos.particles; + launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); } igEndMenu(); } @@ -463,20 +623,22 @@ 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, 500), ImGuiCond_Once); + igSetNextWindowSize(ImVec2(250, launcher.window_size.y - 60), ImGuiCond_Once); if(igBegin("Demo",&launcher.show_demo_wnd,0)) { ImDrawList* draw_list = igGetWindowDrawList(); - //igBeginGroup(); + igBeginGroup(); launcher.gui_manager.gui(); - //igEndGroup(); + igEndGroup(); + ImDrawList_AddRect(draw_list, igGetItemRectMin(), ImVec2(igGetWindowPos().x+igGetWindowWidth()-2,igGetItemRectMax().y), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 4, ImDrawCornerFlags_All, 1); + //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); - if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth)) + igBeginGroup(); + if(igCollapsingHeader("Tool##ToolHeader", ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) { igIndent(8); - igBeginGroup(); if(igBeginCombo("Tool",tool_strings[launcher.used_tool],0)) { if(igSelectable("Entity spawner",false,0,ImVec2(0,0))) @@ -493,14 +655,20 @@ void mainLoop(void* arg) } igEndCombo(); } + igCheckbox("Show Tool", &launcher.tool_show); + //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); + if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; + igSameLine(0,0); + if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; igSliderInt("Tool size", &launcher.tool_size, 0, 256, null); igSliderFloat("Tool repeat", &launcher.tool_repeat, 0, 1024, null, 4); launcher.gui_manager.toolGui(); - igEndGroup(); - ImDrawList_AddRect(draw_list, igGetItemRectMin(), igGetItemRectMax(), igColorConvertFloat4ToU32(ImVec4(0.4,0.4,0.4,0.4)), 4, ImDrawCornerFlags_All, 1); 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); + //igEndChild(); //igEndChildFrame(); @@ -516,7 +684,8 @@ void mainLoop(void* arg) if(launcher.show_profile_wnd) { - igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0)); + //igSetNextWindowPos(ImVec2(launcher.window_size.x - 260, launcher.window_size.y - 280), ImGuiCond_Once, ImVec2(0,0)); + igSetNextWindowPos(ImVec2(8, launcher.window_size.y - 258), ImGuiCond_Once, ImVec2(0,0)); igSetNextWindowSize(ImVec2(250, 250), ImGuiCond_Once); if(igBegin("Profile",&launcher.show_profile_wnd,0)) { @@ -577,6 +746,10 @@ void mainLoop(void* arg) launcher.renderer.present(); draw_time = launcher.getTime() - draw_time; + //import std.stdio; + //printf("Scalling: %f",launcher.scalling); + if(launcher.tool_show)launcher.tool_circle.draw(&launcher.renderer, (launcher.mouse.position*launcher.scalling)-launcher.render_position, cast(float)launcher.tool_size, launcher.renderer.view_size.y*6*launcher.scalling); + __gshared float plot_time = 0; __gshared uint plot_samples = 0; plot_time += launcher.delta_time; @@ -703,6 +876,7 @@ int app_main(int argc, char** argv) SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); launcher.window = SDL_CreateWindow("Simple", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, launcher.window_size.x, launcher.window_size.y, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); + SDL_MaximizeWindow(launcher.window); launcher.gl_context = SDL_GL_CreateContext(launcher.window); launcher.context = igCreateContext(null); @@ -778,8 +952,11 @@ int app_main(int argc, char** argv) launcher.manager.registerPass("clean"); + launcher.manager.registerComponent!CLocation; + launcher.manager.registerSystem!CountSystem(10000); launcher.manager.registerSystem!CleanSystem(0,"clean"); + launcher.manager.registerSystem!IteratorSystem(0,"clean"); launcher.manager.endRegister(); @@ -796,8 +973,10 @@ int app_main(int argc, char** argv) { import demos.simple; import demos.space_invaders; - // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,&spaceInvadersTool,SpaceInvaders.tips); - launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,&simpleTool,Simple.tips); + import demos.particles; + // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); + // launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); } int key_num; @@ -842,7 +1021,7 @@ void loadGFX() Texture.__loadBackend(); Renderer.__loadBackend(); - GfxConfig.materials = Mallocator.makeArray!Material(1); + GfxConfig.materials = Mallocator.makeArray!Material(3); GfxConfig.meshes = Mallocator.makeArray!Mesh(1); float[16] vertices = [-0.5,-0.5, 0,1, -0.5,0.5, 0,0, 0.5,-0.5, 1,1, 0.5,0.5, 1,0]; @@ -889,7 +1068,84 @@ void loadGFX() GfxConfig.materials[0].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); + Shader vsh2; + vsh2.create(); + vsh2.load("assets/shaders/circle.vp"); + vsh2.compile(); + + Shader fsh2; + fsh2.create(); + fsh2.load("assets/shaders/circle.fp"); + fsh2.compile(); + + GfxConfig.materials[1].create(); + GfxConfig.materials[1].data.blend_mode = Material.BlendMode.mixed; + GfxConfig.materials[1].data.mode = Material.TransformMode.position; + Material.ShaderModule[1] modules2 = [Material.ShaderModule(vsh2,fsh2)]; + GfxConfig.materials[1].attachModules(modules2); + //GfxConfig.materials[0]. + //GfxConfig.materials[0].load(load_data.materials[i].str); + GfxConfig.materials[1].compile(); + GfxConfig.materials[1].bindAttribLocation("positions",0); + //GfxConfig.materials[1].bindAttribLocation("tex_coords",1); + //GfxConfig.materials[1].bindAttribLocation("depth",2); + //GfxConfig.materials[1].bindAttribLocation("vcolor",3); + GfxConfig.materials[1].link(); + + /* import std.stdio; + writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); + writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); + writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); + writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ + + GfxConfig.materials[1].data.uniforms = Mallocator.makeArray!(Material.Uniform)(2); + GfxConfig.materials[1].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_1"), 0); + GfxConfig.materials[1].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[1].getLocation("matrix_2"), 16); + //GfxConfig.materials[1].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); + //GfxConfig.materials[1].data.bindings = Mallocator.makeArray!(int)(1); + //GfxConfig.materials[1].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); + + + + + + + GfxConfig.materials[2].create(); + GfxConfig.materials[2].data.blend_mode = Material.BlendMode.opaque; + GfxConfig.materials[2].data.mode = Material.TransformMode.position; + //Material.ShaderModule[1] modules = [Material.ShaderModule(vsh,fsh)]; + GfxConfig.materials[2].attachModules(modules); + //GfxConfig.materials[0]. + //GfxConfig.materials[0].load(load_data.materials[i].str); + GfxConfig.materials[2].compile(); + GfxConfig.materials[2].bindAttribLocation("positions",0); + GfxConfig.materials[2].bindAttribLocation("tex_coords",1); + GfxConfig.materials[2].bindAttribLocation("depth",2); + GfxConfig.materials[2].bindAttribLocation("vcolor",3); + GfxConfig.materials[2].link(); + + /* import std.stdio; + writeln("positions ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"positions")); + writeln("tex_coords ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"tex_coords")); + writeln("depth ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"depth")); + writeln("vcolor ",glGetAttribLocation(GfxConfig.materials[0].data.modules[0].gl_handle,"vcolor"));*/ + + GfxConfig.materials[2].data.uniforms = Mallocator.makeArray!(Material.Uniform)(3); + GfxConfig.materials[2].data.uniforms[0] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_1"), 0); + GfxConfig.materials[2].data.uniforms[1] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("matrix_2"), 16); + GfxConfig.materials[2].data.uniforms[2] = Material.Uniform(Material.Type.float4, GfxConfig.materials[0].getLocation("uv_transform"), 32); + GfxConfig.materials[2].data.bindings = Mallocator.makeArray!(int)(1); + GfxConfig.materials[2].data.bindings[0] = GfxConfig.materials[0].getLocation("tex"); + GfxConfig.materials[2].data.blend_mode = Material.BlendMode.additive; + + + + + + /*glUseProgram(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);*/ + + launcher.tool_circle = Mallocator.make!ToolCircle; } \ No newline at end of file diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d new file mode 100644 index 0000000..6ed8ea7 --- /dev/null +++ b/demos/source/demos/particles.d @@ -0,0 +1,545 @@ +module demos.particles; + +import app; + +import bindbc.sdl; + +import cimgui.cimgui; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; + +import gui.attributes; + +extern(C): + +private enum float px = 1.0/512.0; + +/*####################################################################################################################### +------------------------------------------------ Components ------------------------------------------------------------------ +#######################################################################################################################*/ + +/*struct CLocation +{ + mixin ECS.Component; + + alias location this; + + vec2 location; +}*/ + +struct CTexCoords +{ + mixin ECS.Component; + + vec4 value; +} + +struct CColor +{ + mixin ECS.Component; + + alias value this; + + @GUIColor uint value = uint.max; +} + +struct CVelocity +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(0); +} + +struct CForceRange +{ + mixin ECS.Component; + + vec2 range = vec2(20,200); +} + +struct CAttractor +{ + mixin ECS.Component; + + //alias value this; + float strength = 0.2; +} + +struct CVortex +{ + mixin ECS.Component; + + float strength = 0.6; +} + +struct CDamping +{ + mixin ECS.Component; + + alias power this; + + @GUIRange(0,9) ubyte power = 0; +} + +struct CGravity +{ + mixin ECS.Component; +} + +struct CParticleLife +{ + mixin ECS.Component; + + this(float life_in_secs) + { + life = cast(int)(life_in_secs * 1000_000); + } + + alias life this; + + int life = 1000000; +} + +/*####################################################################################################################### +------------------------------------------------ Systems ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct DrawSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + //uint thread_id; + uint job_id; + //@readonly CTexCoords[] coords; + @readonly CLocation[] locations; + + @optional @readonly CColor[] color; + } + + void onUpdate(EntitiesData data) + { + if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + + if(!data.color) + { + foreach(i; 0..data.length) + { + launcher.renderer.draw(particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, 0x80808080, 0, 2, 0, data.job_id); + } + } + else + { + foreach(i; 0..data.length) + { + launcher.renderer.draw(particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, data.color[i].value, 0, 2, 0, data.job_id); + } + } + + } +} + +struct MoveSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CLocation[] locations; + @readonly CVelocity[] velocity; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.locations[i] += data.velocity[i] * launcher.delta_time; + } + } +} + +struct MouseAttractSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + @readonly CLocation[] locations; + CVelocity[] velocity; + } + + vec2 mouse_pos; + + bool onBegin() + { + if(!launcher.getKeyState(SDL_SCANCODE_SPACE))return false; + mouse_pos = launcher.mouse.position; + mouse_pos = vec2(mouse_pos.x, mouse_pos.y) * launcher.scalling - launcher.render_position; + return true; + } + + void onUpdate(EntitiesData data) + { + float speed = launcher.delta_time * 0.01; + foreach(i;0..data.length) + { + vec2 rel_pos = mouse_pos - data.locations[i]; + float len2 = rel_pos.x * rel_pos.x + rel_pos.y * rel_pos.y; + if(len2 < 0.1)len2 = 0.1; + data.velocity[i] = data.velocity[i] + rel_pos / len2 * speed; + } + } +} + +struct AttractSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + @readonly CLocation[] locations; + CVelocity[] velocity; + } + + struct Updater + { + AttractSystem.EntitiesData data; + + void onUpdate(AttractorIterator.EntitiesData adata) + { + float speed = launcher.delta_time * 0.00004; + if(adata.vortex) + { + foreach(i;0..data.length) + { + foreach(j;0..adata.length) + { + vec2 rel_pos = data.locations[i] - adata.locations[j]; + float len2 = rel_pos.length2(); + float inv_len = rsqrt(len2); + + if(1 < adata.force_range[j].range.y*inv_len) + { + float dist = (adata.force_range[j].range.y - 0.4)*inv_len - 1; + + vec2 vec = rel_pos * inv_len; + vec2 cvec = vec2(-vec.y,vec.x); + + float sign = -1; + if(1 < adata.force_range[j].range.x*inv_len)sign = 1; + + float str = adata.attractor[j].strength * sign; + float vortex_str = adata.vortex[j].strength; + data.velocity[i] = data.velocity[i] + (rel_pos * str + cvec * vortex_str) * speed * dist; + } + } + } + } + else + { + foreach(i;0..data.length) + { + foreach(j;0..adata.length) + { + vec2 rel_pos = data.locations[i] - adata.locations[j]; + float len2 = rel_pos.length2(); + float inv_len = rsqrt(len2); + + if(1 < adata.force_range[j].range.y*inv_len) + { + float dist = (adata.force_range[j].range.y - 0.4)*inv_len - 1; + + vec2 vec = rel_pos; + + float sign = -1; + if(1 < adata.force_range[j].range.x*inv_len)sign = 1; + + float str = adata.attractor[j].strength * speed * dist * sign; + data.velocity[i] = data.velocity[i] + vec * str; + } + } + } + } + } + } + + void onUpdate(EntitiesData data) + { + Updater updater; + updater.data = data; + launcher.manager.callEntitiesFunction!AttractorIterator(&updater.onUpdate); + } +} + +struct AttractorIterator +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + @readonly CLocation[] locations; + @readonly CAttractor[] attractor; + @readonly CForceRange[] force_range; + @optional @readonly CVortex[] vortex; + } + + bool onBegin() + { + return false; + } + + void onUpdate(EntitiesData data) + { + + } +} + +struct PlayAreaSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + Entity[] entity; + @readonly CLocation[] locations; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + if(data.locations[i].x > 400)launcher.manager.removeEntity(data.entity[i].id); + else if(data.locations[i].x < 0)launcher.manager.removeEntity(data.entity[i].id); + if(data.locations[i].y > 300)launcher.manager.removeEntity(data.entity[i].id); + else if(data.locations[i].y < 0)launcher.manager.removeEntity(data.entity[i].id); + } + } +} + +struct DampingSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + @readonly CDamping[] damping; + CVelocity[] velocity; + } + + float[10] damp = 0; + + bool onBegin() + { + foreach(i;0..10) + { + damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1); + } + + return true; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; + } + } +} + +struct ParticleLifeSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + CParticleLife[] life; + } + + int delta_time; + + bool onBegin() + { + delta_time = cast(int)(launcher.delta_time * 1000); + return true; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.life[i] -= delta_time; + if(data.life[i] < 0)launcher.manager.removeEntity(data.entity[i].id); + } + } +} + +struct GravitySystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + @readonly CGravity[] gravity; + CVelocity[] velocity; + } + + void onUpdate(EntitiesData data) + { + float delta_time = launcher.delta_time * 0.00_092; + foreach(i; 0..data.length) + { + data.velocity[i].y -= delta_time; + } + } +} + +/*####################################################################################################################### +------------------------------------------------ Functions ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct ParticlesDemo +{ + __gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window."; + + Texture texture; +} + +__gshared ParticlesDemo* particles_demo; + +void particlesStart() +{ + particles_demo = Mallocator.make!ParticlesDemo; + + particles_demo.texture.create(); + particles_demo.texture.load("assets/textures/atlas.png"); + + launcher.manager.beginRegister(); + + launcher.manager.registerComponent!CLocation; + launcher.manager.registerComponent!CTexCoords; + launcher.manager.registerComponent!CColor; + launcher.manager.registerComponent!CVelocity; + launcher.manager.registerComponent!CAttractor; + launcher.manager.registerComponent!CDamping; + launcher.manager.registerComponent!CGravity; + launcher.manager.registerComponent!CVortex; + launcher.manager.registerComponent!CParticleLife; + launcher.manager.registerComponent!CForceRange; + + launcher.manager.registerSystem!MoveSystem(0); + launcher.manager.registerSystem!DrawSystem(100); + launcher.manager.registerSystem!PlayAreaSystem(102); + launcher.manager.registerSystem!AttractSystem(-1); + launcher.manager.registerSystem!MouseAttractSystem(1); + launcher.manager.registerSystem!DampingSystem(101); + launcher.manager.registerSystem!ParticleLifeSystem(-10); + launcher.manager.registerSystem!GravitySystem(-2); + + launcher.manager.registerSystem!AttractorIterator(-1); + + launcher.manager.endRegister(); + + launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); + launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System"); + launcher.gui_manager.addSystem(PlayAreaSystem.system_id,"Play Area System"); + launcher.gui_manager.addSystem(AttractSystem.system_id,"Attract System"); + launcher.gui_manager.addSystem(MouseAttractSystem.system_id,"Mouse Attract System"); + launcher.gui_manager.addSystem(DampingSystem.system_id,"Damping System"); + launcher.gui_manager.addSystem(ParticleLifeSystem.system_id,"Particle Life System"); + + launcher.gui_manager.addComponent(CColor(),"Color (white)"); + launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)"); + launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)"); + launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)"); + launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor (str 0.1)"); + launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange (5,40)"); + launcher.gui_manager.addComponent(CVelocity(),"Velocity"); + launcher.gui_manager.addComponent(CDamping(),"Damping"); + launcher.gui_manager.addComponent(CVortex(),"Vortex"); + launcher.gui_manager.addComponent(CParticleLife(),"Particle Life"); + launcher.gui_manager.addComponent(CGravity(),"Gravity"); + + EntityTemplate* tmpl; + EntityTemplate* base_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CColor.component_id, CVelocity.component_id, CDamping.component_id].staticArray); + launcher.gui_manager.addTemplate(base_tmpl,"Particle"); + tmpl = launcher.manager.allocateTemplate(base_tmpl); + tmpl.getComponent!CColor().value = 0xFF251010; + launcher.gui_manager.addTemplate(tmpl,"Particle (blue)"); + tmpl = launcher.manager.allocateTemplate(base_tmpl); + tmpl.getComponent!CColor().value = 0xFF102010; + launcher.gui_manager.addTemplate(tmpl,"Particle (green)"); + tmpl = launcher.manager.allocateTemplate(base_tmpl); + tmpl.getComponent!CColor().value = 0xFF101540; + launcher.gui_manager.addTemplate(tmpl,"Particle (red)"); + // tmpl = launcher.manager.allocateTemplate(tmpl, [CDamping.component_id].staticArray); + // launcher.gui_manager.addTemplate(tmpl,"Particle (damping)"); + tmpl = launcher.manager.allocateTemplate(tmpl); + tmpl.getComponent!CDamping().power = 4; + launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)"); + tmpl = launcher.manager.allocateTemplate([CAttractor.component_id, CLocation.component_id, CForceRange.component_id].staticArray); + launcher.gui_manager.addTemplate(tmpl,"Attractor"); + tmpl = launcher.manager.allocateTemplate(tmpl, [CVortex.component_id].staticArray); + launcher.gui_manager.addTemplate(tmpl,"Vortex"); + tmpl = launcher.manager.allocateTemplate(tmpl); + tmpl.getComponent!CVortex().strength = -0.6; + launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)"); + +} + +void particlesEnd() +{ + particles_demo.texture.destroy(); + + //launcher.manager.freeTemplate(simple.tmpl); + Mallocator.dispose(particles_demo); +} + +void particlesEvent(SDL_Event* event) +{ +} + +bool particlesLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + launcher.manager.begin(); + if(launcher.multithreading) + { + launcher.job_updater.begin(); + launcher.manager.updateMT(); + launcher.job_updater.call(); + } + else + { + launcher.manager.update(); + } + launcher.manager.end(); + + return true; +} \ No newline at end of file diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 313cc00..ac3b3f7 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -4,46 +4,38 @@ import app; import bindbc.sdl; -import cimgui.cimgui; - import bubel.ecs.attributes; import bubel.ecs.core; import bubel.ecs.entity; import bubel.ecs.manager; import bubel.ecs.std; +import cimgui.cimgui; + import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; +import game_core.basic; + extern(C): -struct Simple -{ - __gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window."; +/*####################################################################################################################### +------------------------------------------------ Components ------------------------------------------------------------------ +#######################################################################################################################*/ - EntityTemplate* tmpl; - Texture texture; - - bool move_system = true; - bool draw_system = true; -} - -struct CLocation +/*struct CLocation { mixin ECS.Component; alias location this; vec2 location; -} +}*/ -struct CTexture -{ - mixin ECS.Component; - - Texture tex; -} +/*####################################################################################################################### +------------------------------------------------ Systems ------------------------------------------------------------------ +#######################################################################################################################*/ struct DrawSystem { @@ -54,7 +46,6 @@ struct DrawSystem uint length; //uint thread_id; uint job_id; - @readonly CTexture[] textures; @readonly CLocation[] locations; } @@ -63,7 +54,7 @@ struct DrawSystem if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached foreach(i; 0..data.length) { - launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y), 0x80808080, 0, 0, 0, data.job_id); + launcher.renderer.draw(simple.texture, data.locations[i], vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y), 0x80808080, 0, 0, 0, data.job_id); // launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0x80808080, 0, 0, 0, data.job_id); //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); } @@ -85,12 +76,24 @@ struct MoveSystem { foreach(i; 0..data.length) { - data.locations[i].location.y = data.locations[i].location.y + 1; - if(data.locations[i].location.y > 300)data.locations[i].location.y = 0; + data.locations[i].y = data.locations[i].y + 1; + if(data.locations[i].y > 300)data.locations[i].y = 0; } } } +/*####################################################################################################################### +------------------------------------------------ Functions ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct Simple +{ + __gshared const (char)* tips = "Use \"space\" to spwan entities.\n\nSystems can be enabled/disabled from \"Simple\" window."; + + EntityTemplate* tmpl; + Texture texture; +} + __gshared Simple* simple; void simpleStart() @@ -103,7 +106,6 @@ void simpleStart() launcher.manager.beginRegister(); launcher.manager.registerComponent!CLocation; - launcher.manager.registerComponent!CTexture; launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(1); @@ -113,19 +115,17 @@ void simpleStart() launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System"); - ushort[2] components = [CLocation.component_id, CTexture.component_id]; + ushort[1] components = [CLocation.component_id]; simple.tmpl = launcher.manager.allocateTemplate(components); - CTexture* tex_comp = simple.tmpl.getComponent!CTexture; - tex_comp.tex = simple.texture; - CLocation* loc_comp = simple.tmpl.getComponent!CLocation; + //CLocation* loc_comp = simple.tmpl.getComponent!CLocation; launcher.gui_manager.addTemplate(simple.tmpl, "Basic"); foreach(i; 0..10) foreach(j; 0..10) { - loc_comp.location = vec2(i*16+64,j*16+64); - launcher.manager.addEntity(simple.tmpl); + //loc_comp.value = vec2(i*16+64,j*16+64); + launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(i*16+64,j*16+64)).ref_].staticArray); } } @@ -140,46 +140,15 @@ void simpleEnd() Mallocator.dispose(simple); } -void simpleTool(vec2 position, Tool tool, int size) -{ - switch(tool) - { - case Tool.entity_spawner: - { - EntityTemplate* tmpl = launcher.gui_manager.getSelectedTemplate(); - CLocation* location = tmpl.getComponent!CLocation; - if(location) - { - position.x += (randomf - 0.5) * size; - position.y += (randomf - 0.5) * size; - if(position.x > 400)position.x -= 400; - else if(position.x < 0)position.x += 400; - if(position.y > 300)position.y -= 300; - else if(position.y < 0)position.y += 300; - *location = position; - } - launcher.manager.addEntity(tmpl); - } - break; - default: - break; - } -} - void simpleEvent(SDL_Event* event) { - /*if(event.type == event.button) - { - vec2 position = vec2(event.button.x, event.button.y); - - }*/ } void spawnEntity() { - CLocation* loc_comp = simple.tmpl.getComponent!CLocation; - loc_comp.location = vec2(randomf() * 400,0); - launcher.manager.addEntity(simple.tmpl); + //CLocation* loc_comp = simple.tmpl.getComponent!CLocation; + //loc_comp.value = vec2(randomf() * 400,0); + launcher.manager.addEntity(simple.tmpl,[CLocation(vec2(randomf() * 400,0)).ref_].staticArray); } bool simpleLoop() @@ -188,7 +157,7 @@ bool simpleLoop() if(launcher.getKeyState(SDL_SCANCODE_SPACE)) { - foreach(i;0..1)spawnEntity(); + foreach(i;0..20)spawnEntity(); } launcher.manager.begin(); diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 01e9a36..f46009c 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -4,8 +4,6 @@ import app; import bindbc.sdl; -import cimgui.cimgui; - import bubel.ecs.attributes; import bubel.ecs.core; import bubel.ecs.entity; @@ -13,10 +11,14 @@ import bubel.ecs.manager; import bubel.ecs.std; import bubel.ecs.vector; +import cimgui.cimgui; + import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; +import game_core.basic; + //import std.array : staticArray; enum float px = 1.0/512.0; @@ -31,22 +33,6 @@ struct MapElement apple = 1, wall = 2, snake = 3, - - /* snake_head_up = 5, - snake_head_down = 6, - snake_head_left = 7, - snake_head_right = 8, - snake_tail_up = 9, - snake_tail_down = 10, - snake_tail_left = 11, - snake_tail_right = 12, - snake_turn_ld = 13, - snake_turn_lu = 14, - snake_turn_rd = 15, - snake_turn_ru = 16, - snake_vertical = 17, - snake_horizontal = 18*/ - } Type type; EntityID id; @@ -129,10 +115,7 @@ struct Snake } if(base_pos.x == random_pos.x && base_pos.y == random_pos.y)return; } - //CILocation* location = apple_tmpl.getComponent!CILocation; - //*location = random_pos; - //Entity* apple = - launcher.manager.addEntity(apple_tmpl,[CILocation(random_pos).ref_].staticArray); + launcher.manager.addEntity(apple_tmpl,[CLocation(cast(vec2)(random_pos)*16).ref_].staticArray); } } @@ -158,14 +141,14 @@ struct CILocation ivec2 location; } -struct CLocation -{ - mixin ECS.Component; +// struct CLocation +// { +// mixin ECS.Component; - alias location this; +// alias location this; - vec2 location = vec2(0,0); -} +// vec2 location = vec2(0,0); +// } struct CSnake { @@ -264,8 +247,8 @@ struct AppleSystem struct EntitiesData { uint length; - @readonly Entity[] entities; - @readonly CApple[] movement; + @readonly Entity[] entity; + @readonly CApple[] apple; @readonly CILocation[] location; } @@ -273,7 +256,17 @@ struct AppleSystem { foreach(i;0..data.length) { - snake.element(MapElement(MapElement.Type.apple,data.entities[i].id),data.location[i]); + if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.apple,data.entity[i].id),data.location[i]); + else launcher.manager.removeEntity(data.entity[i].id); + } + } + + void onRemoveEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + if(snake.element(data.location[i].location).id == data.entity[i].id) + snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location); } } } @@ -315,7 +308,7 @@ struct ParticleMovementSystem { foreach(i;0..data.length) { - data.location[i].location -= data.movement[i].velocity; + data.location[i] -= data.movement[i].velocity; } } } @@ -357,7 +350,7 @@ struct AnimationRenderSystem { foreach(i;0..data.length) { - launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i].location, vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080); + launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i], vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080); } } } @@ -477,7 +470,12 @@ struct MoveSystem break; case MapElement.Type.apple: launcher.manager.removeEntity(snake.element(data.location[i].location).id); - if(data.snakes[i].parts.length < 100)data.snakes[i].parts.add(new_location); + if(data.snakes[i].parts.length >= 99) + { + snake.addApple(); + goto case(MapElement.Type.empty); + } + data.snakes[i].parts.add(new_location); if(data.snakes[i].parts.length > 1) { @@ -506,7 +504,40 @@ struct MoveSystem } } } - + } +} + +struct SnakeSystem +{ + mixin ECS.System!1; + + struct EntitiesData + { + uint length; + Entity[] entity; + @readonly CSnake[] snake; + @readonly CILocation[] location; + } + + void onAddSystem(EntitiesData data) + { + foreach(i;0..data.length) + { + if(snake.element(data.location[i]).id == EntityID())snake.element(MapElement(MapElement.Type.snake,data.entity[i].id),data.location[i]); + else launcher.manager.removeEntity(data.entity[i].id); + } + } + + void onRemoveEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + if(snake.element(data.location[i].location).id == data.entity[i].id) + snake.element(MapElement(MapElement.Type.empty, EntityID()),data.location[i].location); + foreach(part; data.snake[i].parts.array) + if(snake.element(part).id == data.entity[i].id) + snake.element(MapElement(MapElement.Type.empty, EntityID()),part); + } } } @@ -750,6 +781,35 @@ struct CleanSystem } } +struct CopyLocationSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + CLocation[] location; + @readonly CILocation[] ilocation; + } + + void onAddEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + data.ilocation[i] = cast(ivec2)(data.location[i] / 16); + } + } + + void onUpdate(EntitiesData data) + { + foreach(i;0..data.length) + { + data.location[i] = cast(vec2)(data.ilocation[i] * 16); + } + } +} + __gshared Snake* snake; void snakeStart() @@ -776,7 +836,6 @@ void snakeStart() launcher.manager.registerSystem!MoveSystem(0,"fixed"); launcher.manager.registerSystem!InputSystem(-100); launcher.manager.registerSystem!FixSnakeDirectionSystem(-1,"fixed"); - launcher.manager.registerSystem!AppleSystem(-1,"fixed"); launcher.manager.registerSystem!AnimationRenderSystem(100); launcher.manager.registerSystem!AnimationSystem(-1); launcher.manager.registerSystem!ParticleSystem(-1); @@ -784,8 +843,20 @@ void snakeStart() launcher.manager.registerSystem!DrawAppleSystem(99); launcher.manager.registerSystem!DrawSnakeSystem(101); + launcher.manager.registerSystem!CopyLocationSystem(100); + //launcher.manager.registerSystem!AppleRemoveSystem(100); + launcher.manager.registerSystem!AppleSystem(101); + launcher.manager.registerSystem!SnakeSystem(101); + launcher.manager.endRegister(); + launcher.gui_manager.addComponent(CApple(),"Apple"); + launcher.gui_manager.addComponent(CSnake(),"Snake"); + launcher.gui_manager.addComponent(CParticle(1000),"Particle (1s)"); + launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector (UP)"); + launcher.gui_manager.addComponent(CInput(),"Input"); + launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement (UP)"); + launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); launcher.gui_manager.addSystem(InputSystem.system_id,"Input System"); launcher.gui_manager.addSystem(FixSnakeDirectionSystem.system_id,"Fix Direction System"); @@ -797,15 +868,13 @@ void snakeStart() snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray); { - ushort[4] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id]; + ushort[5] components = [CILocation.component_id, CSnake.component_id, CMovement.component_id, CInput.component_id, CLocation.component_id]; snake.snake_tmpl = launcher.manager.allocateTemplate(components); - //CILocation* loc_comp = snake.snake_tmpl.getComponent!CILocation; - //*loc_comp = ivec2(2,2); launcher.manager.addEntity(snake.snake_tmpl,[CILocation(ivec2(2,2)).ref_].staticArray); } { - snake.snake_destroy_particle = launcher.manager.allocateTemplate([CLocation.component_id, CParticle.component_id, CParticleVector.component_id, CAnimation.component_id].staticArray); + snake.snake_destroy_particle = launcher.manager.allocateTemplate([CLocation.component_id, CParticle.component_id, CParticleVector.component_id, CAnimation.component_id, CLocation.component_id].staticArray); CAnimation* canim = snake.snake_destroy_particle.getComponent!CAnimation; canim.frames = snake.snake_destroy_particle_frames; CParticle* particle = snake.snake_destroy_particle.getComponent!CParticle; @@ -813,7 +882,7 @@ void snakeStart() } { - ushort[2] components = [CILocation.component_id, CApple.component_id]; + ushort[3] components = [CILocation.component_id, CApple.component_id, CLocation.component_id]; snake.apple_tmpl = launcher.manager.allocateTemplate(components); snake.addApple(); } @@ -824,13 +893,6 @@ void snakeStart() MoveSystem* move_system = launcher.manager.getSystem!MoveSystem(); move_system.setTemplates(); - - /*foreach(i; 0..10) - foreach(j; 0..10) - { - loc_compation = vec2(i*32+64,j*32+64); - launcher.manager.addEntity(simple.tmpl); - }*/ } void snakeEnd() @@ -839,39 +901,6 @@ void snakeEnd() Mallocator.dispose(snake); } -void snakeTool(vec2 position, Tool tool, int size) -{ - switch(tool) - { - case Tool.entity_spawner: - { - EntityTemplate* tmpl = launcher.gui_manager.getSelectedTemplate(); - CLocation* location = tmpl.getComponent!CLocation; - if(location) - { - position.x += (randomf() - 0.5) * size; - position.y += (randomf() - 0.5) * size; - *location = position; - } - CILocation* ilocation = tmpl.getComponent!CILocation; - if(ilocation) - { - position.x += (randomf() - 0.5) * size; - position.y += (randomf() - 0.5) * size; - ivec2 ipos; - ipos.x = cast(int)(position.x / 16); - ipos.y = cast(int)(position.y / 16); - *ilocation = ipos; - if(snake.element(ipos).type != MapElement.Type.empty)return; - } - launcher.manager.addEntity(tmpl); - } - break; - default: - break; - } -} - void snakeEvent(SDL_Event* event) { @@ -881,16 +910,16 @@ bool snakeLoop() { launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(288,288)) * 0.5; - /*if(launcher.show_demo_wnd) - { - igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0)); - igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once); - if(igBegin("Snake",&launcher.show_demo_wnd,0)) - { + // if(launcher.show_demo_wnd) + // { + // igSetNextWindowPos(ImVec2(800 - 260, 30), ImGuiCond_Once, ImVec2(0,0)); + // igSetNextWindowSize(ImVec2(250, 0), ImGuiCond_Once); + // if(igBegin("Snake",&launcher.show_demo_wnd,0)) + // { - } - igEnd(); - }*/ + // } + // igEnd(); + // } launcher.manager.begin(); @@ -912,7 +941,5 @@ bool snakeLoop() launcher.manager.end(); - //snake.drawMap(); - return true; } \ No newline at end of file diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 45dd06d..ce2cd6a 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -4,25 +4,26 @@ import app; import bindbc.sdl; -import cimgui.cimgui; - import bubel.ecs.attributes; import bubel.ecs.core; import bubel.ecs.entity; import bubel.ecs.manager; import bubel.ecs.std; +import cimgui.cimgui; + import ecs_utils.gfx.texture; import ecs_utils.math.vector; import ecs_utils.utils; +import game_core.basic; + //import std.math : PI; -enum PI = 3.141592653589793238462643383279502884197169399375105820; //import std.array : staticArray; -enum float px = 1.0/512.0; +private enum float px = 1.0/512.0; extern(C): @@ -114,14 +115,14 @@ enum Direction : byte ------------------------------------------------ Components ------------------------------------------------------------------ #######################################################################################################################*/ -struct CLocation +/*struct CLocation { mixin ECS.Component; alias value this; vec2 value = vec2(0); -} +}*/ struct CScale { @@ -273,7 +274,7 @@ struct CTargetParent mixin ECS.Component; EntityID parent; - vec2 rel_pos; + vec2 rel_pos = vec2(0,0); } @@ -699,7 +700,7 @@ struct ShipWeaponSystem Entity[] entity; CInit[] init; //CShip[] ship; - //CChildren[] children; + CChildren[] children; } struct Ship @@ -1062,7 +1063,7 @@ struct CollisionSystem } } -struct LaserShootingSystem +struct ShootingSystem { mixin ECS.System!32; @@ -1187,7 +1188,7 @@ struct LaserShootingSystem else fire_velocity.value = vec2(0,0); fire_location.value = data.location[i]; - if(data.shoot_direction[i].direction == Direction.down) + if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down) { fire_rotation.value = PI; //fire_location.value.y -= 16; @@ -1270,7 +1271,7 @@ struct DampingSystem } } -struct LaserCollisionSystem +struct BulletsCollisionSystem { mixin ECS.System!32; @@ -1423,9 +1424,12 @@ struct UpgradeSystem if(ship) { CChildren* children = entity.getComponent!CChildren; - foreach(child;children.childern) + if(children) { - launcher.manager.sendEvent(child,EUpgrade()); + foreach(child;children.childern) + { + launcher.manager.sendEvent(child,EUpgrade()); + } } } } @@ -1742,7 +1746,7 @@ struct ShootWaveSystem CLocation* location = entity.getComponent!CLocation; CGuild* guild = entity.getComponent!CGuild; - //LaserShootingSystem.bullet_tmpl + //ShootingSystem.bullet_tmpl EntityTemplate* tmpl = space_invaders.bullet_tmpl[wave.bullet_type]; foreach(dir;dirs) { @@ -2180,12 +2184,6 @@ struct CShipIterator //void handleEvent(Entity* entity, ) }//*/ -extern(C) float sqrtf(float x) @nogc nothrow @system; -extern(C) float acosf(float x) @nogc nothrow @system; -extern(C) float sinf(float x) @nogc nothrow @system; -extern(C) float cosf(float x) @nogc nothrow @system; -extern(C) float powf(float x, float y) @nogc nothrow @system; - /** *System is responsible for movement of objects with CInput component. *In this example every entity has same speed when using movement system. @@ -2348,9 +2346,9 @@ void spaceInvadersStart() launcher.manager.registerSystem!InputMovementSystem(-100); launcher.manager.registerSystem!MovementSystem(-99); launcher.manager.registerSystem!ClampPositionSystem(-90); - launcher.manager.registerSystem!LaserShootingSystem(0); + launcher.manager.registerSystem!ShootingSystem(0); launcher.manager.registerSystem!ChangeDirectionSystem(0); - launcher.manager.registerSystem!LaserCollisionSystem(-70); + launcher.manager.registerSystem!BulletsCollisionSystem(-70); launcher.manager.registerSystem!ShootGridManager(-80); launcher.manager.registerSystem!ShootGridCleaner(-101); launcher.manager.registerSystem!HitPointsSystem(0); @@ -2374,13 +2372,49 @@ void spaceInvadersStart() launcher.manager.endRegister(); + launcher.gui_manager.addComponent(CInput(),"Input"); + launcher.gui_manager.addComponent(CShip(),"Ship"); + launcher.gui_manager.addComponent(CEnemy(),"Enemy"); + launcher.gui_manager.addComponent(CAutoShoot(),"Auto Shoot"); + launcher.gui_manager.addComponent(CWeapon(0, CWeapon.Type.laser),"Weapon (laser)"); + launcher.gui_manager.addComponent(CVelocity(vec2(0,0)),"Velocity (0,0)"); + launcher.gui_manager.addComponent(CBullet(),"Bullet (dmg1)"); + launcher.gui_manager.addComponent(CSideMove(),"Side Move"); + launcher.gui_manager.addComponent(CSideMove(0),"Side Move (g1)"); + launcher.gui_manager.addComponent(CSideMove(1),"Side Move (g2)"); + launcher.gui_manager.addComponent(CShootGrid(),"Shoot Grid"); + launcher.gui_manager.addComponent(CGuild(),"Guild (Player)"); + launcher.gui_manager.addComponent(CGuild(1),"Guild (Enemy)"); + launcher.gui_manager.addComponent(CHitPoints(10),"Hit Points (10)"); + launcher.gui_manager.addComponent(CHitMark(),"Hit Mark"); + launcher.gui_manager.addComponent(CUpgrade(CUpgrade.Upgrade.laser),"Upgrade (laser)"); + launcher.gui_manager.addComponent(CParticle(1000),"Particle (1s)"); + //launcher.gui_manager.addComponent(CMaxHitPoints(),"Max Hit Points"); + launcher.gui_manager.addComponent(CDamping(0),"Damping (0)"); + launcher.gui_manager.addComponent(CDamping(4),"Damping (4)"); + launcher.gui_manager.addComponent(CDamping(8),"Damping (8)"); + launcher.gui_manager.addComponent(CTargetParent(),"Target Parent"); + launcher.gui_manager.addComponent(CTargetPlayerShip(),"Target Player Ship"); + launcher.gui_manager.addComponent(CTarget(),"Target"); + launcher.gui_manager.addComponent(CChildren(),"Children"); + launcher.gui_manager.addComponent(CWeaponLocation(vec2(0,16)),"Weapon Location (0,16)"); + launcher.gui_manager.addComponent(CInit(CInit.Type.space_ship),"Init (Ship)"); + launcher.gui_manager.addComponent(CInit(CInit.Type.boss),"Init (Boss)"); + launcher.gui_manager.addComponent(CInit(CInit.Type.tower),"Init (Tower)"); + launcher.gui_manager.addComponent(CBoss(),"Boss"); + launcher.gui_manager.addComponent(CColliderScale(),"Collider Scale"); + launcher.gui_manager.addComponent(CParticleEmitter(),"Particle Emitter"); + launcher.gui_manager.addComponent(CParticleEmitterTime(),"Particle Emitter Time"); + //launcher.gui_manager.addComponent(CSpawnUponDeath(),"Spawn Upon Death"); + launcher.gui_manager.addComponent(CShootWaveUponDeath(CWeapon.Type.canon),"Wave Upon Death"); + launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System"); launcher.gui_manager.addSystem(InputMovementSystem.system_id,"Input Movement"); - launcher.gui_manager.addSystem(LaserShootingSystem.system_id,"Laser Shooting"); + launcher.gui_manager.addSystem(ShootingSystem.system_id,"Shooting System"); launcher.gui_manager.addSystem(MovementSystem.system_id,"Movement System"); launcher.gui_manager.addSystem(ClampPositionSystem.system_id,"Clamp Position System"); launcher.gui_manager.addSystem(ChangeDirectionSystem.system_id,"Change Direction System"); - launcher.gui_manager.addSystem(LaserCollisionSystem.system_id,"Laser Collision System"); + launcher.gui_manager.addSystem(BulletsCollisionSystem.system_id,"Bullets Collision System"); launcher.gui_manager.addSystem(ShootGridManager.system_id,"Shoot Grid Manager"); launcher.gui_manager.addSystem(ShootGridCleaner.system_id,"Shoot Grid Cleaner"); launcher.gui_manager.addSystem(HitPointsSystem.system_id,"Hit Points System"); @@ -2560,7 +2594,7 @@ void spaceInvadersEnd() { /*launcher.manager.getSystem(DrawSystem.system_id).disable(); launcher.manager.getSystem(InputMovementSystem.system_id).disable(); - launcher.manager.getSystem(LaserShootingSystem.system_id).disable(); + launcher.manager.getSystem(ShootingSystem.system_id).disable(); launcher.manager.getSystem(MovementSystem.system_id).disable(); launcher.manager.getSystem(ClampPositionSystem.system_id).disable(); launcher.manager.getSystem(ShootGridCleaner.system_id).disable();*/ @@ -2570,35 +2604,6 @@ void spaceInvadersEnd() space_invaders = null; } -void spaceInvadersTool(vec2 position, Tool tool, int size) -{ - switch(tool) - { - case Tool.entity_spawner: - { - EntityTemplate* tmpl = launcher.gui_manager.getSelectedTemplate(); - CLocation* location = tmpl.getComponent!CLocation; - if(location) - { - position.x += (randomf - 0.5) * size; - position.y += (randomf - 0.5) * size; - if(position.y < 16)position.y = 16; - else if(position.y > 299)position.y = 299; - *location = position; - } - CWeapon* laser_weapon = tmpl.getComponent!CWeapon; - if(laser_weapon) - { - laser_weapon.shoot_time = randomf * CWeapon.levels[laser_weapon.level - 1].reload_time; - } - launcher.manager.addEntity(tmpl); - } - break; - default: - break; - } -} - void spaceInvadersEvent(SDL_Event* event) { diff --git a/demos/source/game_core/basic.d b/demos/source/game_core/basic.d new file mode 100644 index 0000000..993a5aa --- /dev/null +++ b/demos/source/game_core/basic.d @@ -0,0 +1,14 @@ +module game_core.basic; + +import bubel.ecs.core; + +import ecs_utils.math.vector; + +struct CLocation +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(0); +} \ No newline at end of file diff --git a/demos/source/gui/attributes.d b/demos/source/gui/attributes.d new file mode 100644 index 0000000..53605c2 --- /dev/null +++ b/demos/source/gui/attributes.d @@ -0,0 +1,20 @@ +module gui.attributes; + +enum GUIColor = "GUIColor"; + +struct GUIRange +{ + union + { + struct + { + int min; + int max; + } + struct + { + float minf; + float maxf; + } + } +} \ No newline at end of file diff --git a/demos/source/gui/component.d b/demos/source/gui/component.d index bbd7ec5..b19f069 100644 --- a/demos/source/gui/component.d +++ b/demos/source/gui/component.d @@ -1,6 +1,61 @@ -module gui.components; +module gui.component; + +import ecs_utils.utils; struct ComponentGUI { - -} \ No newline at end of file + const (char)* name; + void* data; + ushort component_id; +} + +struct ComponentEditGUI +{ + const (char)* name; + VariableGUI[] variables; + uint used; +} + +struct VariableGUI +{ + struct Int + { + int min; + int max; + } + + struct Float + { + float min; + float max; + } + + struct Enum + { + const (char)[][] strings; + } + + enum Type + { + byte_, + ubyte_, + short_, + ushort_, + int_, + uint_, + float_, + enum_, + color, + vec2, + ivec2 + } + Type type; + const (char)* name; + ushort offset; + union + { + Int int_; + Float float_; + Enum enum_; + } +} diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index 4d452ad..b7c8678 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -4,22 +4,32 @@ import app; import cimgui.cimgui; +import bubel.ecs.entity; +import bubel.ecs.manager; import bubel.ecs.std; import bubel.ecs.system; import bubel.ecs.vector; -import bubel.ecs.entity; +import ecs_utils.math.vector; + +import gui.attributes; +import gui.component; import gui.system; import gui.template_; +import std.traits; + extern(C): struct GUIManager { Vector!SystemGUI systems; + Vector!ComponentGUI components; Vector!TemplateGUI templates; + Vector!ComponentEditGUI edit_components; uint selected_tempalte = 0; + uint selected_component = 0; void clear() { @@ -27,10 +37,22 @@ struct GUIManager { launcher.manager.freeTemplate(tmpl.tmpl); } + foreach(comp; components) + { + free(comp.data); + } + foreach(ref comp; edit_components) + { + if(comp.variables)Mallocator.dispose(comp.variables); + comp.variables = null; + comp.used = 0; + } systems.clear(); templates.clear(); + components.clear(); selected_tempalte = 0; + selected_component = 0; } EntityTemplate* getSelectedTemplate() @@ -39,6 +61,12 @@ struct GUIManager else return null; } + ComponentRef getSelectedComponent() + { + if(components.length > selected_component)return ComponentRef(components[selected_component].data, components[selected_component].component_id); + else return ComponentRef(null, ushort.max); + } + void addSystem(ushort id, const (char)* name, bool enabled = true) { System* system = launcher.manager.getSystem(id); @@ -56,9 +84,112 @@ struct GUIManager templates.add(TemplateGUI(name, tmpl)); } + // void addComponent(ComponentRef comp, const (char)* name) + // { + // uint size = EntityManager.instance.components[comp.component_id].size; + // void* data = malloc(size); + // memcpy(data, comp.ptr, size); + // components.add(ComponentGUI(name, data, comp.component_id)); + // } + + void addComponent(T)(T comp, const (char)* name) + { + static assert(hasStaticMember!(T,"component_id")); + uint size = EntityManager.instance.components[comp.component_id].size; + void* data = malloc(size); + memcpy(data, &comp, size); + components.add(ComponentGUI(name, data, comp.component_id)); + + if(edit_components.length <= comp.component_id) + { + edit_components.length = comp.component_id+1;//.extend(comp.component_id + 1); + } + //edit_components[comp.component_id] = ComponentEditGUI(name); + ComponentEditGUI comp_edit; + comp_edit.name = T.stringof; + //enum fields = __traits(allMembers, T); + alias fields = FieldNameTuple!T; + //pragma(msg,fields); + comp_edit.variables = Mallocator.makeArray!VariableGUI(fields.length); + foreach(member_str; fields) + { + alias member = __traits(getMember, T, member_str); + alias member_type = typeof(member); + //pragma(msg,member); + //pragma(msg,member_type); + //pragma(msg,__traits(getMember, T, member).offsetof); + ushort offset = member.offsetof;//cast(ushort)__traits(getMember, T, member).offsetof; + static if(__traits(isIntegral,member_type)) + { + static if(__traits(isUnsigned, member_type)) + { + static if(hasUDA!(member,GUIColor)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.color,member_str,offset); + } + else switch(member_type.sizeof) + { + case 1: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ubyte_,member_str,offset);break; + case 2: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ushort_,member_str,offset);break; + case 4: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.uint_,member_str,offset);break; + default:break; + } + static if(hasUDA!(member,GUIRange)) + { + comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min; + comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[0].max; + } + else + { + comp_edit.variables[comp_edit.used-1].int_.min = 0; + comp_edit.variables[comp_edit.used-1].int_.max = int.max; + } + } + else + { + switch(member_type.sizeof) + { + case 1: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.byte_,member_str,offset);break; + case 2: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.short_,member_str,offset);break; + case 4: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.int_,member_str,offset);break; + default:break; + } + static if(hasUDA!(member,GUIRange)) + { + comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min; + comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[1].max; + } + { + comp_edit.variables[comp_edit.used-1].int_.min = int.min; + comp_edit.variables[comp_edit.used-1].int_.max = int.max; + } + } + } + else static if(__traits(isScalar,member_type)) + { + switch(member_type.sizeof) + { + case 4:comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.float_,member_str,offset);break; + case 8: + default:break; + } + static if(hasUDA!(member,GUIRange)) + { + comp_edit.variables[comp_edit.used-1].float_.min = getUDAs!(member,GUIRange)[0].minf; + comp_edit.variables[comp_edit.used-1].float_.max = getUDAs!(member,GUIRange)[1].maxf; + } + { + comp_edit.variables[comp_edit.used-1].float_.min = -float.max; + comp_edit.variables[comp_edit.used-1].float_.max = float.max; + } + } + } + edit_components[comp.component_id] = comp_edit; + } + void gui() { - if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_FramePadding)) + if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_DefaultOpen)) { bool true_ = true; igIndent(8); @@ -74,25 +205,177 @@ struct GUIManager } } - void toolGui() + static vec4 colorUintToVec4(uint color) { - if(templates.length) + // color = *cast(uint*)(comp_ptr+var.offset); + return vec4(cast(float)(color & 0xFF) / 255, + cast(float)(color >> 8 & 0xFF) / 255, + cast(float)(color >> 16 & 0xFF) / 255, + cast(float)(color >> 24 & 0xFF) / 255); + } + + static uint colorVec4ToUint(vec4 color) + { + return cast(uint)(color.x * 255) | + cast(uint)(color.y * 255) << 8 | + cast(uint)(color.z * 255) << 16 | + cast(uint)(color.w * 255) << 24; + } + + static bool igDragScalarClamp(const(char)* label, ImGuiDataType data_type, void* v, float v_speed, const(void)* v_min, const(void)* v_max, const(char)* format, float power) + { + ubyte[8] v_backup;// = *v; + final switch(data_type) { - if(igBeginCombo("Template",templates[selected_tempalte].name,0)) - { - foreach(i, tmpl; templates) - { - if(igSelectable(tmpl.name,false,0,ImVec2(0,0))) - { - selected_tempalte = cast(uint)i; - } - } - igEndCombo(); - } + case ImGuiDataType_S8:memcpy(v_backup.ptr, v, 1);break; + case ImGuiDataType_S16:memcpy(v_backup.ptr, v, 2);break; + case ImGuiDataType_S32:memcpy(v_backup.ptr, v, 4);break; + case ImGuiDataType_U8:memcpy(v_backup.ptr, v, 1);break; + case ImGuiDataType_U16:memcpy(v_backup.ptr, v, 2);break; + case ImGuiDataType_U32:memcpy(v_backup.ptr, v, 4);break; + case ImGuiDataType_Float:memcpy(v_backup.ptr, v, 4);break; } - else + if (!igDragScalar(label, data_type, v, v_speed, v_min, v_max, format, power)) + return false; + + final switch(data_type) { - if(igBeginCombo("Template",null,0))igEndCombo(); + case ImGuiDataType_S8: + if(*cast(byte*)v < *cast(byte*)v_min)*cast(byte*)v = *cast(byte*)v_min; + else if(*cast(byte*)v > *cast(byte*)v_max)*cast(byte*)v = *cast(byte*)v_max; + return *cast(byte*)v != *cast(byte*)v_backup.ptr; + case ImGuiDataType_S16: + if(*cast(short*)v < *cast(short*)v_min)*cast(short*)v = *cast(short*)v_min; + else if(*cast(short*)v > *cast(short*)v_max)*cast(short*)v = *cast(short*)v_max; + return *cast(short*)v != *cast(short*)v_backup.ptr; + case ImGuiDataType_S32: + if(*cast(int*)v < *cast(int*)v_min)*cast(int*)v = *cast(int*)v_min; + else if(*cast(int*)v > *cast(int*)v_max)*cast(int*)v = *cast(int*)v_max; + return *cast(int*)v != *cast(int*)v_backup.ptr; + case ImGuiDataType_U8: + if(*cast(ubyte*)v < *cast(ubyte*)v_min)*cast(ubyte*)v = *cast(ubyte*)v_min; + else if(*cast(ubyte*)v > *cast(ubyte*)v_max)*cast(ubyte*)v = *cast(ubyte*)v_max; + return *cast(ubyte*)v != *cast(ubyte*)v_backup.ptr; + case ImGuiDataType_U16: + if(*cast(ushort*)v < *cast(ushort*)v_min)*cast(ushort*)v = *cast(ushort*)v_min; + else if(*cast(ushort*)v > *cast(ushort*)v_max)*cast(ushort*)v = *cast(ushort*)v_max; + return *cast(ushort*)v != *cast(ushort*)v_backup.ptr; + case ImGuiDataType_U32: + if(*cast(uint*)v < *cast(uint*)v_min)*cast(uint*)v = *cast(uint*)v_min; + else if(*cast(uint*)v > *cast(uint*)v_max)*cast(uint*)v = *cast(uint*)v_max; + return *cast(uint*)v != *cast(uint*)v_backup.ptr; + case ImGuiDataType_Float: + if(*cast(float*)v < *cast(float*)v_min)*cast(float*)v = *cast(float*)v_min; + else if(*cast(float*)v > *cast(float*)v_max)*cast(float*)v = *cast(float*)v_max; + return *cast(float*)v != *cast(float*)v_backup.ptr; } } + + void entityComponentsGUI() + { + EntityTemplate* tmpl = templates[selected_tempalte].tmpl; + EntityManager.EntityInfo* info = tmpl.info; + void* data_ptr = tmpl.entity_data.ptr; + vec4 color; + foreach(comp_id; info.components) + { + if(comp_id >= edit_components.length)break; + void* comp_ptr = data_ptr + info.tmpl_deltas[comp_id]; + if(edit_components[comp_id].used) + { + if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) + { + igIndent(8); + foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used]) + { + switch(var.type) + { + case VariableGUI.Type.byte_: + igDragScalarClamp(var.name, ImGuiDataType_S8, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ubyte_: + igDragScalarClamp(var.name, ImGuiDataType_U8, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.short_: + igDragScalarClamp(var.name, ImGuiDataType_S16, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ushort_: + igDragScalarClamp(var.name, ImGuiDataType_U16, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.int_: + igDragScalarClamp(var.name, ImGuiDataType_S32, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.uint_: + igDragScalarClamp(var.name, ImGuiDataType_U32, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.float_: + igDragScalarClamp(var.name, ImGuiDataType_Float, comp_ptr+var.offset, 1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, null, 1); + break; + case VariableGUI.Type.color: + color = colorUintToVec4(*cast(uint*)(comp_ptr+var.offset)); + if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None)) + *cast(uint*)(comp_ptr+var.offset) = colorVec4ToUint(color); + break; + default:break; + } + } + igUnindent(8); + } + } + } + } + + void toolGui() + { + ImGuiStyle * style = igGetStyle(); + ImVec4 col = style.Colors[ImGuiCol_Header]; + style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg]; + //style. + //ImDrawList* draw_list = igGetWindowDrawList(); + final switch(launcher.used_tool) + { + case Tool.entity_spawner: + if(templates.length) + { + { + if(igListBoxHeaderInt("Template",cast(int)templates.length,cast(int)templates.length)) + { + foreach(i, tmpl; templates) + { + if(igSelectable(tmpl.name,selected_tempalte == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0))) + { + selected_tempalte = cast(uint)i; + } + } + igListBoxFooter(); + } + } + } + style.Colors[ImGuiCol_Header] = col; + entityComponentsGUI(); + break; + case Tool.component_manipulator: + if(components.length) + { + if(igListBoxHeaderInt("Components",cast(int)components.length,cast(int)components.length)) + { + { + foreach(i, comp; components) + { + if(igSelectable(comp.name,selected_component == i,0,ImVec2(0,0))) + { + selected_component = cast(uint)i; + } + } + igListBoxFooter(); + } + } + } + break; + case Tool.selector: + break; + } + + style.Colors[ImGuiCol_Header] = col; + } } \ No newline at end of file diff --git a/demos/source/gui/tool_circle.d b/demos/source/gui/tool_circle.d new file mode 100644 index 0000000..c43ade3 --- /dev/null +++ b/demos/source/gui/tool_circle.d @@ -0,0 +1,52 @@ +module gui.tool_circle; + +import ecs_utils.gfx.buffer; +import ecs_utils.gfx.shader; +import ecs_utils.gfx.config; +import ecs_utils.gfx.renderer; + +import ecs_utils.math.vector; + +version(WebAssembly)import glad.gl.gles2; +else version(Android)import glad.gl.gles2; +else import glad.gl.gl; + +struct ToolCircle +{ + //Buffer vbo; + //Buffer ibo; + + uint material_id = 1; + uint mesh_id = 0; + + /*/void generate() + { + ushort[] + }*/ + + void draw(Renderer* renderer, vec2 position, float size, float edge = 1) + { + position = position * renderer.view_size + renderer.view_pos; + vec2 sizes = renderer.view_size * size; + vec2 sizes2 = vec2(edge,0); + + import core.stdc.string; + ubyte[32] uniform_block; + void* ptr = uniform_block.ptr; + *cast(float*)(ptr) = sizes.x; + *cast(float*)(ptr+4) = 0; + *cast(float*)(ptr+8) = 0; + *cast(float*)(ptr+12) = sizes.y; + memcpy(ptr+16,position.data.ptr,8); + memcpy(ptr+24,sizes2.data.ptr,8); + glEnableVertexAttribArray(0); + + GfxConfig.meshes[mesh_id].bind(); + GfxConfig.materials[material_id].bind(); + GfxConfig.materials[material_id].pushBindings(); + GfxConfig.materials[material_id].pushUniforms(uniform_block.ptr); + //glDisable(GL_DEPTH_TEST); + + glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_SHORT,null); + } +} \ No newline at end of file diff --git a/demos/utils/source/ecs_utils/gfx/buffer.d b/demos/utils/source/ecs_utils/gfx/buffer.d index bfdad62..76cab50 100644 --- a/demos/utils/source/ecs_utils/gfx/buffer.d +++ b/demos/utils/source/ecs_utils/gfx/buffer.d @@ -68,7 +68,7 @@ struct Buffer void map(BindTarget target) nothrow { bind(target); - version(Android){}else data.map_ptr = glMapBuffer(target,GL_WRITE_ONLY); + version(Android){}else version(WebAssembly){}else data.map_ptr = glMapBuffer(target,GL_WRITE_ONLY); } void map(uint offset, uint size, BindTarget target, uint flags = MapFlagBits.write | MapFlagBits.flush_explict | MapFlagBits.invalidate_buffer) nothrow diff --git a/demos/utils/source/ecs_utils/gfx/material.d b/demos/utils/source/ecs_utils/gfx/material.d index 1bde9c8..0fca5fb 100644 --- a/demos/utils/source/ecs_utils/gfx/material.d +++ b/demos/utils/source/ecs_utils/gfx/material.d @@ -78,6 +78,25 @@ struct Material void bind() nothrow { + final switch(data.blend_mode) + { + case BlendMode.mixed: + glDepthMask(0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case BlendMode.opaque: + glDepthMask(1); + glDisable(GL_BLEND); + break; + case BlendMode.additive: + glDepthMask(0); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + //glBlendFunc(GL_ONE, GL_ONE); + break; + } + glUseProgram(data.modules[0].gl_handle); } diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index 93d009e..4e34b54 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -67,8 +67,10 @@ struct Renderer enum max_items = batch_size;//963; byte[] batch_vertices; ushort[] batch_indices; - void* memory; + void* memory = null; uint items = 0; + uint material_id; + uint texture_id; } Mutex* get_block_mutex; @@ -128,11 +130,11 @@ struct Renderer block_stack_mutex.unlock();*/ foreach(ref Thread thread; threads) { - foreach(VertexBlock block; thread.blocks) + foreach(VertexBlock block; thread.filled_blocks) { allocator.freeBlock(block.memory); } - thread.blocks.clear(); + thread.filled_blocks.clear(); } render_blocks = 0; current_block = 0; @@ -144,13 +146,13 @@ struct Renderer { foreach(ref Thread thread; threads) { - foreach(VertexBlock block; thread.blocks) + foreach(VertexBlock block; thread.filled_blocks) { uint items = block.items; if(items + item_id >= MaxObjects)items = MaxObjects - item_id; batch_vbo[0].bufferSubData(Buffer.BindTarget.array,items*4*14,item_id*4*14,block.batch_vertices.ptr); batch_ibo[0].bufferSubData(Buffer.BindTarget.element_array,items*2*6,item_id*2*6,block.batch_indices.ptr); - draw_list.add(DrawCall(item_id,items)); + draw_list.add(DrawCall(block.texture_id,block.material_id,item_id,items)); item_id += items; } //thread.blocks.clear(); @@ -173,8 +175,15 @@ struct Renderer foreach(i, ref Thread thread; threads) { //pushBlock(thread.block); - thread.blocks.add(thread.block); - thread.block = getBlock(); + foreach(ref block; thread.blocks) + { + if(block.items > 0) + { + thread.filled_blocks.add(block); + block.items = 0; + } + } + //thread.blocks = getBlock(); } } @@ -182,8 +191,8 @@ struct Renderer { //Vector!VertexBlock block; RenderData[] render_list; - VertexBlock block; - Vector!VertexBlock blocks; + VertexBlock[] blocks; + Vector!VertexBlock filled_blocks; } Thread[] threads; @@ -225,6 +234,8 @@ struct Renderer struct DrawCall { + uint texture_id; + uint material_id; uint start; uint count; } @@ -249,6 +260,7 @@ struct Renderer void initialize() { + import ecs_utils.gfx.config; //this.technique = __ecs_used_technique; __initialize(this); @@ -261,7 +273,8 @@ struct Renderer threads = Mallocator.makeArray!Thread(32); foreach(ref Thread thread;threads) { - thread.block = getBlock(); + //thread.blocks = getBlock(); + thread.blocks = Mallocator.makeArray!VertexBlock(GfxConfig.materials.length); } } @@ -494,12 +507,33 @@ struct Renderer private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0) { import ecs_utils.gfx.config; - short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)]; + //import core.stdc.string; with(this_) { //if(item_id >= MaxObjects)return; //pos += view_pos; + Thread* thread = &threads[thread_id]; + VertexBlock* block; + assert(thread.blocks.length > material_id); + block = &thread.blocks[material_id]; + if(block.items == 0) + { + thread.blocks[material_id] = getBlock(); + block = &thread.blocks[material_id]; + block.material_id = material_id; + } + else if(block.items >= VertexBlock.max_items) + { + //pushBlock(thread.block); + prepared_items += block.items; + thread.filled_blocks.add(*block); + thread.blocks[material_id] = getBlock(); + block = &thread.blocks[material_id]; + block.material_id = material_id; + } + + short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)]; pos.x = pos.x * view_size.x + view_pos.x; pos.y = pos.y * view_size.y + view_pos.y;//*/ @@ -513,8 +547,8 @@ struct Renderer memcpy(ptr+16,pos.data.ptr,8); memcpy(ptr+32,coords.data.ptr,16);*/ - short[] verts = cast(short[])threads[thread_id].block.batch_vertices; - uint item_id = threads[thread_id].block.items; + short[] verts = cast(short[])block.batch_vertices; + uint item_id = block.items; if(angle == 0) { @@ -619,7 +653,7 @@ struct Renderer uint ind_id = (item_id % batch_size)*4; - ushort[] indices = threads[thread_id].block.batch_indices; + ushort[] indices = block.batch_indices; indices[item_id*6] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[0] + ind_id); indices[item_id*6+1] = cast(ushort)(GfxConfig.meshes[mesh_id].indices[1] + ind_id); @@ -634,14 +668,7 @@ struct Renderer //render_list[item_id].mesh_id = mesh_id; //data_index += 1;//data_offset; - threads[thread_id].block.items++; - if(threads[thread_id].block.items >= VertexBlock.max_items) - { - //pushBlock(threads[thread_id].block); - prepared_items += threads[thread_id].block.items; - threads[thread_id].blocks.add(threads[thread_id].block); - threads[thread_id].block = getBlock(); - } + block.items++; } } @@ -659,6 +686,7 @@ struct Renderer { glClearColor(0,0,0,0); glViewport(0,0,this_.resolution.x,this_.resolution.y); + glDepthMask(1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glDisable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST); @@ -828,9 +856,9 @@ struct Renderer //uint items = item_id/batch_size+1; foreach(i; 0..draw_list.length) { - if(material_id != render_list[i].material_id) + if(material_id != draw_list[i].material_id) { - material_id = render_list[i].material_id; + material_id = draw_list[i].material_id; GfxConfig.materials[material_id].bind(); float[3*4] data = [1,0,0,1,0,0,0,0,0,0,1,1]; GfxConfig.materials[material_id].pushUniforms(data.ptr); diff --git a/demos/utils/source/ecs_utils/math/vector.d b/demos/utils/source/ecs_utils/math/vector.d index a8f14f8..adb3a36 100644 --- a/demos/utils/source/ecs_utils/math/vector.d +++ b/demos/utils/source/ecs_utils/math/vector.d @@ -1,5 +1,7 @@ module ecs_utils.math.vector; +import ecs_utils.utils; + struct vec2 { this(float v) @nogc nothrow @@ -71,6 +73,26 @@ struct vec2 } else static assert(0, "Operator "~op~" not implemented"); } + + float length2() + { + return x*x + y*y; + } + + float length() + { + return sqrtf(length2); + } + + float fastSqrLength() + { + return rsqrt(length2); + } + + vec2 normalize() + { + return this * fastSqrLength(); + } } struct vec4 diff --git a/demos/utils/source/ecs_utils/utils.d b/demos/utils/source/ecs_utils/utils.d index 144d24f..da5453f 100644 --- a/demos/utils/source/ecs_utils/utils.d +++ b/demos/utils/source/ecs_utils/utils.d @@ -2,13 +2,24 @@ module ecs_utils.utils; extern(C): -int randomRange(int min, int max) +import ecs_utils.math.vector; + +enum PI = 3.141592653589793238462643383279502884197169399375105820; + +extern(C) float sqrtf(float x) @nogc nothrow @system; +extern(C) float acosf(float x) @nogc nothrow @system; +extern(C) float sinf(float x) @nogc nothrow @system; +extern(C) float cosf(float x) @nogc nothrow @system; +extern(C) float powf(float x, float y) @nogc nothrow @system; +extern(C) float fabs(float x) @nogc nothrow @system; + +int randomRange(int min, int max) nothrow @nogc @trusted { int range = max - min; return rand() % range - min; } -float randomf() +float randomf() nothrow @nogc @trusted { const float scale = 1.0 / 32_767.0; return cast(float)(rand() & 0x007FFF) * scale; @@ -21,6 +32,38 @@ float randomRangef(float min, float max) return rand()%4096; }*/ +float mix(float x, float y, float a) +{ + //return x*a + y*(a-1); + //return x*a + y*a - y; + return x*(a+y) - y; +} + +float rsqrt(float number) +{ + long i; + float x2, y; + const float threehalfs = 1.5F; + + x2 = number * 0.5F; + y = number; + i = * cast( long * ) &y; // evil floating point bit level hacking + i = 0x5f3759df - ( i >> 1 ); // what the fuck? + y = * cast( float * ) &i; + y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration + + return y; +} + +vec2 randomCircularSample() nothrow @nogc @trusted +{ + float angle = 2 * PI * randomf; + float radius = sqrtf(randomf); + float s = sinf(angle); + float c = cosf(angle); + return vec2(c,s)*radius; +} + version(GNU) { public import core.stdc.stdio : printf; @@ -34,7 +77,7 @@ else extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; public import std.array : staticArray; } -extern(C) int rand(); +extern(C) int rand() nothrow @nogc @trusted; version(D_BetterC) { From 5018464a410fc2ea4c8c90d2c0a02d603b3736ef Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 10 Jun 2020 14:13:01 +0200 Subject: [PATCH 41/58] Demo GUI fixes and improvements plus some shortcuts -added option to override components (by remove them before adding) -added shortcuts for tools -fixed mouse scroll on WASM -addding entity filtering option (WIP) -added some tooltips -remove Components duplicates in ComponentManipulator menu -fixed ImGUI controls IDs -added possibility to change values of component to add --- demos/source/app.d | 124 +++++++++++++++++++------ demos/source/demos/particles.d | 44 ++++----- demos/source/demos/snake.d | 10 ++- demos/source/gui/manager.d | 159 ++++++++++++++++++++++----------- 4 files changed, 237 insertions(+), 100 deletions(-) diff --git a/demos/source/app.d b/demos/source/app.d index 808426f..d526f97 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -71,6 +71,7 @@ struct Launcher float tool_repeat = 0; float repeat_time = 0; bool tool_show = true; + bool override_ = true; bool tool_mode = true; ToolCircle* tool_circle; @@ -154,6 +155,20 @@ struct Launcher } } + void overrideComponent(IteratorSystem.EntitiesData data) + { + 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 < size2) + { + gEM.removeComponents(data.entity[i].id, rem_comps); + gEM.addComponents(data.entity[i].id, add_comps); + } + } + } + void removeComponent(IteratorSystem.EntitiesData data) { foreach(i;0..data.length) @@ -200,7 +215,13 @@ struct Launcher { ComponentRef[1] comps = [gui_manager.getSelectedComponent()]; iterator.add_comps = comps; - manager.callEntitiesFunction!IteratorSystem(&iterator.addComponent); + if(launcher.override_) + { + ushort[1] rcomps = [gui_manager.getSelectedComponent().component_id]; + iterator.rem_comps = rcomps; + manager.callEntitiesFunction!IteratorSystem(&iterator.overrideComponent); + } + else manager.callEntitiesFunction!IteratorSystem(&iterator.addComponent); } else { @@ -330,6 +351,33 @@ void mainLoop(void* arg) *cast(bool*)arg = false; return; } + else if(event.type == SDL_KEYDOWN) + { + if(event.key.state) + { + if(SDL_GetModState() & KMOD_CTRL) + { + switch(event.key.keysym.scancode) + { + case SDL_SCANCODE_1:launcher.used_tool=Tool.entity_spawner;break; + case SDL_SCANCODE_2:launcher.used_tool=Tool.component_manipulator;break; + case SDL_SCANCODE_3:launcher.used_tool=Tool.selector;break; + default:break; + } + } + else + { + switch(event.key.keysym.scancode) + { + case SDL_SCANCODE_1:break; + case SDL_SCANCODE_2:break; + case SDL_SCANCODE_3:break; + case SDL_SCANCODE_4:break; + default:break; + } + } + } + } else if(event.type == SDL_WINDOWEVENT) { switch(event.window.event) @@ -383,17 +431,32 @@ void mainLoop(void* arg) { float sign = 1; if(event.wheel.y < 0)sign = -1; - float val = sign * event.wheel.y * launcher.tool_repeat * 0.25; + float val = /*sign * event.wheel.y */ launcher.tool_repeat * 0.25; if(val < 0.1)val = 0.1; launcher.tool_repeat -= sign * val; if(launcher.tool_repeat < 0)launcher.tool_repeat = 0; else if(launcher.tool_repeat > 1000)launcher.tool_repeat = 1000; } + else if(SDL_GetModState() & KMOD_SHIFT) + { + int sign = 1; + if(event.wheel.y < 0)sign = -1; + switch(launcher.used_tool) + { + case Tool.entity_spawner: + launcher.gui_manager.selectTemplate(launcher.gui_manager.selected_template-sign); + break; + case Tool.component_manipulator: + launcher.gui_manager.selectComponent(launcher.gui_manager.selected_component-sign); + break; + default:break; + } + } else { int sign = 1; if(event.wheel.y < 0)sign = -1; - int val = sign * event.wheel.y * launcher.tool_size / 4; + int val = /*sign * event.wheel.y */ launcher.tool_size / 4; if(val < 1)val = 1; launcher.tool_size -= sign * val; if(launcher.tool_size < 1)launcher.tool_size = 1; @@ -503,22 +566,11 @@ void mainLoop(void* arg) } if(igBeginMenu("Show",true)) { - if(igMenuItemBool("Statistics",null,launcher.show_stat_wnd,true)) - { - launcher.show_stat_wnd = !launcher.show_stat_wnd; - } - else if(igMenuItemBool("Demo",null,launcher.show_demo_wnd,true)) - { - launcher.show_demo_wnd = !launcher.show_demo_wnd; - } - else if(igMenuItemBool("Tips",null,launcher.show_tips,true)) - { - launcher.show_tips = !launcher.show_tips; - } - else if(igMenuItemBool("Virual keys",null,launcher.show_virtual_keys_wnd,true)) - { - launcher.show_virtual_keys_wnd = !launcher.show_virtual_keys_wnd; - } + igMenuItemBoolPtr("Statistics",null,&launcher.show_stat_wnd,true); + igMenuItemBoolPtr("Demo",null,&launcher.show_demo_wnd,true); + igMenuItemBoolPtr("Tips",null,&launcher.show_tips,true); + igMenuItemBoolPtr("Virual keys",null,&launcher.show_virtual_keys_wnd,true); + igMenuItemBoolPtr("Profile",null,&launcher.show_profile_wnd,true); igEndMenu(); } if(igBeginMenu("Style",true)) @@ -655,12 +707,25 @@ void mainLoop(void* arg) } igEndCombo(); } + if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); igCheckbox("Show Tool", &launcher.tool_show); + if(igIsItemHovered(0))igSetTooltip("Show/hide graphical tool representation"); + if(launcher.used_tool == Tool.component_manipulator) + { + igSameLine(0,4); + igCheckbox("Override", &launcher.override_); + } //igSelectable("Selectabe",false,ImGuiSelectableFlags_None,ImVec2(0,0)); - if(igRadioButtonBool("Add", launcher.tool_mode))launcher.tool_mode = true; - igSameLine(0,0); - if(igRadioButtonBool("Remove", !launcher.tool_mode))launcher.tool_mode = false; + 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); launcher.gui_manager.toolGui(); @@ -668,7 +733,16 @@ void mainLoop(void* arg) } 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(); + if(igCollapsingHeader("Filter", ImGuiTreeNodeFlags_SpanAvailWidth)) + { + igIndent(8); + launcher.gui_manager.filterGUI(); + 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); //igEndChild(); //igEndChildFrame(); @@ -975,8 +1049,8 @@ int app_main(int argc, char** argv) import demos.space_invaders; import demos.particles; // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); - // launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); - launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); + launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); } int key_num; diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d index 6ed8ea7..b58b775 100644 --- a/demos/source/demos/particles.d +++ b/demos/source/demos/particles.d @@ -473,12 +473,13 @@ void particlesStart() launcher.gui_manager.addSystem(DampingSystem.system_id,"Damping System"); launcher.gui_manager.addSystem(ParticleLifeSystem.system_id,"Particle Life System"); - launcher.gui_manager.addComponent(CColor(),"Color (white)"); - launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)"); - launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)"); - launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)"); - launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor (str 0.1)"); - launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange (5,40)"); + // launcher.gui_manager.addComponent(CColor(),"Color (white)"); + // launcher.gui_manager.addComponent(CColor(0xFF101540),"Color (red)"); + // launcher.gui_manager.addComponent(CColor(0xFF251010),"Color (blue)"); + // launcher.gui_manager.addComponent(CColor(0xFF102010),"Color (green)"); + launcher.gui_manager.addComponent(CColor(0xFF101540),"Color"); + launcher.gui_manager.addComponent(CAttractor(0.1),"Attractor"); + launcher.gui_manager.addComponent(CForceRange(vec2(5,40)),"ForceRange"); launcher.gui_manager.addComponent(CVelocity(),"Velocity"); launcher.gui_manager.addComponent(CDamping(),"Damping"); launcher.gui_manager.addComponent(CVortex(),"Vortex"); @@ -487,28 +488,29 @@ void particlesStart() EntityTemplate* tmpl; EntityTemplate* base_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CColor.component_id, CVelocity.component_id, CDamping.component_id].staticArray); + base_tmpl.getComponent!CColor().value = 0xFF251010; launcher.gui_manager.addTemplate(base_tmpl,"Particle"); - tmpl = launcher.manager.allocateTemplate(base_tmpl); - tmpl.getComponent!CColor().value = 0xFF251010; - launcher.gui_manager.addTemplate(tmpl,"Particle (blue)"); - tmpl = launcher.manager.allocateTemplate(base_tmpl); - tmpl.getComponent!CColor().value = 0xFF102010; - launcher.gui_manager.addTemplate(tmpl,"Particle (green)"); - tmpl = launcher.manager.allocateTemplate(base_tmpl); - tmpl.getComponent!CColor().value = 0xFF101540; - launcher.gui_manager.addTemplate(tmpl,"Particle (red)"); + // tmpl = launcher.manager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF251010; + // launcher.gui_manager.addTemplate(tmpl,"Particle (blue)"); + // tmpl = launcher.manager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF102010; + // launcher.gui_manager.addTemplate(tmpl,"Particle (green)"); + // tmpl = launcher.manager.allocateTemplate(base_tmpl); + // tmpl.getComponent!CColor().value = 0xFF101540; + // launcher.gui_manager.addTemplate(tmpl,"Particle (red)"); // tmpl = launcher.manager.allocateTemplate(tmpl, [CDamping.component_id].staticArray); // launcher.gui_manager.addTemplate(tmpl,"Particle (damping)"); - tmpl = launcher.manager.allocateTemplate(tmpl); - tmpl.getComponent!CDamping().power = 4; - launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)"); + // tmpl = launcher.manager.allocateTemplate(tmpl); + // tmpl.getComponent!CDamping().power = 4; + // launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)"); tmpl = launcher.manager.allocateTemplate([CAttractor.component_id, CLocation.component_id, CForceRange.component_id].staticArray); launcher.gui_manager.addTemplate(tmpl,"Attractor"); tmpl = launcher.manager.allocateTemplate(tmpl, [CVortex.component_id].staticArray); launcher.gui_manager.addTemplate(tmpl,"Vortex"); - tmpl = launcher.manager.allocateTemplate(tmpl); - tmpl.getComponent!CVortex().strength = -0.6; - launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)"); + // tmpl = launcher.manager.allocateTemplate(tmpl); + // tmpl.getComponent!CVortex().strength = -0.6; + // launcher.gui_manager.addTemplate(tmpl,"Vortex (reversed)"); } diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index f46009c..579bc54 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -852,10 +852,12 @@ void snakeStart() launcher.gui_manager.addComponent(CApple(),"Apple"); launcher.gui_manager.addComponent(CSnake(),"Snake"); - launcher.gui_manager.addComponent(CParticle(1000),"Particle (1s)"); - launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector (UP)"); + launcher.gui_manager.addComponent(CParticle(1000),"Particle"); + launcher.gui_manager.addComponent(CParticleVector(vec2(0,1)),"Particle Vector"); launcher.gui_manager.addComponent(CInput(),"Input"); - launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement (UP)"); + launcher.gui_manager.addComponent(CMovement(CMovement.Direction.up),"Movement"); + //launcher.gui_manager.addComponent(CAnimation(),"Movement"); + launcher.gui_manager.addComponent(CILocation(),"Int Location"); launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); launcher.gui_manager.addSystem(InputSystem.system_id,"Input System"); @@ -864,6 +866,8 @@ void snakeStart() launcher.gui_manager.addSystem(AnimationSystem.system_id,"Animation System"); launcher.gui_manager.addSystem(ParticleSystem.system_id,"Particle Life System"); launcher.gui_manager.addSystem(ParticleMovementSystem.system_id,"Particle Movement System"); + launcher.gui_manager.addSystem(DrawAppleSystem.system_id,"Draw Apple System"); + launcher.gui_manager.addSystem(DrawSnakeSystem.system_id,"Draw Snake System"); snake.snake_destroy_particle_frames = Mallocator.makeArray([vec4(64,144,16,16)*px,vec4(80,144,16,16)*px,vec4(96,144,16,16)*px,vec4(112,144,16,16)*px].staticArray); diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index b7c8678..4ae9688 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -28,8 +28,24 @@ struct GUIManager Vector!TemplateGUI templates; Vector!ComponentEditGUI edit_components; - uint selected_tempalte = 0; - uint selected_component = 0; + int selected_template = 0; + int selected_component = 0; + + void selectTemplate(int id) + { + if(templates.length == 0)return; + selected_template = id; + while(selected_template < 0)selected_template += cast(int)templates.length; + while(selected_template >= templates.length)selected_template -= cast(int)templates.length; + } + + void selectComponent(int id) + { + if(components.length == 0)return; + selected_component = id; + while(selected_component < 0)selected_component += cast(int)components.length; + while(selected_component >= components.length)selected_component -= cast(int)components.length; + } void clear() { @@ -51,13 +67,13 @@ struct GUIManager systems.clear(); templates.clear(); components.clear(); - selected_tempalte = 0; + selected_template = 0; selected_component = 0; } EntityTemplate* getSelectedTemplate() { - if(templates.length > selected_tempalte)return templates[selected_tempalte].tmpl; + if(templates.length > selected_template)return templates[selected_template].tmpl; else return null; } @@ -271,57 +287,65 @@ struct GUIManager } } + void componentGUI(ushort comp_id, void* data_ptr) + { + vec4 color; + if(comp_id >= edit_components.length)return; + if(edit_components[comp_id].used) + { + if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) + { + igIndent(8); + foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used]) + { + igPushIDPtr(&var); + switch(var.type) + { + case VariableGUI.Type.byte_: + igDragScalarClamp(var.name, ImGuiDataType_S8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ubyte_: + igDragScalarClamp(var.name, ImGuiDataType_U8, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.short_: + igDragScalarClamp(var.name, ImGuiDataType_S16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.ushort_: + igDragScalarClamp(var.name, ImGuiDataType_U16, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.int_: + igDragScalarClamp(var.name, ImGuiDataType_S32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.uint_: + igDragScalarClamp(var.name, ImGuiDataType_U32, data_ptr+var.offset, 0.1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); + break; + case VariableGUI.Type.float_: + igDragScalarClamp(var.name, ImGuiDataType_Float, data_ptr+var.offset, 0.1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, "%2.2f", 1); + break; + case VariableGUI.Type.color: + color = colorUintToVec4(*cast(uint*)(data_ptr+var.offset)); + if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None)) + *cast(uint*)(data_ptr+var.offset) = colorVec4ToUint(color); + break; + default:break; + } + igPopID(); + } + //igPopID(); + igUnindent(8); + } + } + } + void entityComponentsGUI() { - EntityTemplate* tmpl = templates[selected_tempalte].tmpl; + EntityTemplate* tmpl = templates[selected_template].tmpl; EntityManager.EntityInfo* info = tmpl.info; - void* data_ptr = tmpl.entity_data.ptr; - vec4 color; foreach(comp_id; info.components) { - if(comp_id >= edit_components.length)break; + void* data_ptr = tmpl.entity_data.ptr; void* comp_ptr = data_ptr + info.tmpl_deltas[comp_id]; - if(edit_components[comp_id].used) - { - if(igCollapsingHeader(edit_components[comp_id].name, ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_DefaultOpen)) - { - igIndent(8); - foreach(ref VariableGUI var;edit_components[comp_id].variables[0 .. edit_components[comp_id].used]) - { - switch(var.type) - { - case VariableGUI.Type.byte_: - igDragScalarClamp(var.name, ImGuiDataType_S8, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.ubyte_: - igDragScalarClamp(var.name, ImGuiDataType_U8, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.short_: - igDragScalarClamp(var.name, ImGuiDataType_S16, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.ushort_: - igDragScalarClamp(var.name, ImGuiDataType_U16, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.int_: - igDragScalarClamp(var.name, ImGuiDataType_S32, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.uint_: - igDragScalarClamp(var.name, ImGuiDataType_U32, comp_ptr+var.offset, 1, cast(void*)&var.int_.min, cast(void*)&var.int_.max, null, 1); - break; - case VariableGUI.Type.float_: - igDragScalarClamp(var.name, ImGuiDataType_Float, comp_ptr+var.offset, 1, cast(void*)&var.float_.min, cast(void*)&var.float_.max, null, 1); - break; - case VariableGUI.Type.color: - color = colorUintToVec4(*cast(uint*)(comp_ptr+var.offset)); - if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None)) - *cast(uint*)(comp_ptr+var.offset) = colorVec4ToUint(color); - break; - default:break; - } - } - igUnindent(8); - } - } + componentGUI(comp_id, comp_ptr); } } @@ -342,14 +366,15 @@ struct GUIManager { foreach(i, tmpl; templates) { - if(igSelectable(tmpl.name,selected_tempalte == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0))) + if(igSelectable(tmpl.name,selected_template == i,ImGuiSelectableFlags_AllowDoubleClick,ImVec2(0,0))) { - selected_tempalte = cast(uint)i; + selected_template = cast(uint)i; } } igListBoxFooter(); } } + if(igIsItemHovered(0))igSetTooltip("Select entity to spawn (SHIFT + Scroll)"); } style.Colors[ImGuiCol_Header] = col; entityComponentsGUI(); @@ -370,7 +395,10 @@ struct GUIManager igListBoxFooter(); } } + if(igIsItemHovered(0))igSetTooltip("Select component to add/remove (SHIFT + Scroll)"); } + style.Colors[ImGuiCol_Header] = col; + componentGUI(components[selected_component].component_id, components[selected_component].data); break; case Tool.selector: break; @@ -378,4 +406,33 @@ struct GUIManager style.Colors[ImGuiCol_Header] = col; } + + void filterGUI() + { + ImGuiStyle * style = igGetStyle(); + ImVec4 col = style.Colors[ImGuiCol_Header]; + style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg]; + + int length = 0; + foreach(comp; edit_components) + { + if(comp.name !is null)length++; + } + + if(length && igListBoxHeaderInt("Components",cast(int)length,cast(int)length)) + { + foreach(i, comp; edit_components) + { + if(comp.name is null)return; + if(igSelectable(comp.name,false,0,ImVec2(0,0))) + { + + } + } + igListBoxFooter(); + } + if(igIsItemHovered(0))igSetTooltip("Select components to filter while tool work.\nComponents are only changed for filtered entities."); + + style.Colors[ImGuiCol_Header] = col; + } } \ No newline at end of file From 8cba2626be1d8279550acd19bdc93ce6d3346a52 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 10 Jun 2020 15:35:42 +0200 Subject: [PATCH 42/58] Added entity filering support and fixed minor bug --- demos/source/app.d | 16 +++++++++++++++ demos/source/gui/manager.d | 42 ++++++++++++++++++++++++++++---------- source/bubel/ecs/entity.d | 2 +- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/demos/source/app.d b/demos/source/app.d index d526f97..6808e42 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -134,9 +134,21 @@ struct Launcher vec2 position; ComponentRef[] add_comps; ushort[] rem_comps; + ushort[] filter; + + bool filterEntity(ref const Entity entity) + { + EntityMeta meta = entity.getMeta(); + foreach(id;filter) + { + if(!meta.hasComponent(id))return false; + } + return true; + } void removeEntity(IteratorSystem.EntitiesData data) { + if(!filterEntity(data.entity[0]))return; foreach(i;0..data.length) { vec2 rel_vec = data.location[i] - position; @@ -147,6 +159,7 @@ struct Launcher void addComponent(IteratorSystem.EntitiesData data) { + if(!filterEntity(data.entity[0]))return; foreach(i;0..data.length) { vec2 rel_vec = data.location[i] - position; @@ -157,6 +170,7 @@ struct Launcher void overrideComponent(IteratorSystem.EntitiesData data) { + if(!filterEntity(data.entity[0]))return; foreach(i;0..data.length) { vec2 rel_vec = data.location[i] - position; @@ -171,6 +185,7 @@ struct Launcher void removeComponent(IteratorSystem.EntitiesData data) { + if(!filterEntity(data.entity[0]))return; foreach(i;0..data.length) { vec2 rel_vec = data.location[i] - position; @@ -185,6 +200,7 @@ struct Launcher Iterator iterator; iterator.size2 = size2; iterator.position = position; + iterator.filter = gui_manager.filter_list[]; switch(used_tool) { diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index 4ae9688..6fb3165 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -27,6 +27,8 @@ struct GUIManager Vector!ComponentGUI components; Vector!TemplateGUI templates; Vector!ComponentEditGUI edit_components; + Vector!bool filter; + Vector!ushort filter_list; int selected_template = 0; int selected_component = 0; @@ -62,8 +64,14 @@ struct GUIManager if(comp.variables)Mallocator.dispose(comp.variables); comp.variables = null; comp.used = 0; + comp.name = null; + } + foreach(ref comp; filter) + { + comp = false; } + filter_list.clear(); systems.clear(); templates.clear(); components.clear(); @@ -384,16 +392,14 @@ struct GUIManager { if(igListBoxHeaderInt("Components",cast(int)components.length,cast(int)components.length)) { + foreach(i, comp; components) { - foreach(i, comp; components) + if(igSelectable(comp.name,selected_component == i,0,ImVec2(0,0))) { - if(igSelectable(comp.name,selected_component == i,0,ImVec2(0,0))) - { - selected_component = cast(uint)i; - } + selected_component = cast(uint)i; } - igListBoxFooter(); } + igListBoxFooter(); } if(igIsItemHovered(0))igSetTooltip("Select component to add/remove (SHIFT + Scroll)"); } @@ -407,26 +413,40 @@ struct GUIManager style.Colors[ImGuiCol_Header] = col; } + private void genFilterList() + { + filter_list.clear(); + foreach(i, comp; filter) + { + if(comp) + { + filter_list.add(cast(ushort)i); + } + } + } + void filterGUI() { ImGuiStyle * style = igGetStyle(); ImVec4 col = style.Colors[ImGuiCol_Header]; style.Colors[ImGuiCol_Header] = style.Colors[ImGuiCol_TextSelectedBg]; + if(filter.length < edit_components.length)filter.length(edit_components.length); + int length = 0; foreach(comp; edit_components) { if(comp.name !is null)length++; } - if(length && igListBoxHeaderInt("Components",cast(int)length,cast(int)length)) + if(length && igListBoxHeaderInt("Components##FilterComponents",cast(int)length,cast(int)length)) { - foreach(i, comp; edit_components) + foreach(i, ref comp; edit_components) { - if(comp.name is null)return; - if(igSelectable(comp.name,false,0,ImVec2(0,0))) + if(comp.name is null)continue; + if(igSelectableBoolPtr(comp.name,&filter[i],0,ImVec2(0,0))) { - + genFilterList(); } } igListBoxFooter(); diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index 6a64d50..2c64c60 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -50,7 +50,7 @@ struct Entity return true; } - EntityMeta getMeta() + EntityMeta getMeta() const { EntityMeta meta; meta.block = gEM.getMetaData(&this); From 3a7a5b2a212279cd2af72635dad574b160602bcc Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 12 Jun 2020 14:53:59 +0200 Subject: [PATCH 43/58] Slightly changed rendering code -renderer draw function now takes struct instead of multiple parameters --- demos/source/demos/particles.d | 15 ++- demos/source/demos/simple.d | 14 ++- demos/source/demos/snake.d | 69 ++++++++++---- demos/source/demos/space_invaders.d | 73 ++++++++++---- demos/utils/source/ecs_utils/gfx/renderer.d | 100 +++++++++++++------- 5 files changed, 199 insertions(+), 72 deletions(-) diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d index b58b775..8b27f80 100644 --- a/demos/source/demos/particles.d +++ b/demos/source/demos/particles.d @@ -134,19 +134,30 @@ struct DrawSystem void onUpdate(EntitiesData data) { if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(2,2); + draw_data.coords = vec4(246,64,2,2)*px; + draw_data.color = 0x80808080; + draw_data.material_id = 2; + draw_data.thread_id = data.job_id; + draw_data.texture = particles_demo.texture; if(!data.color) { foreach(i; 0..data.length) { - launcher.renderer.draw(particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, 0x80808080, 0, 2, 0, data.job_id); + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data);//particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, 0x80808080, 0, 2, 0, data.job_id); } } else { foreach(i; 0..data.length) { - launcher.renderer.draw(particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, data.color[i].value, 0, 2, 0, data.job_id); + draw_data.position = data.locations[i]; + draw_data.color = data.color[i].value; + launcher.renderer.draw(draw_data);//particles_demo.texture, data.locations[i], vec2(2,2), vec4(246,64,2,2)*px, 0, data.color[i].value, 0, 2, 0, data.job_id); } } diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index ac3b3f7..6876e4f 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -52,9 +52,21 @@ struct DrawSystem void onUpdate(EntitiesData data) { if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.coords = vec4(0,0,1,1); + draw_data.color = 0x80808080; + draw_data.material_id = 0; + draw_data.thread_id = data.job_id; + draw_data.texture = simple.texture; + foreach(i; 0..data.length) { - launcher.renderer.draw(simple.texture, data.locations[i], vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y), 0x80808080, 0, 0, 0, data.job_id); + draw_data.position = data.locations[i]; + draw_data.depth = cast(ushort)(data.locations[i].y); + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(simple.texture, data.locations[i], vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y), 0x80808080, 0, 0, 0, data.job_id); // launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0x80808080, 0, 0, 0, data.job_id); //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); } diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 579bc54..c42f690 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -348,9 +348,21 @@ struct AnimationRenderSystem void onUpdate(EntitiesData data) { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + //draw_data.coords = vec4(0,0,1,1)*px; + draw_data.color = 0x80808080; + draw_data.material_id = 0; + draw_data.thread_id = 0; + draw_data.texture = snake.texture; + draw_data.depth = -1; foreach(i;0..data.length) { - launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i], vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080); + draw_data.position = data.location[i]; + draw_data.coords = data.animation[i].frames[cast(int)(data.animation[i].time)]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(snake.texture, cast(vec2)cast(ivec2)data.location[i], vec2(16,16), data.animation[i].frames[cast(int)(data.animation[i].time)], -1, 0x80808080); } } } @@ -649,9 +661,19 @@ struct DrawAppleSystem void onUpdate(EntitiesData data) { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.coords = vec4(0,32*px,16*px,16*px); + draw_data.color = 0x80808080; + draw_data.material_id = 0; + draw_data.thread_id = 0; + draw_data.texture = snake.texture; foreach(i; 0..data.location.length) { - launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0x80808080, 0); + draw_data.position = vec2(data.location[i].x*16,data.location[i].y*16); + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,32*px,16*px,16*px), 0, 0x80808080, 0); } } } @@ -719,34 +741,49 @@ struct DrawSnakeSystem static void drawElement(ivec2 loc, SnakePart part) { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.color = 0x80808080; + draw_data.texture = snake.texture; + draw_data.position = cast(vec2)loc; final switch(cast(ubyte)part) { - case SnakePart.tail_up:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,112,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.tail_down:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,112,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.tail_left:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,112,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.tail_right:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(0,144,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.turn_ld:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,128,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.turn_lu:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(32,144,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.turn_rd:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,144,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.turn_ru:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(64,112,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.vertical:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(16,128,16,16)*px, 0, 0x80808080, 0);break; - case SnakePart.horizontal:launcher.renderer.draw(.snake.texture, cast(vec2)loc, vec2(16,16), vec4(48,128,16,16)*px, 0, 0x80808080, 0);break; + case SnakePart.tail_up:draw_data.coords = vec4(16,112,16,16)*px;break; + case SnakePart.tail_down:draw_data.coords = vec4(0,112,16,16)*px;break; + case SnakePart.tail_left:draw_data.coords = vec4(32,112,16,16)*px;break; + case SnakePart.tail_right:draw_data.coords = vec4(0,144,16,16)*px;break; + case SnakePart.turn_ld:draw_data.coords = vec4(64,128,16,16)*px;break; + case SnakePart.turn_lu:draw_data.coords = vec4(32,144,16,16)*px;break; + case SnakePart.turn_rd:draw_data.coords = vec4(16,144,16,16)*px;break; + case SnakePart.turn_ru:draw_data.coords = vec4(64,112,16,16)*px;break; + case SnakePart.vertical:draw_data.coords = vec4(16,128,16,16)*px;break; + case SnakePart.horizontal:draw_data.coords = vec4(48,128,16,16)*px;break; } + launcher.renderer.draw(draw_data); } void onUpdate(EntitiesData data) { + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.size = vec2(16,16); + draw_data.color = 0x80808080; + draw_data.texture = snake.texture; + foreach(i; 0..data.length) { const (CSnake)* snake = &data.snake[i]; scope vec2 loc = cast(vec2)(data.location[i].location * 16); + draw_data.position = loc; final switch(snake.direction) { - case CMovement.Direction.up:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,112,16,16)*px, 0, 0x80808080, 0);break; - case CMovement.Direction.down:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(48,144,16,16)*px, 0, 0x80808080, 0);break; - case CMovement.Direction.left:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(0,128,16,16)*px, 0, 0x80808080, 0);break; - case CMovement.Direction.right:launcher.renderer.draw(.snake.texture, vec2(data.location[i].x*16,data.location[i].y*16), vec2(16,16), vec4(32,128,16,16)*px, 0, 0x80808080, 0);break; + case CMovement.Direction.up:draw_data.coords = vec4(48,112,16,16)*px;break; + case CMovement.Direction.down:draw_data.coords = vec4(48,144,16,16)*px;break; + case CMovement.Direction.left:draw_data.coords = vec4(0,128,16,16)*px;break; + case CMovement.Direction.right:draw_data.coords = vec4(32,128,16,16)*px;break; } + launcher.renderer.draw(draw_data); if(snake.parts.length >1) { foreach(j;1..snake.parts.length - 1)drawElement(snake.parts[j]*16, snakePart(snake.parts[j], snake.parts[j+1], snake.parts[j-1])); diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index ce2cd6a..b08b9ac 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -976,31 +976,52 @@ struct DrawSystem void onUpdate(EntitiesData data) { + if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + import ecs_utils.gfx.renderer; + Renderer.DrawData draw_data; + draw_data.color = 0x80808080; + draw_data.thread_id = data.job_id; + draw_data.texture = space_invaders.texture; + //uint color_mask = 0xFCFCFCFC; + uint const_map = 0x80A08080;//0x80808080; if(!data.depth) { if(data.hit_mark) { foreach(i; 0..data.length) { - uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; - short depth = cast(short)(data.locations[i].y); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, 0, 0, 0, data.job_id); + draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + draw_data.depth = cast(short)(data.locations[i].y); + draw_data.coords = data.textures[i].coords; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color|const_map, 0, 0, 0, data.job_id); } } else if(data.rotation) { foreach(i; 0..data.length) { - short depth = cast(short)(data.locations[i].y); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, data.rotation[i], 0, 0, data.job_id); + draw_data.depth = cast(short)(data.locations[i].y); + draw_data.angle = data.rotation[i]; + draw_data.coords = data.textures[i].coords; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, data.rotation[i], 0, 0, data.job_id); } } else { foreach(i; 0..data.length) { - short depth = cast(short)(data.locations[i].y); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, 0, 0, 0, data.job_id); + draw_data.depth = cast(short)(data.locations[i].y); + draw_data.coords = data.textures[i].coords; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, 0, 0, 0, data.job_id); } } } @@ -1012,18 +1033,27 @@ struct DrawSystem { foreach(i; 0..data.length) { - uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; - short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, data.rotation[i], 0, 0, data.job_id); + draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + draw_data.angle = data.rotation[i]; + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].coords; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color|const_map, data.rotation[i], 0, 0, data.job_id); } } else { foreach(i; 0..data.length) { - uint color = 0x80808080 + 0x01010101 * data.hit_mark[i]; - short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color, 0, 0, 0, data.job_id); + draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].coords; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, color|const_map, 0, 0, 0, data.job_id); } } } @@ -1031,16 +1061,25 @@ struct DrawSystem { foreach(i; 0..data.length) { - short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, data.rotation[i], 0, 0, data.job_id); + draw_data.angle = data.rotation[i]; + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].coords; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, data.rotation[i], 0, 0, data.job_id); } } else { foreach(i; 0..data.length) { - short depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080, 0, 0, 0, data.job_id); + draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); + draw_data.coords = data.textures[i].coords; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + //launcher.renderer.draw(space_invaders.texture, data.locations[i].value, data.scale[i], data.textures[i].coords, depth, 0x80808080|const_map, 0, 0, 0, data.job_id); } } } diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index 4e34b54..ef53543 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -430,13 +430,29 @@ struct Renderer } - void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0) + struct DrawData { - if(prepared_items >= MaxObjects)return; - __draw(this,tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id); + Texture texture; + vec2 position; + vec2 size; + vec4 coords; + short depth = 0; + uint color = uint.max; + float angle = 0; + uint material_id = 0; + uint mesh_id = 0; + uint thread_id = 0; } - private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) + //void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0) + void draw(scope ref const(DrawData) data) + { + if(prepared_items >= MaxObjects)return; + __draw(this,data);//tex,pos,size,coords,depth,color,angle,material_id,mesh_id,thread_id); + } + + //private static void __draw_sdl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) + private static void __draw_sdl(ref Renderer this_, scope ref const(DrawData) data) { /*with(this_) { @@ -456,22 +472,25 @@ struct Renderer }*/ } - private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) + // private static void __draw_gl(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) + private static void __draw_gl(ref Renderer this_, scope ref const(DrawData) data) { //import core.stdc.string; with(this_) { //pos += view_pos; - size.x *= view_size.x; - size.y *= view_size.y; - pos.x = pos.x * view_size.x + view_pos.x; - pos.y = pos.y * view_size.y + view_pos.y;//*/ + vec2 pos = void; + vec2 size = void; + size.x = data.size.x * view_size.x; + size.y = data.size.y * view_size.y; + pos.x = data.position.x * view_size.x + view_pos.x; + pos.y = data.position.y * view_size.y + view_pos.y;//*/ /*version(ver6)void* ptr = ubos[0].mappedPointer() + data_index; else void* ptr = uniform_block.ptr + data_index;*/ if(data_ptr is null)return; void* ptr = data_ptr + data_index; - if(angle == 0) + if(data.angle == 0) { *cast(float*)ptr = size.x; *cast(float*)(ptr+4) = 0; @@ -481,8 +500,8 @@ struct Renderer else { //import core.stdc.math; - float sinn = sinf(angle); - float coss = cosf(angle); + float sinn = sinf(data.angle); + float coss = cosf(data.angle); *cast(float*)ptr = coss * size.x; *cast(float*)(ptr+4) = -sinn * size.y; *cast(float*)(ptr+8) = sinn * size.x; @@ -491,12 +510,12 @@ struct Renderer //memcpy(ptr,); memcpy(ptr+16,pos.data.ptr,8); - memcpy(ptr+32,coords.data.ptr,16); + memcpy(ptr+32,data.coords.data.ptr,16); //render_list[item_id] = RenderData(tex,material_id,mesh_id); - render_list[item_id].texture = tex; - render_list[item_id].material_id = material_id; - render_list[item_id].mesh_id = mesh_id; + render_list[item_id].texture = *cast(Texture*)&data.texture; + render_list[item_id].material_id = data.material_id; + render_list[item_id].mesh_id = data.mesh_id; data_index += data_offset; item_id++; @@ -504,39 +523,43 @@ struct Renderer } } - private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0) + // private static void __draw_gl_vbo_batch(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id = 0) + private static void __draw_gl_vbo_batch(ref Renderer this_, scope ref const(DrawData) data) { import ecs_utils.gfx.config; //import core.stdc.string; with(this_) { + uint thread_id = data.thread_id; //if(item_id >= MaxObjects)return; //pos += view_pos; Thread* thread = &threads[thread_id]; VertexBlock* block; - assert(thread.blocks.length > material_id); - block = &thread.blocks[material_id]; + assert(thread.blocks.length > data.material_id); + block = &thread.blocks[data.material_id]; if(block.items == 0) { - thread.blocks[material_id] = getBlock(); - block = &thread.blocks[material_id]; - block.material_id = material_id; + thread.blocks[data.material_id] = getBlock(); + block = &thread.blocks[data.material_id]; + block.material_id = data.material_id; } else if(block.items >= VertexBlock.max_items) { //pushBlock(thread.block); prepared_items += block.items; thread.filled_blocks.add(*block); - thread.blocks[material_id] = getBlock(); - block = &thread.blocks[material_id]; - block.material_id = material_id; + thread.blocks[data.material_id] = getBlock(); + block = &thread.blocks[data.material_id]; + block.material_id = data.material_id; } - short[3] mem = [depth, *cast(short*)&color, *(cast(short*)&color + 1)]; + short[3] mem = [data.depth, *cast(short*)&data.color, *(cast(short*)&data.color + 1)]; - pos.x = pos.x * view_size.x + view_pos.x; - pos.y = pos.y * view_size.y + view_pos.y;//*/ + vec2 pos = void; + vec2 size = void; + pos.x = data.position.x * view_size.x + view_pos.x; + pos.y = data.position.y * view_size.y + view_pos.y;//*/ /*void* ptr = data_ptr + data_index; *cast(float*)ptr = size.x; @@ -550,10 +573,13 @@ struct Renderer short[] verts = cast(short[])block.batch_vertices; uint item_id = block.items; - if(angle == 0) + uint mesh_id = data.mesh_id; + vec4 coords = data.coords; + + if(data.angle == 0) { - size.x *= view_size.x; - size.y *= view_size.y; + size.x = data.size.x * view_size.x; + size.y = data.size.y * view_size.y; verts[item_id*28] = cast(short)((GfxConfig.meshes[mesh_id].vertices[0] * size.x + pos.x) * 8191); verts[item_id*28+1] = cast(short)((GfxConfig.meshes[mesh_id].vertices[1] * size.y + pos.y) * 8191); @@ -585,10 +611,11 @@ struct Renderer else { //import core.stdc.math; - float sinx = sinf(angle) * size.x * view_size.y; - float cosx = cosf(angle) * size.x * view_size.x; - float siny = sinf(angle) * size.y * view_size.x; - float cosy = cosf(angle) * size.y * view_size.y; + float angle = data.angle; + float sinx = sinf(angle) * data.size.x * view_size.y; + float cosx = cosf(angle) * data.size.x * view_size.x; + float siny = sinf(angle) * data.size.y * view_size.x; + float cosy = cosf(angle) * data.size.y * view_size.y; /*batch_vertices[item_id*28] = GfxConfig.meshes[mesh_id].vertices[0] * size.x; batch_vertices[item_id*28+1] = GfxConfig.meshes[mesh_id].vertices[1] * size.y; @@ -1088,7 +1115,8 @@ struct Renderer view_pos = (pos - size * 0.5) * view_size; } - __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) __draw; + // __gshared void function(ref Renderer this_, Texture tex, vec2 pos, vec2 size, vec4 coords, short depth, uint color, float angle, uint material_id, uint mesh_id, uint thread_id) __draw; + __gshared void function(ref Renderer this_, scope ref const(DrawData) data) __draw; __gshared void function(ref Renderer this_) __present; __gshared void function(ref Renderer this_) __clear; __gshared void function(ref Renderer this_) __initialize; From d733bb514ccc65c3ff877b787c95b21a6b9000c1 Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 12 Jun 2020 20:51:05 +0200 Subject: [PATCH 44/58] Make common draw system, moved some components to basic components and fixed bug with GUI for signed short integers --- demos/source/demos/particles.d | 16 +-- demos/source/demos/space_invaders.d | 151 +++++++++++------------ demos/source/game_core/basic.d | 45 +++++++ demos/source/game_core/rendering.d | 178 ++++++++++++++++++++++++++++ demos/source/gui/manager.d | 22 +++- 5 files changed, 326 insertions(+), 86 deletions(-) create mode 100644 demos/source/game_core/rendering.d diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d index 8b27f80..2242ecf 100644 --- a/demos/source/demos/particles.d +++ b/demos/source/demos/particles.d @@ -35,13 +35,6 @@ private enum float px = 1.0/512.0; alias location this; vec2 location; -}*/ - -struct CTexCoords -{ - mixin ECS.Component; - - vec4 value; } struct CColor @@ -53,6 +46,13 @@ struct CColor @GUIColor uint value = uint.max; } +struct CTexCoords +{ + mixin ECS.Component; + + vec4 value; +}*/ + struct CVelocity { mixin ECS.Component; @@ -453,7 +453,7 @@ void particlesStart() launcher.manager.beginRegister(); launcher.manager.registerComponent!CLocation; - launcher.manager.registerComponent!CTexCoords; + //launcher.manager.registerComponent!CTexCoords; launcher.manager.registerComponent!CColor; launcher.manager.registerComponent!CVelocity; launcher.manager.registerComponent!CAttractor; diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index b08b9ac..311feb3 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -17,6 +17,7 @@ import ecs_utils.math.vector; import ecs_utils.utils; import game_core.basic; +import game_core.rendering; //import std.math : PI; @@ -122,7 +123,7 @@ enum Direction : byte alias value this; vec2 value = vec2(0); -}*/ +} struct CScale { @@ -134,13 +135,13 @@ struct CScale vec2 value = vec2(16,16); } -struct CColliderScale +struct CDepth { mixin ECS.Component; - alias value this; + alias depth this; - vec2 value = vec2(16,16); + short depth; } struct CRotation @@ -160,6 +161,15 @@ struct CTexture //Texture tex; uint id; vec4 coords = vec4(0,0,0,1); +}*/ + +struct CColliderScale +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(16,16); } struct CVelocity @@ -255,15 +265,6 @@ struct CSideMove byte group = -1; } -struct CDepth -{ - mixin ECS.Component; - - alias depth this; - - short depth; -} - struct CShootGrid { mixin ECS.Component; @@ -754,11 +755,11 @@ struct ShipWeaponSystem CDepth* depth = entity.getComponent!CDepth; EntityID[2] weapons; weapon_tmpl.getComponent!CTargetParent().parent = entity.id; - if(depth)weapon_tmpl.getComponent!CDepth().depth = cast(short)(depth.depth - 1); - else weapon_tmpl.getComponent!CDepth().depth = -1; + if(depth)weapon_tmpl.getComponent!CDepth().value = cast(short)(depth.value - 1); + else weapon_tmpl.getComponent!CDepth().value = -1; top_tmpl.getComponent!CTargetParent().parent = entity.id; - if(depth)top_tmpl.getComponent!CDepth().depth = cast(short)(depth.depth - 2); - else top_tmpl.getComponent!CDepth().depth = -2; + if(depth)top_tmpl.getComponent!CDepth().value = cast(short)(depth.value - 2); + else top_tmpl.getComponent!CDepth().value = -2; weapons[0] = launcher.manager.addEntity(weapon_tmpl).id; weapons[1] = launcher.manager.addEntity(top_tmpl).id; @@ -771,7 +772,7 @@ struct ShipWeaponSystem [CWeapon.component_id, CLocation.component_id, CShootDirection.component_id, CTargetParent.component_id, CGuild.component_id, CVelocity.component_id, CAutoShoot.component_id, CTarget.component_id, CTargetPlayerShip.component_id, - CRotation.component_id, CScale.component_id, CTexture.component_id, + CRotation.component_id, CScale.component_id, CTexCoords.component_id, CDepth.component_id, CWeaponLocation.component_id].staticArray); *weapon_tmpl.getComponent!CWeapon = CWeapon(0,CWeapon.Type.laser,3); weapon_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,0); @@ -779,17 +780,17 @@ struct ShipWeaponSystem weapon_tmpl.getComponent!CScale().value = vec2(4,16); //weapon_tmpl.getComponent!CWeapon().level = 1; *weapon_tmpl.getComponent!CWeapon() = CWeapon(0,CWeapon.Type.canon,1); - weapon_tmpl.getComponent!CDepth().depth = -1; - weapon_tmpl.getComponent!CTexture().coords = vec4(136,96,4,16)*px; + weapon_tmpl.getComponent!CDepth().value = -1; + weapon_tmpl.getComponent!CTexCoords().value = vec4(136,96,4,16)*px; weapon_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,12); top_tmpl = launcher.manager.allocateTemplate( [CLocation.component_id, CTargetParent.component_id, CScale.component_id, - CTexture.component_id, CDepth.component_id].staticArray); + CTexCoords.component_id, CDepth.component_id].staticArray); top_tmpl.getComponent!CTargetParent().rel_pos = vec2(0,1); top_tmpl.getComponent!CScale().value = vec2(10,11); - top_tmpl.getComponent!CDepth().depth = -2; - top_tmpl.getComponent!CTexture().coords = vec4(112,96,10,11)*px; + top_tmpl.getComponent!CDepth().value = -2; + top_tmpl.getComponent!CTexCoords().value = vec4(112,96,10,11)*px; } @@ -829,21 +830,23 @@ struct ShipWeaponSystem { tower1_tmpl = launcher.manager.allocateTemplate( [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, - CTexture.component_id, CScale.component_id, CEnemy.component_id, + CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, CChildren.component_id, CDepth.component_id, CTargetParent.component_id, CSpawnUponDeath.component_id, CShootWaveUponDeath.component_id].staticArray ); - CTexture* tex_comp = tower1_tmpl.getComponent!CTexture; + /*CTexCoords* tex_comp = tower1_tmpl.getComponent!CTexCoords; //tex_comp.tex = space_invaders.texture;//ship_tex; tex_comp.coords = vec4(96*px,96*px,16*px,16*px); CLocation* loc_comp = tower1_tmpl.getComponent!CLocation; - loc_comp.value = vec2(64,space_invaders.map_size.y - 16); + loc_comp.value = vec2(64,space_invaders.map_size.y - 16);*/ + tower1_tmpl.getComponent!CTexCoords().value = vec4(96*px,96*px,16*px,16*px); + tower1_tmpl.getComponent!CLocation().value = vec2(64,space_invaders.map_size.y - 16); tower1_tmpl.getComponent!CGuild().guild = 1; tower1_tmpl.getComponent!CInit().type = CInit.Type.tower; tower1_tmpl.getComponent!CHitPoints().value = 10; - tower1_tmpl.getComponent!CDepth().depth = -2; + tower1_tmpl.getComponent!CDepth().value = -2; tower1_tmpl.getComponent!CShootWaveUponDeath().bullet_type = CWeapon.Type.canon; tower1_tmpl.getComponent!CTargetParent().rel_pos = vec2(-33,2); @@ -851,11 +854,11 @@ struct ShipWeaponSystem tower2_tmpl.getComponent!CTargetParent().rel_pos = vec2(33,2); tower3_tmpl = launcher.manager.allocateTemplate(tower1_tmpl); - tower3_tmpl.getComponent!CDepth().depth = 0; + tower3_tmpl.getComponent!CDepth().value = 0; tower3_tmpl.getComponent!CTargetParent().rel_pos = vec2(-40,-15); tower4_tmpl = launcher.manager.allocateTemplate(tower1_tmpl); - tower4_tmpl.getComponent!CDepth().depth = 0; + tower4_tmpl.getComponent!CDepth().value = 0; tower4_tmpl.getComponent!CTargetParent().rel_pos = vec2(40,-15); } @@ -966,7 +969,7 @@ struct DrawSystem uint length; //uint thread_id; uint job_id; - @readonly CTexture[] textures; + @readonly CTexCoords[] textures; @readonly CLocation[] locations; @readonly CScale[] scale; @readonly @optional CRotation[] rotation; @@ -992,7 +995,7 @@ struct DrawSystem { draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; draw_data.depth = cast(short)(data.locations[i].y); - draw_data.coords = data.textures[i].coords; + draw_data.coords = data.textures[i].value; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; launcher.renderer.draw(draw_data); @@ -1005,7 +1008,7 @@ struct DrawSystem { draw_data.depth = cast(short)(data.locations[i].y); draw_data.angle = data.rotation[i]; - draw_data.coords = data.textures[i].coords; + draw_data.coords = data.textures[i].value; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; launcher.renderer.draw(draw_data); @@ -1017,7 +1020,7 @@ struct DrawSystem foreach(i; 0..data.length) { draw_data.depth = cast(short)(data.locations[i].y); - draw_data.coords = data.textures[i].coords; + draw_data.coords = data.textures[i].value; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; launcher.renderer.draw(draw_data); @@ -1036,7 +1039,7 @@ struct DrawSystem draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; draw_data.angle = data.rotation[i]; draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - draw_data.coords = data.textures[i].coords; + draw_data.coords = data.textures[i].value; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; launcher.renderer.draw(draw_data); @@ -1049,7 +1052,7 @@ struct DrawSystem { draw_data.color = 0x80808080 + 0x01010101 * data.hit_mark[i]; draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - draw_data.coords = data.textures[i].coords; + draw_data.coords = data.textures[i].value; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; launcher.renderer.draw(draw_data); @@ -1063,7 +1066,7 @@ struct DrawSystem { draw_data.angle = data.rotation[i]; draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - draw_data.coords = data.textures[i].coords; + draw_data.coords = data.textures[i].value; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; launcher.renderer.draw(draw_data); @@ -1075,7 +1078,7 @@ struct DrawSystem foreach(i; 0..data.length) { draw_data.depth = cast(short)(data.depth[i] * 8 + data.locations[i].y); - draw_data.coords = data.textures[i].coords; + draw_data.coords = data.textures[i].value; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; launcher.renderer.draw(draw_data); @@ -1138,31 +1141,31 @@ struct ShootingSystem void onCreate() { /*bullet_tmpl[0] = launcher.manager.allocateTemplate( - [CLocation.component_id, CTexture.component_id, CVelocity.component_id, + [CLocation.component_id, CTexCoords.component_id, CVelocity.component_id, CScale.component_id, CBullet.component_id, CGuild.component_id].staticArray ); - bullet_tmpl[0].getComponent!CTexture().coords = vec4(0,24,2,8)*px; + bullet_tmpl[0].getComponent!CTexCoords().value = vec4(0,24,2,8)*px; bullet_tmpl[0].getComponent!CScale().value = vec2(2,8); bullet_tmpl[1] = launcher.manager.allocateTemplate(bullet_tmpl[0]); bullet_tmpl[2] = launcher.manager.allocateTemplate(bullet_tmpl[0]); - bullet_tmpl[2].getComponent!CTexture().coords = vec4(64,32,8,16)*px; + bullet_tmpl[2].getComponent!CTexCoords().value = vec4(64,32,8,16)*px; bullet_tmpl[2].getComponent!CScale().value = vec2(8,16); bullet_tmpl[3] = launcher.manager.allocateTemplate(bullet_tmpl[0]); - bullet_tmpl[3].getComponent!CTexture().coords = vec4(56,32,2,2)*px; + bullet_tmpl[3].getComponent!CTexCoords().value = vec4(56,32,2,2)*px; bullet_tmpl[3].getComponent!CScale().value = vec2(2,2); - // bullet_tmpl[3].getComponent!CTexture().coords = vec4(48,32,8,8)*px; + // bullet_tmpl[3].getComponent!CTexCoords().value = vec4(48,32,8,8)*px; // bullet_tmpl[3].getComponent!CScale().value = vec2(8,8); bullet_tmpl[4] = launcher.manager.allocateTemplate(bullet_tmpl[0]);*/ fire_tmpl = launcher.manager.allocateTemplate( - [CLocation.component_id, CTexture.component_id, CScale.component_id, + [CLocation.component_id, CTexCoords.component_id, CScale.component_id, CAnimation.component_id, CParticle.component_id, CRotation.component_id, CVelocity.component_id, CDamping.component_id].staticArray ); - fire_tmpl.getComponent!CTexture().coords = vec4(96,64,8,16)*px; + fire_tmpl.getComponent!CTexCoords().value = vec4(96,64,8,16)*px; fire_tmpl.getComponent!CScale().value = vec2(8,16); fire_tmpl.getComponent!(CParticle).life = 300; *fire_tmpl.getComponent!(CAnimation) = CAnimation(fire_frames, 0, 3); @@ -1364,7 +1367,7 @@ struct ParticleEmittingSystem void onCreate() { templates[0] = launcher.manager.allocateTemplate( - [CLocation.component_id, CTexture.component_id, CScale.component_id, + [CLocation.component_id, CTexCoords.component_id, CScale.component_id, CAnimation.component_id, CParticle.component_id, CRotation.component_id, CVelocity.component_id, CDamping.component_id, CDepth.component_id].staticArray); *templates[0].getComponent!CAnimation() = CAnimation(flashes,0,2); @@ -1400,7 +1403,7 @@ struct ParticleEmittingSystem if(data.depth) { - depth.depth = data.depth[i]; + depth.value = data.depth[i]; } launcher.manager.addEntity(templates[0],[data.location[i].ref_,velocity.ref_,depth.ref_].staticArray); @@ -1659,18 +1662,18 @@ struct HitPointsSystem void onCreate() { upgrade_tmpl = launcher.manager.allocateTemplate( - [CVelocity.component_id, CLocation.component_id, CTexture.component_id, + [CVelocity.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CUpgrade.component_id, CAnimation.component_id, CAnimationLooped.component_id].staticArray); //tex_comp.tex = space_invaders.texture;//ship_tex; - upgrade_tmpl.getComponent!CTexture().coords = vec4(0*px,32*px,16*px,16*px); + upgrade_tmpl.getComponent!CTexCoords().value = vec4(0*px,32*px,16*px,16*px); *upgrade_tmpl.getComponent!CAnimation = CAnimation(upgrade_laser_frames, 0, 1); upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.1); explosion_tmpl = launcher.manager.allocateTemplate( [CDepth.component_id, CParticle.component_id, CLocation.component_id, - CTexture.component_id, CScale.component_id, CAnimation.component_id].staticArray); - //explosion_tmpl.getComponent!(CTexture).tex = space_invaders.texture; + CTexCoords.component_id, CScale.component_id, CAnimation.component_id].staticArray); + //explosion_tmpl.getComponent!(CTexCoords).tex = space_invaders.texture; *explosion_tmpl.getComponent!CAnimation = CAnimation(explosion_laser_frames, 0, 1.333); explosion_tmpl.getComponent!(CParticle).life = 600; *explosion_tmpl.getComponent!CDepth = -1; @@ -2005,7 +2008,8 @@ struct AnimationSystem { uint length; CAnimation[] animation; - CTexture[] texture; + //CTexture[] texture; + CTexCoords[] texcoords; @optional @readonly CAnimationLooped[] looped; } @@ -2020,7 +2024,7 @@ struct AnimationSystem while(cast(uint)data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time -= cast(float)data.animation[i].frames.length; if(cast(uint)(data.animation[i].time) >= data.animation[i].frames.length)assert(0); uint index = cast(uint)(data.animation[i].time); - if(index < data.animation[i].frames.length)data.texture[i].coords = data.animation[i].frames[index]; + if(index < data.animation[i].frames.length)data.texcoords[i].value = data.animation[i].frames[index]; } } else @@ -2030,7 +2034,7 @@ struct AnimationSystem data.animation[i].time += dt * data.animation[i].speed; if(cast(uint)data.animation[i].time >= data.animation[i].frames.length)data.animation[i].time = data.animation[i].frames.length - 0.9; uint index = cast(uint)(data.animation[i].time); - if(index < data.animation[i].frames.length)data.texture[i].coords = data.animation[i].frames[index]; + if(index < data.animation[i].frames.length)data.texcoords[i].value = data.animation[i].frames[index]; } } @@ -2241,7 +2245,7 @@ struct InputMovementSystem //components are treated as required by default //CLocation[] locations; CVelocity[] velocity; - CTexture[] textures; + //CTexture[] textures; } /** @@ -2336,7 +2340,8 @@ void spaceInvadersStart() launcher.manager.registerDependency(ShootGridDependency); launcher.manager.registerComponent!CLocation; - launcher.manager.registerComponent!CTexture; + launcher.manager.registerComponent!CTexCoords; + //launcher.manager.registerComponent!CTexture; launcher.manager.registerComponent!CInput; launcher.manager.registerComponent!CShip; launcher.manager.registerComponent!CEnemy; @@ -2478,12 +2483,12 @@ void spaceInvadersStart() { space_invaders.ship_tmpl = launcher.manager.allocateTemplate( [CVelocity.component_id, CHitMark.component_id, CHitPoints.component_id, - CLocation.component_id, CTexture.component_id, CInput.component_id, + CLocation.component_id, CTexCoords.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CColliderScale.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id, CDamping.component_id, CChildren.component_id, CInit.component_id].staticArray ); - space_invaders.ship_tmpl.getComponent!CTexture().coords = vec4(0,80,48,32)*px; + space_invaders.ship_tmpl.getComponent!CTexCoords().value = vec4(0,80,48,32)*px; space_invaders.ship_tmpl.getComponent!CScale().value = vec2(48,32); space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; space_invaders.ship_tmpl.getComponent!CDamping().value = 7; @@ -2494,10 +2499,10 @@ void spaceInvadersStart() } { - ushort[6] components = [CLocation.component_id, CTexture.component_id, CVelocity.component_id, CScale.component_id, CBullet.component_id, CGuild.component_id]; + ushort[6] components = [CLocation.component_id, CTexCoords.component_id, CVelocity.component_id, CScale.component_id, CBullet.component_id, CGuild.component_id]; space_invaders.laser_tmpl = launcher.manager.allocateTemplate(components); - space_invaders.laser_tmpl.getComponent!CTexture().coords = vec4(0,24,2,8)*px; + space_invaders.laser_tmpl.getComponent!CTexCoords().value = vec4(0,24,2,8)*px; space_invaders.laser_tmpl.getComponent!CScale().value = vec2(2,8); space_invaders.laser_tmpl.getComponent!CVelocity().value = vec2(0,1); } @@ -2513,7 +2518,7 @@ void spaceInvadersStart() { boss_tmpl = launcher.manager.allocateTemplate( [CHitMark.component_id, CParts.component_id, CLocation.component_id, - CTexture.component_id, CScale.component_id, CEnemy.component_id, + CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CBoss.component_id, CGuild.component_id, CInit.component_id, CChildren.component_id, CSideMove.component_id, CVelocity.component_id, CDepth.component_id].staticArray @@ -2524,11 +2529,11 @@ void spaceInvadersStart() //tex_comp.coords = vec4(128*px,0*px,96*px,48*px); //CLocation* loc_comp = boss_tmpl.getComponent!CLocation; //loc_comp.value = vec2(64,space_invaders.map_size.y - 16); - boss_tmpl.getComponent!CTexture().coords = vec4(128,0,96,48)*px; + boss_tmpl.getComponent!CTexCoords().value = vec4(128,0,96,48)*px; boss_tmpl.getComponent!CGuild().guild = 1; boss_tmpl.getComponent!CInit().type = CInit.Type.boss; boss_tmpl.getComponent!CScale().value = vec2(96,48); - boss_tmpl.getComponent!CDepth().depth = -1; + boss_tmpl.getComponent!CDepth().value = -1; boss_tmpl.getComponent!CParts().count = 4; boss_tmpl.getComponent!CVelocity().value = vec2(0.05,0); } @@ -2536,12 +2541,12 @@ void spaceInvadersStart() { tower_tmpl = launcher.manager.allocateTemplate( [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, - CTexture.component_id, CScale.component_id, CEnemy.component_id, + CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, CChildren.component_id].staticArray ); - tower_tmpl.getComponent!CTexture().coords = vec4(96,96,16,16)*px; + tower_tmpl.getComponent!CTexCoords().value = vec4(96,96,16,16)*px; tower_tmpl.getComponent!CGuild().guild = 1; tower_tmpl.getComponent!CInit().type = CInit.Type.tower; tower_tmpl.getComponent!CHitPoints().value = 10; @@ -2551,12 +2556,12 @@ void spaceInvadersStart() space_invaders.enemy_tmpl = launcher.manager.allocateTemplate( [CWeaponLocation.component_id, CHitMark.component_id, CHitPoints.component_id, CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, - CTexture.component_id, CScale.component_id, CWeapon.component_id, + CTexCoords.component_id, CScale.component_id, CWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id].staticArray ); - space_invaders.enemy_tmpl.getComponent!CTexture().coords = vec4(32,32,16,16)*px; + space_invaders.enemy_tmpl.getComponent!CTexCoords().value = vec4(32,32,16,16)*px; space_invaders.enemy_tmpl.getComponent!CShootDirection().direction = Direction.down; space_invaders.enemy_tmpl.getComponent!CVelocity().value = vec2(0.1,0); space_invaders.enemy_tmpl.getComponent!CGuild().guild = 1; @@ -2588,8 +2593,8 @@ void spaceInvadersStart() EntityTemplate* upgrade_tmpl; { - upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexture.component_id, CScale.component_id, CUpgrade.component_id, CAnimationLooped.component_id, CAnimation.component_id].staticArray); - upgrade_tmpl.getComponent!CTexture().coords = vec4(0,32,16,16)*px; + upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CUpgrade.component_id, CAnimationLooped.component_id, CAnimation.component_id].staticArray); + upgrade_tmpl.getComponent!CTexCoords().value = vec4(0,32,16,16)*px; upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.1); *upgrade_tmpl.getComponent!CAnimation = CAnimation(HitPointsSystem.upgrade_laser_frames, 0, 0.75); } @@ -2600,20 +2605,20 @@ void spaceInvadersStart() grouped_tmpl = launcher.manager.allocateTemplate(grouped_id); space_invaders.bullet_tmpl[0] = launcher.manager.allocateTemplate( - [CLocation.component_id, CTexture.component_id, CVelocity.component_id, + [CLocation.component_id, CTexCoords.component_id, CVelocity.component_id, CScale.component_id, CBullet.component_id, CGuild.component_id].staticArray ); - space_invaders.bullet_tmpl[0].getComponent!CTexture().coords = vec4(0,24,2,8)*px; + space_invaders.bullet_tmpl[0].getComponent!CTexCoords().value = vec4(0,24,2,8)*px; space_invaders.bullet_tmpl[0].getComponent!CScale().value = vec2(2,8); space_invaders.bullet_tmpl[1] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); space_invaders.bullet_tmpl[2] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); - space_invaders.bullet_tmpl[2].getComponent!CTexture().coords = vec4(64,32,8,16)*px; + space_invaders.bullet_tmpl[2].getComponent!CTexCoords().value = vec4(64,32,8,16)*px; space_invaders.bullet_tmpl[2].getComponent!CScale().value = vec2(8,16); space_invaders.bullet_tmpl[3] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); - space_invaders.bullet_tmpl[3].getComponent!CTexture().coords = vec4(56,32,2,2)*px; + space_invaders.bullet_tmpl[3].getComponent!CTexCoords().value = vec4(56,32,2,2)*px; space_invaders.bullet_tmpl[3].getComponent!CScale().value = vec2(2,2); - // bullet_tmpl[3].getComponent!CTexture().coords = vec4(48,32,8,8)*px; + // bullet_tmpl[3].getComponent!CTexCoords().value = vec4(48,32,8,8)*px; // bullet_tmpl[3].getComponent!CScale().value = vec2(8,8); space_invaders.bullet_tmpl[4] = launcher.manager.allocateTemplate(space_invaders.bullet_tmpl[0]); diff --git a/demos/source/game_core/basic.d b/demos/source/game_core/basic.d index 993a5aa..156680b 100644 --- a/demos/source/game_core/basic.d +++ b/demos/source/game_core/basic.d @@ -4,6 +4,8 @@ import bubel.ecs.core; import ecs_utils.math.vector; +import gui.attributes; + struct CLocation { mixin ECS.Component; @@ -11,4 +13,47 @@ struct CLocation alias value this; vec2 value = vec2(0); +} + +struct CScale +{ + mixin ECS.Component; + + alias value this;///use component as it value + + vec2 value = vec2(16,16); +} + +struct CRotation +{ + mixin ECS.Component; + + alias value this;///use component as it value + + float value = 0; +} + +struct CDepth +{ + mixin ECS.Component; + + alias value this; + + short value; +} + +struct CColor +{ + mixin ECS.Component; + + alias value this; + + @GUIColor uint value; +} + +struct CSelected +{ + mixin ECS.Component; + + bool value = false; } \ No newline at end of file diff --git a/demos/source/game_core/rendering.d b/demos/source/game_core/rendering.d new file mode 100644 index 0000000..de5f0b5 --- /dev/null +++ b/demos/source/game_core/rendering.d @@ -0,0 +1,178 @@ +module game_core.rendering; + +import bubel.ecs.core; +import bubel.ecs.attributes; + +import ecs_utils.math.vector; +import ecs_utils.gfx.texture; + +import game_core.basic; + +struct CTexCoords +{ + mixin ECS.Component; + + alias value this;///use component as it value + + vec4 value; +} + +struct CTexCoordsIndex +{ + mixin ECS.Component; + + ushort value; +} + +struct TexCoordsManager +{ + import bubel.ecs.vector; + import bubel.ecs.hash_map; + + Vector!vec4 coords; + HashMap!(vec4,ushort) coords_map; +} + +struct DrawSystem +{ + mixin ECS.System!32; + + import ecs_utils.gfx.renderer : Renderer; + + struct EntitiesData + { + uint length; + //uint thread_id; + uint job_id; + @readonly CLocation[] locations; + @readonly CScale[] scale; + @readonly CTexCoords[] texcoord; + // @readonly @optional CTexCoords[] texcoord; + // @readonly @optional CTexCoordsIndex[] texcoord_index; + @readonly @optional CRotation[] rotation; + @readonly @optional CDepth[] depth; + @readonly @optional CColor[] color; + } + + Renderer.DrawData default_data; + + void onUpdate(EntitiesData data) + { + import app : launcher; + + if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached + Renderer.DrawData draw_data = default_data; + draw_data.thread_id = data.job_id; + + if(!data.depth) + { + if(!data.color) + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + else + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.color = data.color[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + } + else + { + if(!data.color) + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + else + { + if(!data.rotation) + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.color = data.color[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + else + { + foreach(i; 0..data.length) + { + draw_data.depth = data.depth[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + draw_data.size = data.scale[i]; + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + } + } + } + } +} \ No newline at end of file diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index 6fb3165..3f6e6cb 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -173,9 +173,21 @@ struct GUIManager { switch(member_type.sizeof) { - case 1: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.byte_,member_str,offset);break; - case 2: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.short_,member_str,offset);break; - case 4: comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.int_,member_str,offset);break; + case 1: + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.byte_,member_str,offset); + comp_edit.variables[comp_edit.used-1].int_.min = byte.min; + comp_edit.variables[comp_edit.used-1].int_.max = byte.max; + break; + case 2: + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.short_,member_str,offset); + comp_edit.variables[comp_edit.used-1].int_.min = short.min; + comp_edit.variables[comp_edit.used-1].int_.max = short.max; + break; + case 4: + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.int_,member_str,offset); + comp_edit.variables[comp_edit.used-1].int_.min = int.min; + comp_edit.variables[comp_edit.used-1].int_.max = int.max; + break; default:break; } static if(hasUDA!(member,GUIRange)) @@ -183,10 +195,10 @@ struct GUIManager comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min; comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[1].max; } - { + /*{ comp_edit.variables[comp_edit.used-1].int_.min = int.min; comp_edit.variables[comp_edit.used-1].int_.max = int.max; - } + }*/ } } else static if(__traits(isScalar,member_type)) From 3e7575c4b2579d9d4aa08a40b64189fa8a7f0076 Mon Sep 17 00:00:00 2001 From: Mergul Date: Mon, 15 Jun 2020 17:21:29 +0200 Subject: [PATCH 45/58] Bug fixes -fix: UnittestRunner don't catch RangeError -fix: sometimes onUpdate was called with empty array of entities --- source/bubel/ecs/manager.d | 28 +++++++++++++++++++++++++--- tests/runner.d | 9 ++++++++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 4c543ce..132ab62 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -1011,7 +1011,8 @@ export struct EntityManager if (entities_count > 0) { assert(entities_count <= block.entities_count - && offset <= block.entities_count); + && offset < block.entities_count); + assert(entities_count > offset); fillInputData(input_data, info, block, offset, entities_count, system); @@ -1489,21 +1490,27 @@ export struct EntityManager if (first_block is null || blocks_count == 0) continue; + //if this info will fill job if ((blocks_count - 1) * info.max_entities + entities_count + info.last_block.entities_count - first_elem >= entities_per_job) { int reamaining_entities = (entities_per_job - entities_count - ( first_block.entities_count - first_elem)); - if (reamaining_entities >= 0) + + //if first block don't fill job + if (reamaining_entities > 0) { + //take as many full blocks as possible int full_blocks_count = reamaining_entities / info.max_entities; EntitiesBlock* block = first_block; foreach (i; 0 .. full_blocks_count + 1) block = block.next_block; + //if full block + actual contained entities + remaining entities form first block > entities count per job if (full_blocks_count * info.max_entities + entities_count + ( first_block.entities_count - first_elem) >= entities_per_job) { + assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + (first_block.entities_count - first_elem)); CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate, first_block, cast(ushort)(full_blocks_count + 1), @@ -1518,6 +1525,8 @@ export struct EntityManager entities_count += full_blocks_count * info.max_entities + ( first_block.entities_count - first_elem); // - first_elem; uint last_elem = entities_per_job - entities_count; // + first_elem - 1; + assert(last_elem > 0); + assert(last_elem <= block.entities_count); CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate, first_block, cast(ushort)(full_blocks_count + 2), @@ -1525,19 +1534,31 @@ export struct EntityManager tmp_datas.add(data); first_elem = last_elem; blocks_count -= full_blocks_count + 1; - assert(first_elem <= block.entities_count); first_block = block; + if(last_elem == block.entities_count) + { + assert(block.next_block == null); + first_block = null; + } } } else { uint last_elem = entities_per_job - entities_count; + assert(last_elem > 0); CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate, first_block, 1, cast(ushort) first_elem, cast(ushort)(first_elem + last_elem)); tmp_datas.add(data); first_elem += last_elem; assert(first_elem <= first_block.entities_count); + //if job takes every entity, take next block + if(first_elem == first_block.entities_count) + { + first_elem = 0; + first_block = first_block.next_block; + blocks_count--; + } } nextJob(); entities_count = 0; @@ -1545,6 +1566,7 @@ export struct EntityManager } else { + //take whole info blocks CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate, first_block, cast(ushort) blocks_count, cast(ushort) first_elem); tmp_datas.add(data); diff --git a/tests/runner.d b/tests/runner.d index 7e3dd07..83c2288 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -236,7 +236,7 @@ struct TestRunner(Args...) } else { - import core.exception : AssertError; + import core.exception : AssertError, RangeError; try { unittest_(); @@ -249,6 +249,13 @@ struct TestRunner(Args...) test.file_line = cast(int)error.line; test.msg = copyString(error.msg); } + catch(RangeError error) + { + test.passed = false; + test.file = copyString(error.file); + test.file_line = cast(int)error.line; + test.msg = copyString(error.msg); + } } if (test.passed) From ffc19d4723f214cc4d083343f4021825849355cb Mon Sep 17 00:00:00 2001 From: Mergul Date: Mon, 15 Jun 2020 22:28:55 +0200 Subject: [PATCH 46/58] Better multithread jobs generation tests --- source/bubel/ecs/manager.d | 9 +++---- tests/basic.d | 48 +++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 132ab62..fa64e7b 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -1496,7 +1496,7 @@ export struct EntityManager { int reamaining_entities = (entities_per_job - entities_count - ( first_block.entities_count - first_elem)); - + //if first block don't fill job if (reamaining_entities > 0) { @@ -1510,7 +1510,8 @@ export struct EntityManager if (full_blocks_count * info.max_entities + entities_count + ( first_block.entities_count - first_elem) >= entities_per_job) { - assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + (first_block.entities_count - first_elem)); + assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + ( + first_block.entities_count - first_elem)); CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate, first_block, cast(ushort)(full_blocks_count + 1), @@ -1535,7 +1536,7 @@ export struct EntityManager first_elem = last_elem; blocks_count -= full_blocks_count + 1; first_block = block; - if(last_elem == block.entities_count) + if (last_elem == block.entities_count) { assert(block.next_block == null); first_block = null; @@ -1553,7 +1554,7 @@ export struct EntityManager first_elem += last_elem; assert(first_elem <= first_block.entities_count); //if job takes every entity, take next block - if(first_elem == first_block.entities_count) + if (first_elem == first_block.entities_count) { first_elem = 0; first_block = first_block.next_block; diff --git a/tests/basic.d b/tests/basic.d index 5046dff..5830a7b 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -897,7 +897,7 @@ unittest { struct TestSystem { - mixin ECS.System; + mixin ECS.System!64; struct EntitiesData { @@ -1003,15 +1003,51 @@ unittest assert(empty_system.update == 3); system.entities = 0; - foreach(i;0..10000)gEM.addEntity(tmpl); + // foreach(i;0..10000)gEM.addEntity(tmpl); - gEM.begin(); + // gEM.begin(); - gEM.updateMT("custom"); + // gEM.updateMT("custom"); - gEM.end(); + // gEM.end(); - assert(system.entities == 12001); + // assert(system.entities == 12001); + + void clearEntities(TestSystem.EntitiesData data) + { + foreach(i;0..data.length) + { + gEM.removeEntity(data.entity[i].id); + } + } + gEM.callEntitiesFunction!TestSystem(&clearEntities); + gEM.commit(); + + foreach(i;0..2000) + { + gEM.addEntity(tmpl); + + gEM.begin(); + gEM.updateMT("custom"); + gEM.end(); + + assert(system.entities == i+1); + system.entities = 0; + } + + foreach(i;0..90000)gEM.addEntity(tmpl); + + foreach(i;0..2000) + { + gEM.addEntity(tmpl); + + gEM.begin(); + gEM.updateMT("custom"); + gEM.end(); + + assert(system.entities == i+92001); + system.entities = 0; + } } unittest From ef4faf27551cd5025614b4ac2fa83326e2212b98 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 1 Jul 2020 19:26:47 +0200 Subject: [PATCH 47/58] Changed Components/System/Events names to full name (with module) and fixed bug with flag --- source/bubel/ecs/manager.d | 63 ++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index fa64e7b..cce03c6 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -382,6 +382,9 @@ export struct EntityManager else assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist."); + enum SystemName = fullyQualifiedName!Sys; + //enum SystemName = Sys.stringof; + System system; system.m_pass = pass; @@ -418,9 +421,9 @@ export struct EntityManager static if (Params.length == 2 && is(Params[0] == Entity*)) { alias EventParamType = Params[1]; - enum EventName = Unqual!(EventParamType).stringof; + enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof; ushort evt = events_map.get(cast(char[]) EventName, ushort.max); - assert(evt != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(evt != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing event \"" ~ EventName ~ "\"."); callers[i].callback = cast(void*)&callEventHandler!(EventParamType); @@ -479,7 +482,7 @@ export struct EntityManager string name; static if (isArray!MemberType) { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = Unqual!(ForeachType!MemberType).stringof; + name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));//.stringof; } bool is_optional; @@ -704,7 +707,8 @@ export struct EntityManager string name; static if (isArray!MemberType) { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = Unqual!(ForeachType!MemberType).stringof; + name = fullyQualifiedName!(Unqual!(ForeachType!MemberType)); + //name = Unqual!(ForeachType!MemberType).stringof; } bool is_optional; @@ -759,7 +763,8 @@ export struct EntityManager { foreach (str; Sys.ExcludedComponents) { - components_info.addExcluded(CompInfo(str.stringof, str.stringof)); + components_info.addExcluded(CompInfo(str.stringof, fullyQualifiedName!str)); + // components_info.addExcluded(CompInfo(str.stringof, str.stringof)); } } @@ -828,10 +833,10 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ Sys.stringof + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else - assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(comp != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); system.m_components[iii] = comp; } @@ -840,10 +845,10 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ Sys.stringof + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else - assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(comp != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); system.m_excluded_components[iii] = comp; } @@ -852,10 +857,10 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ Sys.stringof + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else - assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(comp != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); system.m_optional_components[iii] = comp; } @@ -864,10 +869,10 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ Sys.stringof + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else - assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(comp != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); system.m_read_only_components[iii] = comp; } @@ -876,10 +881,10 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ Sys.stringof + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else - assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(comp != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing component \"" ~ comp_info.type ~ "\"."); system.m_writable_components[iii] = comp; } @@ -1155,10 +1160,10 @@ export struct EntityManager ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ Sys.stringof + "Can't register system \"" ~ SystemName ~ "\" due to non existing dependency."); else - assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(comp != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\"."); system.m_readonly_dependencies[iii] = comp; } @@ -1168,15 +1173,15 @@ export struct EntityManager ushort comp = external_dependencies_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ Sys.stringof + "Can't register system \"" ~ SystemName ~ "\" due to non existing dependency."); else - assert(comp != ushort.max, "Can't register system \"" ~ Sys.stringof + assert(comp != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing dependency \"" ~ comp_info.type ~ "\"."); system.m_writable_dependencies[iii] = comp; } - ushort sys_id = systems_map.get(cast(char[]) Sys.stringof, ushort.max); + ushort sys_id = systems_map.get(cast(char[]) SystemName, ushort.max); if (sys_id < systems.length) { systems[sys_id].disable(); @@ -1195,7 +1200,7 @@ export struct EntityManager } else { - system.m_name = Mallocator.makeArray(cast(char[]) Sys.stringof); + system.m_name = Mallocator.makeArray(cast(char[]) SystemName); systems_map.add(system.m_name, cast(ushort) systems.length); @@ -1254,6 +1259,9 @@ export struct EntityManager { ComponentInfo info; + enum ComponentName = fullyQualifiedName!Comp; + //enum ComponentName = Comp.stringof; + static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort)) { static assert(0, "Add \"mixin ECS.Component;\" in top of component structure;"); @@ -1290,7 +1298,7 @@ export struct EntityManager info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof); *cast(Comp*) info.init_data.ptr = Comp.init; // = Comp(); - ushort comp_id = components_map.get(cast(char[]) Comp.stringof, ushort.max); + ushort comp_id = components_map.get(cast(char[]) ComponentName, ushort.max); if (comp_id < components.length) { Comp.component_id = comp_id; @@ -1300,9 +1308,7 @@ export struct EntityManager { components.add(info); Comp.component_id = cast(ushort)(components.length - 1); - char[] name = Mallocator.makeArray(cast(char[]) Comp.stringof); - /*char[] name = Mallocator.makeArray!char(Comp.stringof.length); - name[0..$] = Comp.stringof;*/ + char[] name = Mallocator.makeArray(cast(char[]) ComponentName); components_map.add(name, cast(ushort)(components.length - 1)); } } @@ -1330,7 +1336,8 @@ export struct EntityManager info.size = Ev.sizeof; info.alignment = Ev.alignof; - ushort event_id = events_map.get(Ev.stringof, ushort.max); + //ushort event_id = events_map.get(Ev.stringof, ushort.max); + ushort event_id = events_map.get(fullyQualifiedName!Ev, ushort.max); if (event_id < events.length) { Ev.event_id = event_id; @@ -1339,7 +1346,8 @@ export struct EntityManager { events.add(info); Ev.event_id = cast(ushort)(events.length - 1); - events_map.add(Ev.stringof, cast(ushort)(events.length - 1)); + // events_map.add(Ev.stringof, cast(ushort)(events.length - 1)); + events_map.add(fullyQualifiedName!Ev, cast(ushort)(events.length - 1)); } } @@ -1861,6 +1869,7 @@ export struct EntityManager foreach (i, id; ids) { + if(current_delta == 0)current_delta = ushort.max; alignNum(current_delta, components[id].alignment); info.deltas[id] = cast(ushort) current_delta; current_delta += entites_in_block * components[id].size; From b0b64b965f1989fba39ccf884fa10d2cd4d776ef Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 1 Jul 2020 19:45:53 +0200 Subject: [PATCH 48/58] Demos update -added some new types to gui manager + some fixes -TexCoordsManager now working (probably) -added CRenderDefault components which makes entities without texcoords possible to draw -makes better way of binding demos to launcher -moved some registration related to rendering to one function (basic components + draw system) -added Sandbox demo (demo which takes all demos to one demo) -extends ParticlesDemo play area -added BirckBreaker demo (WIP) -added special material to additive particles -added whole bunch of rendering code to rendering module -added ability to show filtered entities (blinking) --- demos/assets/shaders/additive_particles.fp | 55 +++ demos/assets/shaders/additive_particles.vp | 106 +++++ demos/source/app.d | 93 +++- demos/source/demos/brick_breaker.d | 193 +++++++++ demos/source/demos/particles.d | 45 +- demos/source/demos/sandbox.d | 89 ++++ demos/source/demos/simple.d | 39 +- demos/source/demos/snake.d | 14 + demos/source/demos/space_invaders.d | 40 +- demos/source/game_core/rendering.d | 472 ++++++++++++++++++++- demos/source/gui/component.d | 4 +- demos/source/gui/manager.d | 46 +- 12 files changed, 1122 insertions(+), 74 deletions(-) create mode 100644 demos/assets/shaders/additive_particles.fp create mode 100644 demos/assets/shaders/additive_particles.vp create mode 100644 demos/source/demos/brick_breaker.d create mode 100644 demos/source/demos/sandbox.d diff --git a/demos/assets/shaders/additive_particles.fp b/demos/assets/shaders/additive_particles.fp new file mode 100644 index 0000000..047f647 --- /dev/null +++ b/demos/assets/shaders/additive_particles.fp @@ -0,0 +1,55 @@ +precision mediump int; +precision mediump float; +precision lowp sampler2D; +precision lowp samplerCube; + + +#ifdef GLES + #define TEX(x,y) texture2D(x,y) + #if __VERSION__ >290 + #define M_IN in mediump + #define L_IN in lowp + #else + #define M_IN varying mediump + #define L_IN varying lowp + #endif +#else + #define TEX(x,y) texture(x,y) + #if __VERSION__ > 320 + #define M_IN in + #define L_IN in + #else + #define M_IN varying + #define L_IN varying + #endif +#endif + + +M_IN vec2 uv; +M_IN vec4 color; +/* +#ifdef GLES + #if __VERSION__ >290 + in mediump vec2 uv; + #else + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + in vec2 uv; + #else + varying vec2 uv; + #endif +#endif*/ + +//layout(binding = 0)uniform sampler2D tex; + +uniform sampler2D tex; + +//layout(location = 0) out vec4 outColor; + +void main() +{ + gl_FragColor = /*TEX(tex,uv) **/ color; + if(gl_FragColor.a < 0.01)discard; +} diff --git a/demos/assets/shaders/additive_particles.vp b/demos/assets/shaders/additive_particles.vp new file mode 100644 index 0000000..2777a24 --- /dev/null +++ b/demos/assets/shaders/additive_particles.vp @@ -0,0 +1,106 @@ +precision highp float; +precision highp int; +precision lowp sampler2D; +precision lowp samplerCube; +#ifdef GLES + #if __VERSION__ >290 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out mediump + #define L_OUT out lowp + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying mediump + #define L_OUT varying lowp + #endif +#else + #if __VERSION__ > 320 + #define LOC(x) layout(location = x) + #define ATT in + #define M_OUT out + #define L_OUT out + #else + #define LOC(x) + #define ATT attribute + #define M_OUT varying + #define L_OUT varying + #endif +#endif +/* +#ifdef GLES + #if __VERSION__ >290 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out mediump vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying mediump vec2 uv; + #endif +#else + #if __VERSION__ > 320 + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + layout(location = 0) in vec2 positions; + layout(location = 1) in vec2 tex_coords; + + out vec2 uv; + #else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + + attribute vec2 positions; + attribute vec2 tex_coords; + + varying vec2 uv; + #endif +#endif*/ + +#define VBO_BATCH 1 + +M_OUT vec2 uv; +L_OUT vec4 color; + +LOC(0) ATT vec2 positions; +LOC(1) ATT vec2 tex_coords; + +#ifdef VBO_BATCH + LOC(2) ATT float depth; + LOC(3) ATT vec4 vcolor; +#else + uniform vec4 matrix_1; + uniform vec4 matrix_2; + uniform vec4 uv_transform; + uniform vec4 vcolor; + + float depth = matrix_2.z; +#endif + +void main() { + #ifdef VBO_BATCH + vec3 position = vec3(positions*4.0,1.0); + uv = tex_coords; + #else + vec3 position = mat3(matrix_1.x,matrix_1.y,0,matrix_1.z,matrix_1.w,0,matrix_2.xy,1.0) * vec3(positions,1.0); + uv = tex_coords * uv_transform.zw + uv_transform.xy; + #endif + + color = vcolor; + + gl_Position = vec4(position.xy,depth,1.0); + +} diff --git a/demos/source/app.d b/demos/source/app.d index 6808e42..2310413 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -41,6 +41,15 @@ struct Mouse bool left, right, middle; } +struct DemoCallbacks +{ + void function() initialize; + void function() deinitialize; + bool function() loop; + void function(SDL_Event*) event; + const (char)* tips; +} + struct Launcher { ECSJobUpdater* job_updater; @@ -49,9 +58,9 @@ struct Launcher SDL_Window* window; SDL_GLContext gl_context; EntityManager* manager; - bool function() loop; + /*bool function() loop; void function() end; - void function(SDL_Event*) event; + void function(SDL_Event*) event;*/ //void function(vec2, Tool, int, bool) tool; float scalling; ivec2 window_size = ivec2(1024,768); @@ -74,12 +83,13 @@ struct Launcher bool override_ = true; bool tool_mode = true; ToolCircle* tool_circle; + bool show_filtered; bool swap_interval = true; float windows_alpha = 0.75; - const (char)* tips; + //const (char)* tips; bool show_stat_wnd = true; bool show_tips = true; @@ -99,12 +109,14 @@ struct Launcher float draw_time = 0; } - void switchDemo(void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, const (char)* tips) + DemoCallbacks demo; + + void switchDemo(DemoCallbacks callbacks)//void function() start, bool function() loop, void function() end, void function(SDL_Event*) event, const (char)* tips) { gui_manager.clear(); //launcher.ent - if(this.end)this.end(); + if(this.demo.deinitialize)this.demo.deinitialize(); manager.begin(); manager.update("clean"); @@ -118,14 +130,29 @@ struct Launcher /*launcher.manager.getSystem(CountSystem.system_id).enable(); launcher.manager.getSystem(CleanSystem.system_id).enable();//*/ - if(start)start(); - this.loop = loop; + if(callbacks.initialize)callbacks.initialize(); + demo = callbacks; + /*this.loop = loop; this.end = end; this.event = event; - this.tips = tips; + this.tips = tips;*/ //this.tool = tool; } + bool filterEntity(ref const Entity entity) + { + EntityMeta meta = entity.getMeta(); + foreach(id;gui_manager.filter_list) + { + if(!meta.hasComponent(id))return false; + } + if(used_tool == Tool.component_manipulator) + { + if(!meta.hasComponent(gui_manager.getSelectedComponent().component_id))return false; + } + return true; + } + void processTool(vec2 position, bool mode) { static struct Iterator @@ -361,7 +388,7 @@ void mainLoop(void* arg) while (SDL_PollEvent(&event)) { ImGui_ImplSDL2_ProcessEvent(&event); - if(launcher.event)launcher.event(&event); + if(launcher.demo.event)launcher.demo.event(&event); if (event.type == SDL_QUIT || (event.type == SDL_KEYDOWN && event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) { quit(); *cast(bool*)arg = false; @@ -534,22 +561,32 @@ void mainLoop(void* arg) if(igMenuItemBool("Simpe",null,false,true)) { import demos.simple; - launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); + launcher.switchDemo(getSimpleDemo());//&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); } if(igMenuItemBool("Snake",null,false,true)) { import demos.snake; - launcher.switchDemo(&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,Snake.tips); + launcher.switchDemo(getSnakeDemo());//&snakeStart,&snakeLoop,&snakeEnd,&snakeEvent,Snake.tips); } - if(igMenuItemBool("Space invaders",null,false,true)) + if(igMenuItemBool("Space Invaders",null,false,true)) { import demos.space_invaders; - launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); + launcher.switchDemo(getSpaceInvadersDemo());//&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); } if(igMenuItemBool("Particles",null,false,true)) { import demos.particles; - launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + launcher.switchDemo(getParticlesDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + } + if(igMenuItemBool("Brick Breaker",null,false,true)) + { + import demos.brick_breaker; + launcher.switchDemo(getBrickBreakerDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + } + if(igMenuItemBool("Sandbox",null,false,true)) + { + import demos.sandbox; + launcher.switchDemo(getSanboxDemo());//&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); } igEndMenu(); } @@ -683,7 +720,7 @@ void mainLoop(void* arg) igSetNextWindowBgAlpha(launcher.windows_alpha); if(igBegin("Tips",&launcher.show_tips,ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) { - igTextWrapped(launcher.tips); + igTextWrapped(launcher.demo.tips); } igEnd(); } @@ -726,9 +763,11 @@ void mainLoop(void* arg) if(igIsItemHovered(0))igSetTooltip("Select tool (CTRL + 1,2,3)"); 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) { - igSameLine(0,4); igCheckbox("Override", &launcher.override_); } @@ -823,7 +862,7 @@ void mainLoop(void* arg) double loop_time = launcher.getTime(); launcher.job_updater.pool.tryWaitCount = 10000; - if(launcher.loop && !launcher.loop()) + if(launcher.demo.loop && !launcher.demo.loop()) { quit(); *cast(bool*)arg = false; @@ -1053,6 +1092,8 @@ int app_main(int argc, char** argv) loadGFX(); launcher.renderer.initialize(); + import game_core.rendering : TexCoordsManager; + TexCoordsManager.initialize(); import mmutils.thread_pool : ThreadPool; launcher.threads = ThreadPool.getCPUCoresCount(); @@ -1065,8 +1106,10 @@ int app_main(int argc, char** argv) import demos.space_invaders; import demos.particles; // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); - launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); + // launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); + // launcher.switchDemo(getParticlesDemo()); + launcher.switchDemo(getSimpleDemo()); } int key_num; @@ -1094,6 +1137,7 @@ int app_main(int argc, char** argv) } } + TexCoordsManager.destroy(); EntityManager.destroy(); return 0; @@ -1198,13 +1242,22 @@ void loadGFX() + + Shader vsh3; + vsh3.create(); + vsh3.load("assets/shaders/additive_particles.vp"); + vsh3.compile(); + Shader fsh3; + fsh3.create(); + fsh3.load("assets/shaders/additive_particles.fp"); + fsh3.compile(); GfxConfig.materials[2].create(); GfxConfig.materials[2].data.blend_mode = Material.BlendMode.opaque; GfxConfig.materials[2].data.mode = Material.TransformMode.position; - //Material.ShaderModule[1] modules = [Material.ShaderModule(vsh,fsh)]; - GfxConfig.materials[2].attachModules(modules); + Material.ShaderModule[1] modules3 = [Material.ShaderModule(vsh3,fsh3)]; + GfxConfig.materials[2].attachModules(modules3); //GfxConfig.materials[0]. //GfxConfig.materials[0].load(load_data.materials[i].str); GfxConfig.materials[2].compile(); diff --git a/demos/source/demos/brick_breaker.d b/demos/source/demos/brick_breaker.d new file mode 100644 index 0000000..1af22b9 --- /dev/null +++ b/demos/source/demos/brick_breaker.d @@ -0,0 +1,193 @@ +module demos.brick_breaker; + +import app; + +import bindbc.sdl; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.entity; +import bubel.ecs.manager; +import bubel.ecs.std; + +import cimgui.cimgui; + +import ecs_utils.gfx.texture; +import ecs_utils.math.vector; +import ecs_utils.utils; + +import game_core.basic; +import game_core.rendering; + +extern(C): + +/*####################################################################################################################### +------------------------------------------------ Components ------------------------------------------------------------------ +#######################################################################################################################*/ + +/*struct CLocation +{ + mixin ECS.Component; + + alias location this; + + vec2 location; +}*/ + +struct CBrick +{ + mixin ECS.Component; +} + +struct CPaddle +{ + mixin ECS.Component; +} + +struct CBall +{ + mixin ECS.Component; + + ubyte radius; +} + +struct CVelocity +{ + mixin ECS.Component; + + alias value this; + + vec2 value; +} + +/*####################################################################################################################### +------------------------------------------------ Systems ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct MoveSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CLocation[] location; + @readonly CVelocity[] velocity; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.location[i] += data.velocity[i] * launcher.delta_time; + } + } +} + +struct BallCollisionSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CLocation[] location; + CVelocity[] velocity; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + + } + } +} + +/*####################################################################################################################### +------------------------------------------------ Functions ------------------------------------------------------------------ +#######################################################################################################################*/ + +struct BrickBreakerDemo +{ + __gshared const (char)* tips = "Brick breaker demo. It's a game about destroying evil bricks."; + + EntityTemplate* tmpl; + Texture texture; +} + +__gshared BrickBreakerDemo* demo; + +void brickBreakerStart() +{ + demo = Mallocator.make!BrickBreakerDemo; + + launcher.manager.beginRegister(); + + registerRenderingModule(launcher.manager); + + launcher.manager.registerComponent!CLocation; + launcher.manager.registerComponent!CRotation; + launcher.manager.registerComponent!CScale; + launcher.manager.registerComponent!CTexCoords; + launcher.manager.registerComponent!CTexCoordsIndex; + launcher.manager.registerComponent!CVelocity; + + launcher.manager.registerSystem!MoveSystem(-100); + launcher.manager.registerSystem!BallCollisionSystem(-99); + + launcher.manager.endRegister(); + + demo.texture.create(); + demo.texture.load("assets/textures/atlas.png"); + + launcher.manager.beginRegister(); + + launcher.manager.registerComponent!CLocation; + + launcher.manager.endRegister(); +} + +void brickBreakerEnd() +{ + launcher.manager.getSystem(MoveSystem.system_id).disable(); + launcher.manager.getSystem(DrawSystem.system_id).disable(); + + demo.texture.destroy(); + + Mallocator.dispose(demo); +} + +void brickBreakerEvent(SDL_Event* event) +{ +} + +bool brickBreakerLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + launcher.manager.begin(); + if(launcher.multithreading) + { + launcher.job_updater.begin(); + launcher.manager.updateMT(); + launcher.job_updater.call(); + } + else + { + launcher.manager.update(); + } + launcher.manager.end(); + + return true; +} + +DemoCallbacks getBrickBreakerDemo() +{ + DemoCallbacks demo; + demo.initialize = &brickBreakerStart; + demo.deinitialize = &brickBreakerEnd; + demo.loop = &brickBreakerLoop; + demo.tips = .demo.tips; + return demo; +} \ No newline at end of file diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d index 2242ecf..8dac7ff 100644 --- a/demos/source/demos/particles.d +++ b/demos/source/demos/particles.d @@ -17,6 +17,7 @@ import ecs_utils.math.vector; import ecs_utils.utils; import game_core.basic; +import game_core.rendering; import gui.attributes; @@ -115,7 +116,7 @@ struct CParticleLife /*####################################################################################################################### ------------------------------------------------ Systems ------------------------------------------------------------------ #######################################################################################################################*/ - +/* struct DrawSystem { mixin ECS.System!32; @@ -162,7 +163,7 @@ struct DrawSystem } } -} +}*/ struct MoveSystem { @@ -338,10 +339,10 @@ struct PlayAreaSystem { foreach(i; 0..data.length) { - if(data.locations[i].x > 400)launcher.manager.removeEntity(data.entity[i].id); - else if(data.locations[i].x < 0)launcher.manager.removeEntity(data.entity[i].id); - if(data.locations[i].y > 300)launcher.manager.removeEntity(data.entity[i].id); - else if(data.locations[i].y < 0)launcher.manager.removeEntity(data.entity[i].id); + if(data.locations[i].x > 440)launcher.manager.removeEntity(data.entity[i].id); + else if(data.locations[i].x < -40)launcher.manager.removeEntity(data.entity[i].id); + if(data.locations[i].y > 340)launcher.manager.removeEntity(data.entity[i].id); + else if(data.locations[i].y < -40)launcher.manager.removeEntity(data.entity[i].id); } } } @@ -452,16 +453,24 @@ void particlesStart() launcher.manager.beginRegister(); + registerRenderingModule(launcher.manager); + launcher.manager.registerComponent!CLocation; //launcher.manager.registerComponent!CTexCoords; launcher.manager.registerComponent!CColor; launcher.manager.registerComponent!CVelocity; + launcher.manager.registerComponent!CScale; + launcher.manager.registerComponent!CTexCoords; + launcher.manager.registerComponent!CTexCoordsIndex; + launcher.manager.registerComponent!CRotation; + launcher.manager.registerComponent!CDepth; launcher.manager.registerComponent!CAttractor; launcher.manager.registerComponent!CDamping; launcher.manager.registerComponent!CGravity; launcher.manager.registerComponent!CVortex; launcher.manager.registerComponent!CParticleLife; launcher.manager.registerComponent!CForceRange; + launcher.manager.registerComponent!CMaterialIndex; launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); @@ -476,6 +485,12 @@ void particlesStart() launcher.manager.endRegister(); + DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; + draw_system.default_data.size = vec2(2,2); + draw_system.default_data.coords = vec4(246,64,2,2)*px; + draw_system.default_data.material_id = 2; + draw_system.default_data.texture = particles_demo.texture; + launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System"); launcher.gui_manager.addSystem(PlayAreaSystem.system_id,"Play Area System"); @@ -498,8 +513,11 @@ void particlesStart() launcher.gui_manager.addComponent(CGravity(),"Gravity"); EntityTemplate* tmpl; - EntityTemplate* base_tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CColor.component_id, CVelocity.component_id, CDamping.component_id].staticArray); + EntityTemplate* base_tmpl = launcher.manager.allocateTemplate([CTexCoords.component_id, CLocation.component_id, CColor.component_id, CVelocity.component_id, CDamping.component_id, CScale.component_id, CMaterialIndex.component_id].staticArray); base_tmpl.getComponent!CColor().value = 0xFF251010; + base_tmpl.getComponent!CScale().value = vec2(2); + base_tmpl.getComponent!CTexCoords().value = vec4(246,64,2,2)*px; + base_tmpl.getComponent!CMaterialIndex().value = 2; launcher.gui_manager.addTemplate(base_tmpl,"Particle"); // tmpl = launcher.manager.allocateTemplate(base_tmpl); // tmpl.getComponent!CColor().value = 0xFF251010; @@ -515,7 +533,8 @@ void particlesStart() // tmpl = launcher.manager.allocateTemplate(tmpl); // tmpl.getComponent!CDamping().power = 4; // launcher.gui_manager.addTemplate(tmpl,"Particle (damping!)"); - tmpl = launcher.manager.allocateTemplate([CAttractor.component_id, CLocation.component_id, CForceRange.component_id].staticArray); + tmpl = launcher.manager.allocateTemplate([CAttractor.component_id, CLocation.component_id, CForceRange.component_id, CScale.component_id].staticArray); + tmpl.getComponent!CScale().value = vec2(4); launcher.gui_manager.addTemplate(tmpl,"Attractor"); tmpl = launcher.manager.allocateTemplate(tmpl, [CVortex.component_id].staticArray); launcher.gui_manager.addTemplate(tmpl,"Vortex"); @@ -555,4 +574,14 @@ bool particlesLoop() launcher.manager.end(); return true; +} + +DemoCallbacks getParticlesDemo() +{ + DemoCallbacks demo; + demo.initialize = &particlesStart; + demo.deinitialize = &particlesEnd; + demo.loop = &particlesLoop; + demo.tips = ParticlesDemo.tips; + return demo; } \ No newline at end of file diff --git a/demos/source/demos/sandbox.d b/demos/source/demos/sandbox.d new file mode 100644 index 0000000..69a2ef2 --- /dev/null +++ b/demos/source/demos/sandbox.d @@ -0,0 +1,89 @@ +module demos.sandbox; + +import bindbc.sdl; + +import demos.simple; +import demos.snake; +import demos.space_invaders; +import demos.particles; + +import game_core.rendering; + +import app; + +import ecs_utils.math.vector; + +extern(C): + +void sandboxStart() +{ + simpleStart(); + snakeStart(); + spaceInvadersStart(); + particlesStart(); + + DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; + draw_system.default_data.size = vec2(16,16); + draw_system.default_data.coords = vec4(0,48,16,16)*demos.simple.px; + draw_system.default_data.material_id = 0; + draw_system.default_data.texture = particles_demo.texture; + draw_system.default_data.color = 0x80808080; +} + +void sandboxEnd() +{ + simpleEnd(); + snakeEnd(); + spaceInvadersEnd(); + particlesEnd(); +} +/* +void sandboxEvent(SDL_Event* event) +{ +}*/ + +bool sandboxLoop() +{ + launcher.render_position = (vec2(launcher.window_size.x,launcher.window_size.y)*launcher.scalling - vec2(400,300)) * 0.5; + + launcher.manager.begin(); + + float delta_time = launcher.delta_time; + if(delta_time > 2000)delta_time = 2000; + __gshared float time = 0; + + /*if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3; + else */ + time += delta_time; + + while(time > 100) + { + time -= 100; + + launcher.manager.update("fixed"); + } + + if(launcher.multithreading) + { + launcher.job_updater.begin(); + launcher.manager.updateMT(); + launcher.job_updater.call(); + } + else + { + launcher.manager.update(); + } + launcher.manager.end(); + + return true; +} + +DemoCallbacks getSanboxDemo() +{ + DemoCallbacks demo; + demo.initialize = &sandboxStart; + demo.deinitialize = &sandboxEnd; + demo.loop = &sandboxLoop; + demo.tips = "tips"; + return demo; +} \ No newline at end of file diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 6876e4f..1aafcb2 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -17,9 +17,12 @@ import ecs_utils.math.vector; import ecs_utils.utils; import game_core.basic; +import game_core.rendering; extern(C): +enum float px = 1.0/512.0; + /*####################################################################################################################### ------------------------------------------------ Components ------------------------------------------------------------------ #######################################################################################################################*/ @@ -36,7 +39,7 @@ extern(C): /*####################################################################################################################### ------------------------------------------------ Systems ------------------------------------------------------------------ #######################################################################################################################*/ - +/* struct DrawSystem { mixin ECS.System!32; @@ -66,13 +69,9 @@ struct DrawSystem draw_data.position = data.locations[i]; draw_data.depth = cast(ushort)(data.locations[i].y); launcher.renderer.draw(draw_data); - //launcher.renderer.draw(simple.texture, data.locations[i], vec2(16,16), vec4(0,0,1,1), cast(ushort)(data.locations[i].y), 0x80808080, 0, 0, 0, data.job_id); - // launcher.renderer.draw(data.textures[i].tex, data.locations[i].location, vec2(16,16), vec4(0,0,1,1), 0, 0x80808080, 0, 0, 0, data.job_id); - //draw(renderer, data.textures[i].tex, data.locations[i], vec2(32,32), vec4(0,0,1,1)); } - //if(data.thread_id == 0)launcher.renderer.pushData(); } -} +}*/ struct MoveSystem { @@ -113,22 +112,30 @@ void simpleStart() simple = Mallocator.make!Simple; simple.texture.create(); - simple.texture.load("assets/textures/buckler.png"); + simple.texture.load("assets/textures/atlas.png"); launcher.manager.beginRegister(); + registerRenderingModule(launcher.manager); + launcher.manager.registerComponent!CLocation; launcher.manager.registerSystem!MoveSystem(0); - launcher.manager.registerSystem!DrawSystem(1); + // launcher.manager.registerSystem!DrawSystem(1); launcher.manager.endRegister(); + + DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; + draw_system.default_data.color = 0x80808080; + draw_system.default_data.texture = simple.texture; + draw_system.default_data.size = vec2(16,16); + draw_system.default_data.coords = vec4(0,48,16,16)*px;//vec4(0,0,1,1); - launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); + launcher.gui_manager.addSystem(MoveSystem.system_id,"Move Up System"); launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System"); - ushort[1] components = [CLocation.component_id]; - simple.tmpl = launcher.manager.allocateTemplate(components); + simple.tmpl = launcher.manager.allocateTemplate([CLocation.component_id, CDrawDefault.component_id].staticArray); + //*simple.tmpl.getComponent!CTexCoordsIndex = TexCoordsManager.instance.getCoordIndex(vec4(0,48,16,16)*px); //CLocation* loc_comp = simple.tmpl.getComponent!CLocation; launcher.gui_manager.addTemplate(simple.tmpl, "Basic"); @@ -186,4 +193,14 @@ bool simpleLoop() launcher.manager.end(); return true; +} + +DemoCallbacks getSimpleDemo() +{ + DemoCallbacks demo; + demo.initialize = &simpleStart; + demo.deinitialize = &simpleEnd; + demo.loop = &simpleLoop; + demo.tips = simple.tips; + return demo; } \ No newline at end of file diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index c42f690..8ff0be6 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -851,6 +851,8 @@ __gshared Snake* snake; void snakeStart() { + import game_core.rendering; + snake = Mallocator.make!Snake; snake.texture.create(); @@ -860,6 +862,8 @@ void snakeStart() launcher.manager.registerPass("fixed"); + registerRenderingModule(launcher.manager); + launcher.manager.registerComponent!CLocation; launcher.manager.registerComponent!CILocation; launcher.manager.registerComponent!CSnake; @@ -983,4 +987,14 @@ bool snakeLoop() launcher.manager.end(); return true; +} + +DemoCallbacks getSnakeDemo() +{ + DemoCallbacks demo; + demo.initialize = &snakeStart; + demo.deinitialize = &snakeEnd; + demo.loop = &snakeLoop; + demo.tips = snake.tips; + return demo; } \ No newline at end of file diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 311feb3..b249fc1 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -401,8 +401,8 @@ struct CParticleEmitter { mixin ECS.Component; - vec2 range; - vec2 time_range; + vec2 range = vec2(0,0); + vec2 time_range = vec2(500,1000); ///due to multithreading there should be separate template for every thread. ///It can be array of tempaltes or (like in this demo) simply index of template; uint tmpl_id; @@ -829,7 +829,7 @@ struct ShipWeaponSystem void create() { tower1_tmpl = launcher.manager.allocateTemplate( - [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, + [CColor.component_id, CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, CChildren.component_id, CDepth.component_id, CTargetParent.component_id, @@ -959,7 +959,7 @@ struct MoveToParentTargetSystem } } } - +/* struct DrawSystem { mixin ECS.System!32; @@ -1088,7 +1088,7 @@ struct DrawSystem } //if(data.thread_id == 0)launcher.renderer.pushData(); } -} +}*/ struct CollisionSystem { @@ -1325,7 +1325,7 @@ struct BulletsCollisionSystem uint length; const (Entity)[] entity; @readonly CLocation[] location; - @readonly CBullet[] laser; + @readonly CBullet[] bullet; @readonly CGuild[] guild; } @@ -1336,7 +1336,7 @@ struct BulletsCollisionSystem { if(space_invaders.shoot_grid.test(id, data.location[i], cast(ubyte)(~(1 << data.guild[i].guild)))) { - launcher.manager.sendEvent(id, EBulletHit(data.entity[i].id,1)); + launcher.manager.sendEvent(id, EBulletHit(data.entity[i].id,data.bullet[i].damage)); //launcher.manager.removeEntity(data.entity[i].id); } } @@ -1631,6 +1631,7 @@ struct HitMarkingSystem { uint length; CHitMark[] mark; + CColor[] color; } void onUpdate(EntitiesData data) @@ -1640,6 +1641,7 @@ struct HitMarkingSystem //if(data.mark[i] < 10)data.mark[i] = 0; //else data.mark[i] -= 1; data.mark[i] = cast(ubyte)(data.mark[i] * 0.9); + data.color[i] = 0x80808080 + 0x01010101 * data.mark[i]; } } } @@ -2339,6 +2341,8 @@ void spaceInvadersStart() launcher.manager.registerDependency(ShootGridDependency); + registerRenderingModule(launcher.manager); + launcher.manager.registerComponent!CLocation; launcher.manager.registerComponent!CTexCoords; //launcher.manager.registerComponent!CTexture; @@ -2416,6 +2420,10 @@ void spaceInvadersStart() launcher.manager.endRegister(); + DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; + draw_system.default_data.color = 0x80808080; + draw_system.default_data.texture = space_invaders.texture; + launcher.gui_manager.addComponent(CInput(),"Input"); launcher.gui_manager.addComponent(CShip(),"Ship"); launcher.gui_manager.addComponent(CEnemy(),"Enemy"); @@ -2482,7 +2490,7 @@ void spaceInvadersStart() //launcher.manager.getSystem(CleanSystem.system_id).disable(); { space_invaders.ship_tmpl = launcher.manager.allocateTemplate( - [CVelocity.component_id, CHitMark.component_id, CHitPoints.component_id, + [CVelocity.component_id, CColor.component_id, CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexCoords.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CColliderScale.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id, @@ -2517,7 +2525,7 @@ void spaceInvadersStart() { boss_tmpl = launcher.manager.allocateTemplate( - [CHitMark.component_id, CParts.component_id, CLocation.component_id, + [CColor.component_id, CHitMark.component_id, CParts.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CBoss.component_id, CGuild.component_id, CInit.component_id, CChildren.component_id, CSideMove.component_id, CVelocity.component_id, @@ -2540,7 +2548,7 @@ void spaceInvadersStart() { tower_tmpl = launcher.manager.allocateTemplate( - [CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, + [CColor.component_id, CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, CChildren.component_id].staticArray @@ -2554,7 +2562,7 @@ void spaceInvadersStart() { space_invaders.enemy_tmpl = launcher.manager.allocateTemplate( - [CWeaponLocation.component_id, CHitMark.component_id, CHitPoints.component_id, + [CWeaponLocation.component_id, CColor.component_id, CHitMark.component_id, CHitPoints.component_id, CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, @@ -2733,4 +2741,14 @@ bool spaceInvadersLoop() }*/ return true; +} + +DemoCallbacks getSpaceInvadersDemo() +{ + DemoCallbacks demo; + demo.initialize = &spaceInvadersStart; + demo.deinitialize = &spaceInvadersEnd; + demo.loop = &spaceInvadersLoop; + demo.tips = space_invaders.tips; + return demo; } \ No newline at end of file diff --git a/demos/source/game_core/rendering.d b/demos/source/game_core/rendering.d index de5f0b5..bee9367 100644 --- a/demos/source/game_core/rendering.d +++ b/demos/source/game_core/rendering.d @@ -1,13 +1,30 @@ module game_core.rendering; -import bubel.ecs.core; import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.std; -import ecs_utils.math.vector; import ecs_utils.gfx.texture; +import ecs_utils.math.vector; import game_core.basic; +void registerRenderingModule(EntityManager* manager) +{ + manager.registerComponent!CLocation; + manager.registerComponent!CScale; + manager.registerComponent!CRotation; + manager.registerComponent!CDepth; + manager.registerComponent!CColor; + manager.registerComponent!CSelected; + manager.registerComponent!CTexCoords; + manager.registerComponent!CTexCoordsIndex; + manager.registerComponent!CMaterialIndex; + manager.registerComponent!CDrawDefault; + + manager.registerSystem!DrawSystem(100); +} + struct CTexCoords { mixin ECS.Component; @@ -19,16 +36,63 @@ struct CTexCoords struct CTexCoordsIndex { - mixin ECS.Component; + mixin ECS.Component; + + alias value this; ushort value; } +struct CMaterialIndex +{ + mixin ECS.Component; + + alias value this; + + ushort value; +} + +struct CDrawDefault +{ + mixin ECS.Component; +} + struct TexCoordsManager { import bubel.ecs.vector; import bubel.ecs.hash_map; + __gshared TexCoordsManager* instance = null; + + static void initialize() + { + if(instance is null)instance = Mallocator.make!TexCoordsManager; + } + + static void destroy() + { + if(instance)Mallocator.dispose(instance); + instance = null; + } + + vec4 get(ushort index) + { + if(index > coords.length)return vec4(0,0,1,1); + else return coords[index]; + } + + ushort getCoordIndex(vec4 coords) + { + ushort ret = coords_map.get(coords, ushort.max); + if(ret != ushort.max) + { + return ret; + } + this.coords.add(coords); + coords_map.add(coords, cast(ushort)(this.coords.length - 1)); + return cast(ushort)(this.coords.length - 1); + } + Vector!vec4 coords; HashMap!(vec4,ushort) coords_map; } @@ -44,17 +108,34 @@ struct DrawSystem uint length; //uint thread_id; uint job_id; + const(Entity)[] entity; @readonly CLocation[] locations; - @readonly CScale[] scale; - @readonly CTexCoords[] texcoord; - // @readonly @optional CTexCoords[] texcoord; - // @readonly @optional CTexCoordsIndex[] texcoord_index; + @readonly @optional CScale[] scale; + // @readonly CTexCoords[] texcoord; + @readonly @optional CTexCoords[] texcoord; + @readonly @optional CTexCoordsIndex[] texcoord_index; @readonly @optional CRotation[] rotation; @readonly @optional CDepth[] depth; @readonly @optional CColor[] color; + @readonly @optional CMaterialIndex[] material; + @readonly @optional CDrawDefault[] draw_default; } Renderer.DrawData default_data; + float color_time = 0; + uint select_color = 0; + + bool onBegin() + { + import app : launcher; + color_time += launcher.delta_time * 0.001; + color_time = color_time - cast(int)(color_time*0.5)*2; + float ratio = color_time - cast(int)color_time; + if(color_time > 1)ratio = 1 - ratio; + uint multipler = cast(uint)(0x60 * ratio); + select_color = 0xA0A0A0A0 + cast(uint)(0x01010101 * multipler); + return true; + } void onUpdate(EntitiesData data) { @@ -63,10 +144,368 @@ struct DrawSystem if(launcher.renderer.prepared_items >= launcher.renderer.MaxObjects)return;//simple leave loop if max visible objects count was reached Renderer.DrawData draw_data = default_data; draw_data.thread_id = data.job_id; - - if(!data.depth) + + if(launcher.show_filtered && launcher.filterEntity(data.entity[0])) { - if(!data.color) + draw_data.color = select_color; + data.color = null; + } + //import std.stdio; + //writeln(data.draw_default); + //if(data.draw_default is null && data.texcoord is null && data.texcoord_index is null && !data.entity[0].hasComponent(CDrawDefault.component_id))return; + + if(data.texcoord is null && data.texcoord_index is null && data.draw_default is null)return; + + + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + if(data.color)draw_data.color = data.color[i]; + if(data.depth)draw_data.depth = data.depth[i]; + if(data.rotation)draw_data.angle = data.rotation[i]; + if(data.scale)draw_data.size = data.scale[i]; + if(data.texcoord)draw_data.coords = data.texcoord[i]; + else if(data.texcoord_index)draw_data.coords = TexCoordsManager.instance.get(data.texcoord_index[i]); + if(data.material)draw_data.material_id = data.material[i]; + launcher.renderer.draw(draw_data); + }//*/ + + /* + ubyte mode; + if(data.scale)mode |= 0x01; + if(data.texcoord)mode |= 0x02; + if(data.texcoord_index)mode |= 0x04; + if(data.rotation)mode |= 0x08; + if(data.depth)mode |= 0x10; + if(data.color)mode |= 0x20; + + if(launcher.show_filtered && launcher.filterEntity(data.entity[0])) + { + draw_data.color = select_color; + mode &= ~0x20; + //goto draw_nocolor; + } + + switch(mode) + { + case 0: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + launcher.renderer.draw(draw_data); + } + break; + + case 0b000001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + + case 0b000010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b000011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + + case 0b001000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b001001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b001010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b001011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + + + case 0b010000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b010001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b010010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b010011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b011011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + + + case 0b100000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b100001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b100010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b100011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b101011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b110011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111000: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111001: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111010: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + case 0b111011: + foreach(i; 0..data.length) + { + draw_data.position = data.locations[i]; + draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; + draw_data.angle = data.rotation[i]; + draw_data.size = data.scale[i]; + draw_data.coords = data.texcoord[i]; + launcher.renderer.draw(draw_data); + } + break; + default:break; + }//*/ +/* + if(!data.color) + { + draw_nocolor: + if(!data.depth) { if(!data.rotation) { @@ -96,7 +535,7 @@ struct DrawSystem { foreach(i; 0..data.length) { - draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; draw_data.coords = data.texcoord[i]; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; @@ -107,7 +546,7 @@ struct DrawSystem { foreach(i; 0..data.length) { - draw_data.color = data.color[i]; + draw_data.depth = data.depth[i]; draw_data.angle = data.rotation[i]; draw_data.coords = data.texcoord[i]; draw_data.size = data.scale[i]; @@ -119,13 +558,13 @@ struct DrawSystem } else { - if(!data.color) + if(!data.depth) { if(!data.rotation) { foreach(i; 0..data.length) { - draw_data.depth = data.depth[i]; + draw_data.color = data.color[i]; draw_data.coords = data.texcoord[i]; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; @@ -136,7 +575,7 @@ struct DrawSystem { foreach(i; 0..data.length) { - draw_data.depth = data.depth[i]; + draw_data.color = data.color[i]; draw_data.angle = data.rotation[i]; draw_data.coords = data.texcoord[i]; draw_data.size = data.scale[i]; @@ -165,7 +604,6 @@ struct DrawSystem { draw_data.depth = data.depth[i]; draw_data.color = data.color[i]; - draw_data.angle = data.rotation[i]; draw_data.coords = data.texcoord[i]; draw_data.size = data.scale[i]; draw_data.position = data.locations[i]; @@ -173,6 +611,6 @@ struct DrawSystem } } } - } + }*/ } } \ No newline at end of file diff --git a/demos/source/gui/component.d b/demos/source/gui/component.d index b19f069..e65dee4 100644 --- a/demos/source/gui/component.d +++ b/demos/source/gui/component.d @@ -47,7 +47,9 @@ struct VariableGUI enum_, color, vec2, - ivec2 + ivec2, + vec4, + ivec4 } Type type; const (char)* name; diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index 3f6e6cb..3745d9d 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -93,9 +93,13 @@ struct GUIManager void addSystem(ushort id, const (char)* name, bool enabled = true) { + foreach(ref sys; systems) + { + if(sys.id == id)return; + } System* system = launcher.manager.getSystem(id); //const (char)* name = - systems.add(SystemGUI(name,system,enabled)); + systems.add(SystemGUI(name,id,enabled)); } void addTemplate(ushort[] components, const (char)* name) @@ -143,7 +147,23 @@ struct GUIManager //pragma(msg,member_type); //pragma(msg,__traits(getMember, T, member).offsetof); ushort offset = member.offsetof;//cast(ushort)__traits(getMember, T, member).offsetof; - static if(__traits(isIntegral,member_type)) + static if(is(member_type == vec2)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec2,member_str,offset); + } + else static if(is(member_type == ivec2)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ivec2,member_str,offset); + } + else static if(is(member_type == vec4)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.vec4,member_str,offset); + } + else static if(is(member_type == ivec4)) + { + comp_edit.variables[comp_edit.used++] = VariableGUI(VariableGUI.Type.ivec4,member_str,offset); + } + else static if(__traits(isIntegral,member_type)) { static if(__traits(isUnsigned, member_type)) { @@ -227,14 +247,15 @@ struct GUIManager { if(igCollapsingHeader("Systems", ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_DefaultOpen)) { - bool true_ = true; + //bool true_ = true; igIndent(8); foreach(ref SystemGUI system;systems) { if(igCheckbox(system.name,&system.enabled)) { - if(system.enabled)system.system.enable(); - else system.system.disable(); + System* sys = launcher.manager.getSystem(system.id); + if(system.enabled)sys.enable(); + else sys.disable(); } } igUnindent(8); @@ -347,6 +368,18 @@ struct GUIManager if(igColorEdit4(var.name, color.data, ImGuiColorEditFlags_None)) *cast(uint*)(data_ptr+var.offset) = colorVec4ToUint(color); break; + case VariableGUI.Type.vec2: + igDragFloat2(var.name, (cast(float*)(data_ptr+var.offset))[0..2], 0.1, -float.max, float.max, null, 1); + break; + case VariableGUI.Type.ivec2: + igDragInt2(var.name, (cast(int*)(data_ptr+var.offset))[0..2], 0.1, int.min, int.max, null); + break; + case VariableGUI.Type.vec4: + igDragFloat4(var.name, (cast(float*)(data_ptr+var.offset))[0..4], 0.1, -float.max, float.max, null, 1); + break; + case VariableGUI.Type.ivec4: + igDragInt4(var.name, (cast(int*)(data_ptr+var.offset))[0..4], 0.1, int.min, int.max, null); + break; default:break; } igPopID(); @@ -359,6 +392,7 @@ struct GUIManager void entityComponentsGUI() { + if(selected_template >= templates.length)return; EntityTemplate* tmpl = templates[selected_template].tmpl; EntityManager.EntityInfo* info = tmpl.info; foreach(comp_id; info.components) @@ -416,7 +450,7 @@ struct GUIManager if(igIsItemHovered(0))igSetTooltip("Select component to add/remove (SHIFT + Scroll)"); } style.Colors[ImGuiCol_Header] = col; - componentGUI(components[selected_component].component_id, components[selected_component].data); + if(selected_component < components.length)componentGUI(components[selected_component].component_id, components[selected_component].data); break; case Tool.selector: break; From a0efa4e67d0df98bfbbba48fcf857b6bb1f4b78e Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 8 Jul 2020 22:04:13 +0200 Subject: [PATCH 49/58] Fixed unittests and betterC compilation (after adding fullyQualifiedName instead of simple stringof) -added new trait to get full name of structure (witho module and package, not tested on more nested packages) -some small improvements (like adding const to function which need it) --- dub.json | 3 ++- source/bubel/ecs/entity.d | 6 +++--- source/bubel/ecs/manager.d | 23 ++++++++++++++--------- source/bubel/ecs/traits.d | 32 ++++++++++++++++++++++++++++++++ tests/basic.d | 4 ++-- 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/dub.json b/dub.json index 01cf85c..ba935ee 100755 --- a/dub.json +++ b/dub.json @@ -118,7 +118,8 @@ "-unittest" ], "dflags-gdc": [ - "-fno-druntime" + "-fno-druntime", + "-lpthread" ], "sourcePaths": ["source/","tests/"], "mainSourceFile":"tests/runner.d", diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index 2c64c60..4cd0e70 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -42,7 +42,7 @@ struct Entity return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof); } - bool hasComponent(ushort component_id) + bool hasComponent(ushort component_id) const { EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); EntityManager.EntityInfo* info = block.type_info; @@ -72,9 +72,9 @@ struct EntityMeta return cast(T*)(cast(void*)block + block.type_info.deltas[T.component_id] + index * T.sizeof); } - bool hasComponent(ushort component_id) + bool hasComponent(ushort component_id) const { - EntityManager.EntityInfo* info = block.type_info; + const EntityManager.EntityInfo* info = block.type_info; if (component_id >= info.deltas.length || info.deltas[component_id] == 0)return false; return true; } diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index cce03c6..7fb79f8 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -382,7 +382,8 @@ export struct EntityManager else assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist."); - enum SystemName = fullyQualifiedName!Sys; + // enum SystemName = fullyQualifiedName!Sys; + enum SystemName = fullName!Sys; //enum SystemName = Sys.stringof; System system; @@ -421,7 +422,8 @@ export struct EntityManager static if (Params.length == 2 && is(Params[0] == Entity*)) { alias EventParamType = Params[1]; - enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof; + enum EventName = fullName!(Unqual!(EventParamType)); + // enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof; ushort evt = events_map.get(cast(char[]) EventName, ushort.max); assert(evt != ushort.max, "Can't register system \"" ~ SystemName ~ "\" due to non existing event \"" ~ EventName ~ "\"."); @@ -482,7 +484,8 @@ export struct EntityManager string name; static if (isArray!MemberType) { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));//.stringof; + // name = fullyQualifiedName!(Unqual!(ForeachType!MemberType));//.stringof; + name = fullName!(Unqual!(ForeachType!MemberType)); } bool is_optional; @@ -707,7 +710,8 @@ export struct EntityManager string name; static if (isArray!MemberType) { // Workaround. This code is never called with: not an array type, but compiler prints an error - name = fullyQualifiedName!(Unqual!(ForeachType!MemberType)); + // name = fullyQualifiedName!(Unqual!(ForeachType!MemberType)); + name = fullName!(Unqual!(ForeachType!MemberType)); //name = Unqual!(ForeachType!MemberType).stringof; } @@ -763,7 +767,7 @@ export struct EntityManager { foreach (str; Sys.ExcludedComponents) { - components_info.addExcluded(CompInfo(str.stringof, fullyQualifiedName!str)); + components_info.addExcluded(CompInfo(str.stringof, fullName!str)); // components_info.addExcluded(CompInfo(str.stringof, str.stringof)); } @@ -1259,8 +1263,9 @@ export struct EntityManager { ComponentInfo info; - enum ComponentName = fullyQualifiedName!Comp; - //enum ComponentName = Comp.stringof; + // enum ComponentName = fullyQualifiedName!Comp; + enum ComponentName = fullName!Comp; + // enum ComponentName = Comp.stringof; static if (!(hasMember!(Comp, "component_id")) || !is(typeof(Comp.component_id) == ushort)) { @@ -1337,7 +1342,7 @@ export struct EntityManager info.alignment = Ev.alignof; //ushort event_id = events_map.get(Ev.stringof, ushort.max); - ushort event_id = events_map.get(fullyQualifiedName!Ev, ushort.max); + ushort event_id = events_map.get(fullName!Ev, ushort.max); if (event_id < events.length) { Ev.event_id = event_id; @@ -1347,7 +1352,7 @@ export struct EntityManager events.add(info); Ev.event_id = cast(ushort)(events.length - 1); // events_map.add(Ev.stringof, cast(ushort)(events.length - 1)); - events_map.add(fullyQualifiedName!Ev, cast(ushort)(events.length - 1)); + events_map.add(fullName!Ev, cast(ushort)(events.length - 1)); } } diff --git a/source/bubel/ecs/traits.d b/source/bubel/ecs/traits.d index 7043b2e..8214b01 100644 --- a/source/bubel/ecs/traits.d +++ b/source/bubel/ecs/traits.d @@ -37,3 +37,35 @@ static long getIndexOfTypeInEntitiesData(EntitiesData, Type)() } return index; } + +static string attachParentName(alias T, string str)() +{ + alias parent = __traits(parent, T); + enum parent_str = parent.stringof; + static if(parent_str[0..7] == "module ") + { + static if(__traits(compiles, __traits(parent, parent))) + { + return attachParentName!(parent, parent_str[7 .. $] ~ '.' ~ str); + } + else return parent_str[8 .. $] ~ '.' ~ str; + } + else static if(parent_str[0..8] == "package ") + { + static if(__traits(compiles, __traits(parent, parent))) + { + return attachParentName!(parent, parent_str[8 .. $] ~ '.' ~ str); + } + else return parent_str[8 .. $] ~ '.' ~ str; + } + else static if(__traits(compiles, __traits(parent, parent))) + { + return attachParentName!(parent, parent_str ~ '.' ~ str); + } + else return parent_str ~ '.' ~ str; +} + +static string fullName(T)() +{ + return attachParentName!(T, T.stringof); +} \ No newline at end of file diff --git a/tests/basic.d b/tests/basic.d index 5830a7b..59f88e2 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -401,7 +401,7 @@ unittest System* ecs_system = gEM.getSystem(EmptySystem.system_id); assert(ecs_system !is null); assert(ecs_system.id == EmptySystem.system_id); - assert(ecs_system.name == "EmptySystem"); + assert(ecs_system.name == "tests.basic.EmptySystem"); gEM.begin(); @@ -605,7 +605,7 @@ unittest assert(ecs_system !is null); assert(ecs_system.id == LongAddSystem.system_id); assert(ecs_system.priority == -1); - assert(ecs_system.name == "LongAddSystem"); + assert(ecs_system.name == "tests.basic.LongAddSystem"); ushort[1] ids = [CLong.component_id]; EntityTemplate* tmpl = gEM.allocateTemplate(ids); From 74179b4fc8e0f5a9b8276b9b2b4575b189495bd7 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 8 Jul 2020 22:09:10 +0200 Subject: [PATCH 50/58] Demo update -added 'dot' function to vector math -fixed Circle tool rendering -fixed some potentiall memory leaks -added 'collision' module which now separates ShootGrid from SpaceInvaders demo -separate some systems from demos to 'basic' module to better demos functionality sharing -slow down snake -added new graphics -BrickBreaker demo now works (without blocks breaking and with bugged collision detection) -some bug fixes --- demos/assets/textures/atlas.png | Bin 42614 -> 37325 bytes demos/source/app.d | 12 +- demos/source/demos/brick_breaker.d | 284 +++++++++++-- demos/source/demos/particles.d | 118 +++--- demos/source/demos/sandbox.d | 16 +- demos/source/demos/simple.d | 8 +- demos/source/demos/snake.d | 18 +- demos/source/demos/space_invaders.d | 444 ++++----------------- demos/source/game_core/basic.d | 196 +++++++++ demos/source/game_core/collision.d | 232 +++++++++++ demos/source/gui/manager.d | 2 +- demos/source/gui/system.d | 3 +- demos/source/gui/tool_circle.d | 1 + demos/utils/source/ecs_utils/math/vector.d | 5 + 14 files changed, 871 insertions(+), 468 deletions(-) create mode 100644 demos/source/game_core/collision.d diff --git a/demos/assets/textures/atlas.png b/demos/assets/textures/atlas.png index eea925e600dde7ea3133047620c037882fdd4b2c..b84c3fac2893e8d6d59cc78ebf30536c964665ab 100644 GIT binary patch literal 37325 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%0DFoV*h>^r~oo%I8wK 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 literal 42614 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 299)position.y = 299; + //if(position.y < 16)position.y = 16; + //else if(position.y > 299)position.y = 299; *location = position; } manager.addEntity(tmpl); @@ -875,8 +877,6 @@ void mainLoop(void* arg) launcher.renderer.present(); draw_time = launcher.getTime() - draw_time; - //import std.stdio; - //printf("Scalling: %f",launcher.scalling); if(launcher.tool_show)launcher.tool_circle.draw(&launcher.renderer, (launcher.mouse.position*launcher.scalling)-launcher.render_position, cast(float)launcher.tool_size, launcher.renderer.view_size.y*6*launcher.scalling); __gshared float plot_time = 0; @@ -1105,11 +1105,13 @@ int app_main(int argc, char** argv) import demos.simple; import demos.space_invaders; import demos.particles; + import demos.brick_breaker; // launcher.switchDemo(&spaceInvadersStart,&spaceInvadersLoop,&spaceInvadersEnd,&spaceInvadersEvent,SpaceInvaders.tips); // launcher.switchDemo(&particlesStart,&particlesLoop,&particlesEnd,&particlesEvent,ParticlesDemo.tips); // launcher.switchDemo(&simpleStart,&simpleLoop,&simpleEnd,&simpleEvent,Simple.tips); // launcher.switchDemo(getParticlesDemo()); - launcher.switchDemo(getSimpleDemo()); + // launcher.switchDemo(getSimpleDemo()); + launcher.switchDemo(getBrickBreakerDemo()); } int key_num; diff --git a/demos/source/demos/brick_breaker.d b/demos/source/demos/brick_breaker.d index 1af22b9..ec4571f 100644 --- a/demos/source/demos/brick_breaker.d +++ b/demos/source/demos/brick_breaker.d @@ -18,9 +18,12 @@ import ecs_utils.utils; import game_core.basic; import game_core.rendering; +import game_core.collision; extern(C): +private enum float px = 1.0/512.0; + /*####################################################################################################################### ------------------------------------------------ Components ------------------------------------------------------------------ #######################################################################################################################*/ @@ -51,40 +54,60 @@ struct CBall ubyte radius; } -struct CVelocity -{ - mixin ECS.Component; +// struct CVelocityFactor +// { +// mixin ECS.Component; - alias value this; +// alias value this; - vec2 value; -} +// vec2 value = vec2(1); +// } + +// struct CVelocity +// { +// mixin ECS.Component; + +// alias value this; + +// vec2 value = vec2(0); +// } /*####################################################################################################################### ------------------------------------------------ Systems ------------------------------------------------------------------ #######################################################################################################################*/ -struct MoveSystem -{ - mixin ECS.System!64; +// struct MoveSystem +// { +// mixin ECS.System!64; - struct EntitiesData - { - uint length; - CLocation[] location; - @readonly CVelocity[] velocity; - } +// struct EntitiesData +// { +// uint length; +// CLocation[] location; +// @readonly CVelocity[] velocity; +// @optional @readonly CVelocityFactor[] vel_factor; +// } - void onUpdate(EntitiesData data) - { - foreach(i; 0..data.length) - { - data.location[i] += data.velocity[i] * launcher.delta_time; - } - } -} +// void onUpdate(EntitiesData data) +// { +// if(data.vel_factor) +// { +// foreach(i; 0..data.length) +// { +// data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.delta_time; +// } +// } +// else +// { +// foreach(i; 0..data.length) +// { +// data.location[i] += data.velocity[i] * launcher.delta_time; +// } +// } +// } +// } -struct BallCollisionSystem +struct EdgeCollisionSystem { mixin ECS.System!64; @@ -93,13 +116,117 @@ struct BallCollisionSystem uint length; CLocation[] location; CVelocity[] velocity; + //CBall[] ball_flag; } void onUpdate(EntitiesData data) { foreach(i; 0..data.length) { - + if(data.location[i].x < 0) + { + if(data.velocity[i].x < 0)data.velocity[i].x = -data.velocity[i].x; + data.location[i].x = 0; + } + else if(data.location[i].x > 400) + { + if(data.velocity[i].x > 0)data.velocity[i].x = -data.velocity[i].x; + data.location[i].x = 400; + } + + if(data.location[i].y < 0) + { + if(data.velocity[i].y < 0)data.velocity[i].y = -data.velocity[i].y; + data.location[i].y = 0; + } + else if(data.location[i].y > 300) + { + if(data.velocity[i].y > 0)data.velocity[i].y = -data.velocity[i].y; + data.location[i].y = 300; + } + } + } +} + +struct BallCollisionSystem +{ + mixin ECS.System!64; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + CVelocity[] velocity; + @readonly CLocation[] location; + @readonly CScale[] scale; + @readonly CBall[] ball_flag; + } + + ShootGrid* grid; + + bool onBegin() + { + grid = launcher.manager.getSystem!ShootGridManager().grid; + if(grid is null)return false; + else return true; + } + + void onUpdate(EntitiesData data) + { + EntityID id; + foreach(i; 0..data.length) + { + float radius = data.scale[i].x; + //if(grid.test(id, data.location[i], ubyte.max)) + if(grid.test(id, data.location[i] - radius, data.location[i] + radius, ubyte.max)) + { + Entity* entity = launcher.manager.getEntity(id); + if(entity) + { + CLocation* location = entity.getComponent!CLocation; + CScale* scale = entity.getComponent!CScale; + if(location && scale) + { + 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; + + if(abs_rel_pos.x < half_scale.x + radius && + abs_rel_pos.y < half_scale.y + radius) + { + 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; + } + 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; + } + 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; + + 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, EBulletHit(data.entity[i].id,data.bullet[i].damage)); + //launcher.manager.removeEntity(data.entity[i].id); + } } } } @@ -118,13 +245,17 @@ struct BrickBreakerDemo __gshared BrickBreakerDemo* demo; -void brickBreakerStart() +void brickBreakerRegister() { demo = Mallocator.make!BrickBreakerDemo; + demo.texture.create(); + demo.texture.load("assets/textures/atlas.png"); + launcher.manager.beginRegister(); registerRenderingModule(launcher.manager); + registerCollisionModule(launcher.manager); launcher.manager.registerComponent!CLocation; launcher.manager.registerComponent!CRotation; @@ -132,27 +263,109 @@ void brickBreakerStart() launcher.manager.registerComponent!CTexCoords; launcher.manager.registerComponent!CTexCoordsIndex; launcher.manager.registerComponent!CVelocity; + launcher.manager.registerComponent!CInput; + launcher.manager.registerComponent!CPaddle; + launcher.manager.registerComponent!CDamping; + launcher.manager.registerComponent!CVelocityFactor; + launcher.manager.registerComponent!CBall; launcher.manager.registerSystem!MoveSystem(-100); - launcher.manager.registerSystem!BallCollisionSystem(-99); + launcher.manager.registerSystem!EdgeCollisionSystem(-99); + launcher.manager.registerSystem!BallCollisionSystem(-79); + launcher.manager.registerSystem!InputMovementSystem(-120); + launcher.manager.registerSystem!DampingSystem(-120); launcher.manager.endRegister(); +} - demo.texture.create(); - demo.texture.load("assets/textures/atlas.png"); +void brickBreakerStart() +{ + DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; + draw_system.default_data.color = 0x80808080; + draw_system.default_data.texture = demo.texture; + draw_system.default_data.size = vec2(16,16); + draw_system.default_data.coords = vec4(246,64,2,2)*px; + draw_system.default_data.material_id = 0; - launcher.manager.beginRegister(); + EntityTemplate* brick_tmpl = launcher.manager.allocateTemplate( + [CLocation.component_id, CScale.component_id, CColor.component_id, + CTexCoordsIndex.component_id, CShootGrid.component_id].staticArray + ); + brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,40,16,8)*px); + brick_tmpl.getComponent!CColor().value = 0x80206020; + brick_tmpl.getComponent!CScale().value = vec2(16,8); - launcher.manager.registerComponent!CLocation; + EntityTemplate* big_brick_tmpl = launcher.manager.allocateTemplate(brick_tmpl); + big_brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(320,32,16,16)*px); + big_brick_tmpl.getComponent!CScale().value = vec2(16,16); + + EntityTemplate* paddle_tmpl = launcher.manager.allocateTemplate( + [CLocation.component_id, CScale.component_id, CInput.component_id, + CTexCoordsIndex.component_id, CPaddle.component_id, CVelocity.component_id, + CDamping.component_id, CVelocityFactor.component_id, CShootGrid.component_id].staticArray + ); + paddle_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(272,48,64,10)*px); + paddle_tmpl.getComponent!CScale().value = vec2(64,10); + paddle_tmpl.getComponent!CDamping().value = 14; + paddle_tmpl.getComponent!CVelocityFactor().value = vec2(1,0); + + EntityTemplate* ball_tmpl = launcher.manager.allocateTemplate( + [CLocation.component_id, CScale.component_id, //CDamping.component_id, + CTexCoordsIndex.component_id, CBall.component_id, CVelocity.component_id].staticArray + ); + ball_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,32,8,8)*px); + ball_tmpl.getComponent!CScale().value = vec2(8,8); + ball_tmpl.getComponent!CVelocity().value = vec2(0.1,0.1); + // paddle_tmpl.getComponent!CDamping().value = 14; + + launcher.gui_manager.addComponent(CLocation(), "Location"); + launcher.gui_manager.addComponent(CRotation(), "Rotation"); + launcher.gui_manager.addComponent(CScale(), "Scale"); + launcher.gui_manager.addComponent(CColor(), "Color"); + launcher.gui_manager.addComponent(CTexCoords(), "Tex Coords"); + launcher.gui_manager.addComponent(CTexCoordsIndex(), "Tex Coords Index"); + launcher.gui_manager.addComponent(CVelocity(), "Velocity"); + launcher.gui_manager.addComponent(CInput(), "Velocity"); + launcher.gui_manager.addComponent(CDamping(), "Damping"); + launcher.gui_manager.addComponent(CBall(), "Ball"); + + launcher.gui_manager.addSystem(MoveSystem.system_id, "Move System"); + launcher.gui_manager.addSystem(BallCollisionSystem.system_id, "Ball Collision System"); + + launcher.gui_manager.addTemplate(brick_tmpl, "Brick"); + launcher.gui_manager.addTemplate(big_brick_tmpl, "Big Brick"); + launcher.gui_manager.addTemplate(paddle_tmpl, "Paddle"); + launcher.gui_manager.addTemplate(ball_tmpl, "Ball"); + + foreach(i;0..10) + { + CColor color; + final switch(i) + { + case 0:color = 0x80206020;break; + case 1:color = 0x80602020;break; + case 2:color = 0x80202060;break; + case 3:color = 0x80206060;break; + case 4:color = 0x80606020;break; + case 5:color = 0x80602060;break; + case 6:color = 0x80606060;break; + case 7:color = 0x80202020;break; + case 8:color = 0x80008030;break; + case 9:color = 0x80206080;break; + } + foreach (j; 0..20) + { + launcher.manager.addEntity(brick_tmpl,[CLocation(vec2(j*18,300-i*10)).ref_, color.ref_].staticArray); + } + } + + launcher.manager.addEntity(paddle_tmpl,[CLocation(vec2(190,20)).ref_].staticArray); + launcher.manager.addEntity(ball_tmpl,[CLocation(vec2(190,40)).ref_].staticArray); - launcher.manager.endRegister(); } void brickBreakerEnd() { - launcher.manager.getSystem(MoveSystem.system_id).disable(); - launcher.manager.getSystem(DrawSystem.system_id).disable(); - demo.texture.destroy(); Mallocator.dispose(demo); @@ -185,6 +398,7 @@ bool brickBreakerLoop() DemoCallbacks getBrickBreakerDemo() { DemoCallbacks demo; + demo.register = &brickBreakerRegister; demo.initialize = &brickBreakerStart; demo.deinitialize = &brickBreakerEnd; demo.loop = &brickBreakerLoop; diff --git a/demos/source/demos/particles.d b/demos/source/demos/particles.d index 8dac7ff..ec64774 100644 --- a/demos/source/demos/particles.d +++ b/demos/source/demos/particles.d @@ -54,14 +54,14 @@ struct CTexCoords vec4 value; }*/ -struct CVelocity -{ - mixin ECS.Component; +// struct CVelocity +// { +// mixin ECS.Component; - alias value this; +// alias value this; - vec2 value = vec2(0); -} +// vec2 value = vec2(0); +// } struct CForceRange { @@ -85,14 +85,14 @@ struct CVortex float strength = 0.6; } -struct CDamping -{ - mixin ECS.Component; +// struct CDamping +// { +// mixin ECS.Component; - alias power this; +// alias power this; - @GUIRange(0,9) ubyte power = 0; -} +// @GUIRange(0,9) ubyte power = 0; +// } struct CGravity { @@ -165,25 +165,25 @@ struct DrawSystem } }*/ -struct MoveSystem -{ - mixin ECS.System!64; +// struct MoveSystem +// { +// mixin ECS.System!64; - struct EntitiesData - { - uint length; - CLocation[] locations; - @readonly CVelocity[] velocity; - } +// struct EntitiesData +// { +// uint length; +// CLocation[] locations; +// @readonly CVelocity[] velocity; +// } - void onUpdate(EntitiesData data) - { - foreach(i; 0..data.length) - { - data.locations[i] += data.velocity[i] * launcher.delta_time; - } - } -} +// void onUpdate(EntitiesData data) +// { +// foreach(i; 0..data.length) +// { +// data.locations[i] += data.velocity[i] * launcher.delta_time; +// } +// } +// } struct MouseAttractSystem { @@ -347,38 +347,38 @@ struct PlayAreaSystem } } -struct DampingSystem -{ - mixin ECS.System!32; +// struct DampingSystem +// { +// mixin ECS.System!32; - struct EntitiesData - { - uint length; - const (Entity)[] entity; - @readonly CDamping[] damping; - CVelocity[] velocity; - } +// struct EntitiesData +// { +// uint length; +// const (Entity)[] entity; +// @readonly CDamping[] damping; +// CVelocity[] velocity; +// } - float[10] damp = 0; +// float[10] damp = 0; - bool onBegin() - { - foreach(i;0..10) - { - damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1); - } +// bool onBegin() +// { +// foreach(i;0..10) +// { +// damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1); +// } - return true; - } +// return true; +// } - void onUpdate(EntitiesData data) - { - foreach(i; 0..data.length) - { - data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; - } - } -} +// void onUpdate(EntitiesData data) +// { +// foreach(i; 0..data.length) +// { +// data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; +// } +// } +// } struct ParticleLifeSystem { @@ -444,7 +444,7 @@ struct ParticlesDemo __gshared ParticlesDemo* particles_demo; -void particlesStart() +void particlesRegister() { particles_demo = Mallocator.make!ParticlesDemo; @@ -484,7 +484,10 @@ void particlesStart() launcher.manager.registerSystem!AttractorIterator(-1); launcher.manager.endRegister(); +} +void particlesStart() +{ DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; draw_system.default_data.size = vec2(2,2); draw_system.default_data.coords = vec4(246,64,2,2)*px; @@ -579,6 +582,7 @@ bool particlesLoop() DemoCallbacks getParticlesDemo() { DemoCallbacks demo; + demo.register = &particlesRegister; demo.initialize = &particlesStart; demo.deinitialize = &particlesEnd; demo.loop = &particlesLoop; diff --git a/demos/source/demos/sandbox.d b/demos/source/demos/sandbox.d index 69a2ef2..925ebb2 100644 --- a/demos/source/demos/sandbox.d +++ b/demos/source/demos/sandbox.d @@ -6,6 +6,7 @@ import demos.simple; import demos.snake; import demos.space_invaders; import demos.particles; +import demos.brick_breaker; import game_core.rendering; @@ -17,10 +18,17 @@ extern(C): void sandboxStart() { + simpleRegister(); + snakeRegister(); + spaceInvadersRegister(); + particlesRegister(); + brickBreakerRegister(); + simpleStart(); snakeStart(); spaceInvadersStart(); particlesStart(); + brickBreakerStart(); DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; draw_system.default_data.size = vec2(16,16); @@ -28,6 +36,10 @@ void sandboxStart() draw_system.default_data.material_id = 0; draw_system.default_data.texture = particles_demo.texture; draw_system.default_data.color = 0x80808080; + + launcher.manager.getSystem(MouseAttractSystem.system_id).disable(); + launcher.manager.getSystem(demos.simple.MoveSystem.system_id).disable(); + } void sandboxEnd() @@ -56,9 +68,9 @@ bool sandboxLoop() else */ time += delta_time; - while(time > 100) + while(time > 200) { - time -= 100; + time -= 200; launcher.manager.update("fixed"); } diff --git a/demos/source/demos/simple.d b/demos/source/demos/simple.d index 1aafcb2..ecccc12 100644 --- a/demos/source/demos/simple.d +++ b/demos/source/demos/simple.d @@ -107,7 +107,7 @@ struct Simple __gshared Simple* simple; -void simpleStart() +void simpleRegister() { simple = Mallocator.make!Simple; @@ -124,7 +124,10 @@ void simpleStart() // launcher.manager.registerSystem!DrawSystem(1); launcher.manager.endRegister(); - +} + +void simpleStart() +{ DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; draw_system.default_data.color = 0x80808080; draw_system.default_data.texture = simple.texture; @@ -198,6 +201,7 @@ bool simpleLoop() DemoCallbacks getSimpleDemo() { DemoCallbacks demo; + demo.register = &simpleRegister; demo.initialize = &simpleStart; demo.deinitialize = &simpleEnd; demo.loop = &simpleLoop; diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 8ff0be6..525b4ab 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -235,10 +235,10 @@ struct CMovement Direction direction; } -struct CInput -{ - mixin ECS.Component; -} +// struct CInput +// { +// mixin ECS.Component; +// } struct AppleSystem { @@ -849,7 +849,7 @@ struct CopyLocationSystem __gshared Snake* snake; -void snakeStart() +void snakeRegister() { import game_core.rendering; @@ -890,7 +890,10 @@ void snakeStart() launcher.manager.registerSystem!SnakeSystem(101); launcher.manager.endRegister(); +} +void snakeStart() +{ launcher.gui_manager.addComponent(CApple(),"Apple"); launcher.gui_manager.addComponent(CSnake(),"Snake"); launcher.gui_manager.addComponent(CParticle(1000),"Particle"); @@ -975,9 +978,9 @@ bool snakeLoop() if(launcher.getKeyState(SDL_SCANCODE_SPACE))time += delta_time * 3; else time += delta_time; - while(time > 100) + while(time > 200) { - time -= 100; + time -= 200; launcher.manager.update("fixed"); } @@ -992,6 +995,7 @@ bool snakeLoop() DemoCallbacks getSnakeDemo() { DemoCallbacks demo; + demo.register = &snakeRegister; demo.initialize = &snakeStart; demo.deinitialize = &snakeEnd; demo.loop = &snakeLoop; diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index b249fc1..66be099 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -18,6 +18,7 @@ import ecs_utils.utils; import game_core.basic; import game_core.rendering; +import game_core.collision; //import std.math : PI; @@ -29,8 +30,6 @@ private enum float px = 1.0/512.0; extern(C): -enum ShootGridDependency = "ShootGridDependency"; - /*####################################################################################################################### ------------------------------------------------ Types ------------------------------------------------------------------ #######################################################################################################################*/ @@ -57,7 +56,7 @@ struct SpaceInvaders ~this() @nogc nothrow { - if(shoot_grid)Mallocator.dispose(shoot_grid); + // if(shoot_grid)Mallocator.dispose(shoot_grid); if(enemy_tmpl)launcher.manager.freeTemplate(enemy_tmpl); if(ship_tmpl)launcher.manager.freeTemplate(ship_tmpl); if(laser_tmpl)launcher.manager.freeTemplate(laser_tmpl); @@ -163,28 +162,14 @@ struct CTexture vec4 coords = vec4(0,0,0,1); }*/ -struct CColliderScale -{ - mixin ECS.Component; +// struct CVelocity +// { +// mixin ECS.Component; - alias value this; +// alias value this; - vec2 value = vec2(16,16); -} - -struct CVelocity -{ - mixin ECS.Component; - - alias value this; - - vec2 value = vec2(0,0); -} - -struct CInput -{ - mixin ECS.Component; -} +// vec2 value = vec2(0,0); +// } struct CEnemy { @@ -265,11 +250,6 @@ struct CSideMove byte group = -1; } -struct CShootGrid -{ - mixin ECS.Component; -} - struct CTargetParent { mixin ECS.Component; @@ -336,14 +316,7 @@ struct CAnimationLooped mixin ECS.Component; } -struct CDamping -{ - mixin ECS.Component; - alias value this; - - byte value = 0; -} struct CParticle { @@ -514,163 +487,6 @@ struct EDestroyedChild ------------------------------------------------ Systems ------------------------------------------------------------------ #######################################################################################################################*/ -struct ShootGrid -{ - - ~this() @nogc nothrow - { - if(nodes)Mallocator.dispose(nodes); - if(masks)Mallocator.dispose(masks); - } - - struct Node - { - alias entity this; - - EntityID entity; - } - - void create(ivec2 nodes_count, vec2 node_size) - { - this.size = nodes_count; - this.node_size = node_size; - inv_node_size = vec2(1.0/node_size.x, 1.0/node_size.y); - nodes = Mallocator.makeArray!Node(nodes_count.x * nodes_count.y); - masks = Mallocator.makeArray!ubyte(nodes.length); - } - - void mark(EntityID id, vec2 beg, vec2 end, byte mask) - { - ivec2 ibeg = cast(ivec2)(beg * inv_node_size); - ivec2 iend = cast(ivec2)((end * inv_node_size) + 0.5); - if(ibeg.x < 0)ibeg.x = 0; - if(ibeg.y < 0)ibeg.y = 0; - if(iend.x > size.x)iend.x = size.x; - if(iend.y > size.y)iend.y = size.y; - foreach(i; ibeg.y .. iend.y) - { - foreach(j; ibeg.x .. iend.x) - { - nodes[i * size.x + j] = id; - masks[i * size.x +j] = mask; - } - } - } - - void clear() - { - size_t size = nodes.length * EntityID.sizeof; - memset(nodes.ptr, 0, size); - memset(masks.ptr, 0, masks.length); - } - - bool test(out EntityID id, vec2 beg, vec2 end) - { - ivec2 ibeg = cast(ivec2)(beg * inv_node_size); - ivec2 iend = cast(ivec2)((end * inv_node_size) + 0.5); - if(ibeg.x < 0)ibeg.x = 0; - if(ibeg.y < 0)ibeg.y = 0; - if(iend.x > size.x)iend.x = size.x; - if(iend.y > size.y)iend.y = size.y; - foreach(i; ibeg.y .. iend.y) - { - foreach(j; ibeg.x .. iend.x) - { - if(nodes[i * size.x + j].id != 0) - { - id = nodes[i * size.x + j]; - return true; - } - } - } - return false; - } - - bool test(out EntityID id, vec2 pos, ubyte mask) - { - ivec2 ipos = cast(ivec2)(pos * inv_node_size - 0.5); - if(ipos.x < 0)ipos.x = 0; - if(ipos.y < 0)ipos.y = 0; - if(ipos.x >= size.x)ipos.x = size.x - 1; - if(ipos.y >= size.y)ipos.y = size.y - 1; - size_t index = ipos.y * size.x + ipos.x; - if((masks[index] & mask) == 0)return false; - if(nodes[index].id != 0) - { - id = nodes[index]; - return true; - } - return false; - } - - vec2 inv_node_size; - ivec2 size; - vec2 node_size; - Node[] nodes; - ubyte[] masks; -} - -struct ShootGridCleaner -{ - mixin ECS.System!1; - - struct EntitiesData - { - - } - - void onUpdate(EntitiesData data) - { - if(space_invaders.shoot_grid)space_invaders.shoot_grid.clear(); - } -} - -struct ShootGridManager -{ - mixin ECS.System!128; - - mixin ECS.WritableDependencies!(ShootGridDependency); - - struct EntitiesData - { - uint length; - //uint thread_id; - const (Entity)[] entity; - @readonly CLocation[] locations; - @readonly CShootGrid[] grid_flag; - @readonly CGuild[] guild; - @optional @readonly CScale[] scale; - @optional @readonly CColliderScale[] collider_scale; - } - - ShootGrid* grid; - - void onCreate() - { - grid = space_invaders.shoot_grid; - } - - bool onBegin() - { - if(!grid)return false; - //grid.clear(); - return true; - } - - void onUpdate(EntitiesData data) - { - vec2[] scale; - if(data.collider_scale)scale = cast(vec2[])data.collider_scale; - else if(data.scale)scale = cast(vec2[])data.scale; - else return; - foreach(i; 0..data.length) - { - vec2 half_scale = scale[i] * 0.5; - grid.mark(data.entity[i].id, data.locations[i] - half_scale, data.locations[i] + half_scale, cast(ubyte)(1 << data.guild[i].guild)); - } - } -} - struct ParentOwnerSystem { mixin ECS.System; @@ -833,7 +649,7 @@ struct ShipWeaponSystem CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, CChildren.component_id, CDepth.component_id, CTargetParent.component_id, - CSpawnUponDeath.component_id, CShootWaveUponDeath.component_id].staticArray + CSpawnUponDeath.component_id, CShootWaveUponDeath.component_id, CShootGridMask.component_id].staticArray ); /*CTexCoords* tex_comp = tower1_tmpl.getComponent!CTexCoords; @@ -1215,8 +1031,8 @@ struct ShootingSystem laser.shoot_time -= CWeapon.levels[laser.level - 1].reload_time; laser_location.value = data.location[i]; - laser_velocity.value = vec2((randomf()*2-1) * CWeapon.levels[laser.level - 1].dispersion,1);//data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); - if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down)laser_velocity.y = -1; + laser_velocity.value = vec2((randomf()*2-1) * CWeapon.levels[laser.level - 1].dispersion,0.5);//data.shoot_direction[i].direction == Direction.up ? 1.0 : -1.0); + if(data.shoot_direction && data.shoot_direction[i].direction == Direction.down)laser_velocity.y = -0.5; laser_guild.guild = data.guild[i].guild; @@ -1280,39 +1096,6 @@ struct ShootingSystem } } -struct DampingSystem -{ - mixin ECS.System!32; - - struct EntitiesData - { - uint length; - const (Entity)[] entity; - @readonly CDamping[] damping; - CVelocity[] velocity; - } - - float[10] damp = 0; - - bool onBegin() - { - foreach(i;0..10) - { - damp[i] = powf((0.98 - cast(float)i * 0.02),launcher.delta_time*0.1); - } - - return true; - } - - void onUpdate(EntitiesData data) - { - foreach(i; 0..data.length) - { - data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; - } - } -} - struct BulletsCollisionSystem { mixin ECS.System!32; @@ -1343,6 +1126,29 @@ struct BulletsCollisionSystem } } +struct CollisionMaskSystem +{ + mixin ECS.System; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + CShootGridMask[] mask; + @readonly CGuild[] guild; + } + + void onAddEntity(EntitiesData data) + { + foreach(i;0..data.length) + { + data.mask[i] = cast(ubyte)(1 << data.guild[i].guild); + } + } +} + struct ParticleEmittingSystem { mixin ECS.System!32; @@ -1670,7 +1476,7 @@ struct HitPointsSystem //tex_comp.tex = space_invaders.texture;//ship_tex; upgrade_tmpl.getComponent!CTexCoords().value = vec4(0*px,32*px,16*px,16*px); *upgrade_tmpl.getComponent!CAnimation = CAnimation(upgrade_laser_frames, 0, 1); - upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.1); + upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.05); explosion_tmpl = launcher.manager.allocateTemplate( [CDepth.component_id, CParticle.component_id, CLocation.component_id, @@ -1975,32 +1781,32 @@ struct ClampPositionSystem } } -struct MovementSystem -{ - mixin ECS.System!32; +// struct MovementSystem +// { +// mixin ECS.System!32; - struct EntitiesData - { - uint length; - //read only components can be marked with @readonly attribute or with const expression instead - const (CVelocity)[] velocity; - //components are treated as required by default - CLocation[] locations; - //@optional const (CBullet)[] laser; - const (Entity)[] entities; +// struct EntitiesData +// { +// uint length; +// //read only components can be marked with @readonly attribute or with const expression instead +// const (CVelocity)[] velocity; +// //components are treated as required by default +// CLocation[] locations; +// //@optional const (CBullet)[] laser; +// const (Entity)[] entities; - //@optional CSideMove[] side_move; - } +// //@optional CSideMove[] side_move; +// } - void onUpdate(EntitiesData data) - { - foreach(i;0..data.length) - { - data.locations[i].x += data.velocity[i].x * launcher.delta_time * 0.5; - data.locations[i].y += data.velocity[i].y * launcher.delta_time * 0.5; - } - } -} +// void onUpdate(EntitiesData data) +// { +// foreach(i;0..data.length) +// { +// data.locations[i].x += data.velocity[i].x * launcher.delta_time * 0.5; +// data.locations[i].y += data.velocity[i].y * launcher.delta_time * 0.5; +// } +// } +// } struct AnimationSystem { @@ -2229,114 +2035,20 @@ struct CShipIterator //void handleEvent(Entity* entity, ) }//*/ -/** -*System is responsible for movement of objects with CInput component. -*In this example every entity has same speed when using movement system. -*/ -struct InputMovementSystem -{ - mixin ECS.System!32; - - vec2 move_vector; - - struct EntitiesData - { - uint length; - //read only components can be marked with @readonly attribute or with const expression instead - const (CInput)[] input; - //components are treated as required by default - //CLocation[] locations; - CVelocity[] velocity; - //CTexture[] textures; - } - - /** - *onBegin gives opportunity to check keys once and call update on entities only when - *one key is pressed. - */ - bool onBegin() - { - move_vector = vec2(0,0); - if(launcher.getKeyState(SDL_SCANCODE_W)) - { - move_vector += vec2(0,1); - } - else if(launcher.getKeyState(SDL_SCANCODE_S)) - { - move_vector += vec2(0,-1); - } - if(launcher.getKeyState(SDL_SCANCODE_A)) - { - move_vector += vec2(-1,0); - } - else if(launcher.getKeyState(SDL_SCANCODE_D)) - { - move_vector += vec2(1,0); - } - - if(move_vector.x != 0 ||move_vector.y != 0) - { - move_vector = move_vector / sqrtf(move_vector.x * move_vector.x + move_vector.y * move_vector.y); - return true; - } - //don't call system update because no key pressed - return false; - } - - /** - *Update is called multiple times in one "manager.update()" call. - *Number of "onUpdate" calls is count of buffers which must be updated during pass. - *When multithreading is used, number of "onUpdate" calls can be greater due to fact that - *JobSystem can split buffers for better data packing. - */ - void onUpdate(EntitiesData data) - { - /*if(move_vector.x == 0) - { - foreach(i; 0..data.length) - { - data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); - } - //return; - }*/ - //move every entity using movement vector - //if(move_vector.x != 0 || move_vector.y != 0) - foreach(i; 0..data.length) - { - data.velocity[i] += move_vector * launcher.delta_time * 0.005; - if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5; - else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5; - if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5; - else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5; - //data.locations[i].x += move_vector.x * launcher.delta_time * 0.25; - //data.locations[i].y += move_vector.y * launcher.delta_time * 0.25; - //if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px); - //else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); - } - /*else - foreach(i; 0..data.length) - { - data.velocity[i] = vec2(0,0); - }*/ - } -} - /*####################################################################################################################### ------------------------------------------------ Functions ------------------------------------------------------------------ #######################################################################################################################*/ __gshared SpaceInvaders* space_invaders; -void spaceInvadersStart() +void spaceInvadersRegister() { + space_invaders = Mallocator.make!SpaceInvaders; space_invaders.texture.create(); space_invaders.texture.load("assets/textures/atlas.png"); - space_invaders.shoot_grid = Mallocator.make!ShootGrid; - space_invaders.shoot_grid.create(ivec2(80,60), vec2(5,5)); - launcher.manager.beginRegister(); launcher.manager.registerDependency(ShootGridDependency); @@ -2381,6 +2093,7 @@ void spaceInvadersStart() launcher.manager.registerComponent!CParticleEmitterTime; launcher.manager.registerComponent!CSpawnUponDeath; launcher.manager.registerComponent!CShootWaveUponDeath; + launcher.manager.registerComponent!CShootGridMask; launcher.manager.registerEvent!EChangeDirection; launcher.manager.registerEvent!EDamage; @@ -2392,7 +2105,8 @@ void spaceInvadersStart() //launcher.manager.registerSystem!MoveSystem(0); launcher.manager.registerSystem!DrawSystem(100); launcher.manager.registerSystem!InputMovementSystem(-100); - launcher.manager.registerSystem!MovementSystem(-99); + //launcher.manager.registerSystem!MovementSystem(-99); + launcher.manager.registerSystem!MoveSystem(-99); launcher.manager.registerSystem!ClampPositionSystem(-90); launcher.manager.registerSystem!ShootingSystem(0); launcher.manager.registerSystem!ChangeDirectionSystem(0); @@ -2417,8 +2131,18 @@ void spaceInvadersStart() launcher.manager.registerSystem!ChildDestroySystem(-110); launcher.manager.registerSystem!ShootWaveSystem(-100); //launcher.manager.registerSystem!SpawnUponDeathSystem(-110); + launcher.manager.registerSystem!CollisionMaskSystem(-100); launcher.manager.endRegister(); +} + +void spaceInvadersStart() +{ + + // space_invaders.shoot_grid = Mallocator.make!ShootGrid; + // space_invaders.shoot_grid.create(ivec2(80,60), vec2(5,5)); + + space_invaders.shoot_grid = launcher.manager.getSystem!ShootGridManager().grid; DrawSystem* draw_system = launcher.manager.getSystem!DrawSystem; draw_system.default_data.color = 0x80808080; @@ -2463,7 +2187,8 @@ void spaceInvadersStart() launcher.gui_manager.addSystem(DrawSystem.system_id,"Draw System"); launcher.gui_manager.addSystem(InputMovementSystem.system_id,"Input Movement"); launcher.gui_manager.addSystem(ShootingSystem.system_id,"Shooting System"); - launcher.gui_manager.addSystem(MovementSystem.system_id,"Movement System"); + //launcher.gui_manager.addSystem(MovementSystem.system_id,"Movement System"); + launcher.gui_manager.addSystem(MoveSystem.system_id,"Move System"); launcher.gui_manager.addSystem(ClampPositionSystem.system_id,"Clamp Position System"); launcher.gui_manager.addSystem(ChangeDirectionSystem.system_id,"Change Direction System"); launcher.gui_manager.addSystem(BulletsCollisionSystem.system_id,"Bullets Collision System"); @@ -2494,14 +2219,16 @@ void spaceInvadersStart() CLocation.component_id, CTexCoords.component_id, CInput.component_id, CShip.component_id, CScale.component_id, CColliderScale.component_id, CShootDirection.component_id, CShootGrid.component_id, CGuild.component_id, - CDamping.component_id, CChildren.component_id, CInit.component_id].staticArray + CDamping.component_id, CChildren.component_id, CInit.component_id, + CShootGridMask.component_id, CVelocityFactor.component_id].staticArray ); space_invaders.ship_tmpl.getComponent!CTexCoords().value = vec4(0,80,48,32)*px; space_invaders.ship_tmpl.getComponent!CScale().value = vec2(48,32); space_invaders.ship_tmpl.getComponent!CHitPoints().value = 1000; - space_invaders.ship_tmpl.getComponent!CDamping().value = 7; + space_invaders.ship_tmpl.getComponent!CDamping().value = 14; space_invaders.ship_tmpl.getComponent!CInit().type = CInit.Type.space_ship; space_invaders.ship_tmpl.getComponent!CColliderScale().value = vec2(26,24); + space_invaders.ship_tmpl.getComponent!CVelocityFactor().value = vec2(0.5,0.5); launcher.manager.addEntity(space_invaders.ship_tmpl,[CLocation(vec2(64,64)).ref_].staticArray); } @@ -2512,7 +2239,7 @@ void spaceInvadersStart() space_invaders.laser_tmpl.getComponent!CTexCoords().value = vec4(0,24,2,8)*px; space_invaders.laser_tmpl.getComponent!CScale().value = vec2(2,8); - space_invaders.laser_tmpl.getComponent!CVelocity().value = vec2(0,1); + space_invaders.laser_tmpl.getComponent!CVelocity().value = vec2(0,0.5); } EntityTemplate* enemy_tmpl; @@ -2543,7 +2270,7 @@ void spaceInvadersStart() boss_tmpl.getComponent!CScale().value = vec2(96,48); boss_tmpl.getComponent!CDepth().value = -1; boss_tmpl.getComponent!CParts().count = 4; - boss_tmpl.getComponent!CVelocity().value = vec2(0.05,0); + boss_tmpl.getComponent!CVelocity().value = vec2(0.025,0); } { @@ -2551,7 +2278,7 @@ void spaceInvadersStart() [CColor.component_id, CHitMark.component_id, CHitPoints.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CEnemy.component_id, CShootGrid.component_id, CGuild.component_id, CInit.component_id, - CChildren.component_id].staticArray + CChildren.component_id, CShootGridMask.component_id].staticArray ); tower_tmpl.getComponent!CTexCoords().value = vec4(96,96,16,16)*px; @@ -2566,12 +2293,12 @@ void spaceInvadersStart() CVelocity.component_id, CAutoShoot.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CWeapon.component_id, CEnemy.component_id, CShootDirection.component_id, CShootGrid.component_id, - CGuild.component_id].staticArray + CGuild.component_id, CShootGridMask.component_id].staticArray ); space_invaders.enemy_tmpl.getComponent!CTexCoords().value = vec4(32,32,16,16)*px; space_invaders.enemy_tmpl.getComponent!CShootDirection().direction = Direction.down; - space_invaders.enemy_tmpl.getComponent!CVelocity().value = vec2(0.1,0); + space_invaders.enemy_tmpl.getComponent!CVelocity().value = vec2(0.05,0); space_invaders.enemy_tmpl.getComponent!CGuild().guild = 1; space_invaders.enemy_tmpl.getComponent!CWeaponLocation().rel_pos = vec2(0,-15); @@ -2603,7 +2330,7 @@ void spaceInvadersStart() { upgrade_tmpl = launcher.manager.allocateTemplate([CVelocity.component_id, CLocation.component_id, CTexCoords.component_id, CScale.component_id, CUpgrade.component_id, CAnimationLooped.component_id, CAnimation.component_id].staticArray); upgrade_tmpl.getComponent!CTexCoords().value = vec4(0,32,16,16)*px; - upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.1); + upgrade_tmpl.getComponent!CVelocity().value = vec2(0,-0.05); *upgrade_tmpl.getComponent!CAnimation = CAnimation(HitPointsSystem.upgrade_laser_frames, 0, 0.75); } @@ -2746,6 +2473,7 @@ bool spaceInvadersLoop() DemoCallbacks getSpaceInvadersDemo() { DemoCallbacks demo; + demo.register = &spaceInvadersRegister; demo.initialize = &spaceInvadersStart; demo.deinitialize = &spaceInvadersEnd; demo.loop = &spaceInvadersLoop; diff --git a/demos/source/game_core/basic.d b/demos/source/game_core/basic.d index 156680b..b47ba52 100644 --- a/demos/source/game_core/basic.d +++ b/demos/source/game_core/basic.d @@ -1,11 +1,18 @@ module game_core.basic; import bubel.ecs.core; +import bubel.ecs.attributes; import ecs_utils.math.vector; import gui.attributes; +import ecs_utils.utils; + +import app : launcher; + +import bindbc.sdl; + struct CLocation { mixin ECS.Component; @@ -56,4 +63,193 @@ struct CSelected mixin ECS.Component; bool value = false; +} + +struct CInput +{ + mixin ECS.Component; +} + +struct CDamping +{ + mixin ECS.Component; + + alias value this; + + @GUIRange(0,9) byte value = 1; +} + +struct CVelocity +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(0,0); +} + +struct CVelocityFactor +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(1); +} + + +struct DampingSystem +{ + mixin ECS.System!32; + + struct EntitiesData + { + uint length; + const (Entity)[] entity; + @readonly CDamping[] damping; + CVelocity[] velocity; + } + + float[20] damp = 0; + + bool onBegin() + { + foreach(i;0..20) + { + damp[i] = powf((0.99 - cast(float)i * 0.01),launcher.delta_time*0.1); + } + + return true; + } + + void onUpdate(EntitiesData data) + { + foreach(i; 0..data.length) + { + data.velocity[i] = data.velocity[i] * damp[data.damping[i]]; + } + } +} + +struct MoveSystem +{ + mixin ECS.System!64; + + struct EntitiesData + { + uint length; + CLocation[] location; + @readonly CVelocity[] velocity; + @optional @readonly CVelocityFactor[] vel_factor; + } + + void onUpdate(EntitiesData data) + { + if(data.vel_factor) + { + foreach(i; 0..data.length) + { + data.location[i] += data.velocity[i] * data.vel_factor[i] * launcher.delta_time; + } + } + else + { + foreach(i; 0..data.length) + { + data.location[i] += data.velocity[i] * launcher.delta_time; + } + } + } +} + +/** +*System is responsible for movement of objects with CInput component. +*In this example every entity has same speed when using movement system. +*/ +struct InputMovementSystem +{ + mixin ECS.System!32; + + vec2 move_vector; + + struct EntitiesData + { + uint length; + //read only components can be marked with @readonly attribute or with const expression instead + const (CInput)[] input; + //components are treated as required by default + //CLocation[] locations; + CVelocity[] velocity; + //CTexture[] textures; + } + + /** + *onBegin gives opportunity to check keys once and call update on entities only when + *one key is pressed. + */ + bool onBegin() + { + move_vector = vec2(0,0); + if(launcher.getKeyState(SDL_SCANCODE_W)) + { + move_vector += vec2(0,1); + } + else if(launcher.getKeyState(SDL_SCANCODE_S)) + { + move_vector += vec2(0,-1); + } + if(launcher.getKeyState(SDL_SCANCODE_A)) + { + move_vector += vec2(-1,0); + } + else if(launcher.getKeyState(SDL_SCANCODE_D)) + { + move_vector += vec2(1,0); + } + + if(move_vector.x != 0 ||move_vector.y != 0) + { + move_vector = move_vector / sqrtf(move_vector.x * move_vector.x + move_vector.y * move_vector.y); + return true; + } + //don't call system update because no key pressed + return false; + } + + /** + *Update is called multiple times in one "manager.update()" call. + *Number of "onUpdate" calls is count of buffers which must be updated during pass. + *When multithreading is used, number of "onUpdate" calls can be greater due to fact that + *JobSystem can split buffers for better data packing. + */ + void onUpdate(EntitiesData data) + { + /*if(move_vector.x == 0) + { + foreach(i; 0..data.length) + { + data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); + } + //return; + }*/ + //move every entity using movement vector + //if(move_vector.x != 0 || move_vector.y != 0) + foreach(i; 0..data.length) + { + data.velocity[i] += move_vector * launcher.delta_time * 0.005; + if(data.velocity[i].x > 0.5)data.velocity[i].x = 0.5; + else if(data.velocity[i].x < -0.5)data.velocity[i].x = -0.5; + if(data.velocity[i].y > 0.5)data.velocity[i].y = 0.5; + else if(data.velocity[i].y < -0.5)data.velocity[i].y = -0.5; + //data.locations[i].x += move_vector.x * launcher.delta_time * 0.25; + //data.locations[i].y += move_vector.y * launcher.delta_time * 0.25; + //if(move_vector.x > 0)data.textures[i].coords = vec4(48*px,80*px,48*px,32*px); + //else data.textures[i].coords = vec4(0*px,80*px,48*px,32*px); + } + /*else + foreach(i; 0..data.length) + { + data.velocity[i] = vec2(0,0); + }*/ + } } \ No newline at end of file diff --git a/demos/source/game_core/collision.d b/demos/source/game_core/collision.d new file mode 100644 index 0000000..75c46f8 --- /dev/null +++ b/demos/source/game_core/collision.d @@ -0,0 +1,232 @@ +module game_core.collision; + +import bubel.ecs.attributes; +import bubel.ecs.core; +import bubel.ecs.std; + +import ecs_utils.math.vector; + +import game_core.basic; + + +void registerCollisionModule(EntityManager* manager) +{ + manager.registerDependency(ShootGridDependency); + + manager.registerComponent!CShootGrid; + manager.registerComponent!CShootGridMask; + manager.registerComponent!CColliderScale; + + manager.registerSystem!ShootGridManager(-80); + manager.registerSystem!ShootGridCleaner(-101); +} + +enum ShootGridDependency = "ShootGridDependency"; + +struct CShootGrid +{ + mixin ECS.Component; +} + +struct CShootGridMask +{ + mixin ECS.Component; + + alias value this; + + ubyte value; +} + +struct CColliderScale +{ + mixin ECS.Component; + + alias value this; + + vec2 value = vec2(16,16); +} + +struct ShootGrid +{ + + ~this() @nogc nothrow + { + if(nodes)Mallocator.dispose(nodes); + if(masks)Mallocator.dispose(masks); + } + + struct Node + { + alias entity this; + + EntityID entity; + } + + void create(ivec2 nodes_count, vec2 node_size) + { + this.size = nodes_count; + this.node_size = node_size; + inv_node_size = vec2(1.0/node_size.x, 1.0/node_size.y); + nodes = Mallocator.makeArray!Node(nodes_count.x * nodes_count.y); + masks = Mallocator.makeArray!ubyte(nodes.length); + } + + void mark(EntityID id, vec2 beg, vec2 end, ubyte mask) + { + ivec2 ibeg = cast(ivec2)(beg * inv_node_size); + ivec2 iend = cast(ivec2)(end * inv_node_size + 0.5); + if(ibeg.x < 0)ibeg.x = 0; + if(ibeg.y < 0)ibeg.y = 0; + if(iend.x > size.x)iend.x = size.x; + if(iend.y > size.y)iend.y = size.y; + foreach(i; ibeg.y .. iend.y) + { + foreach(j; ibeg.x .. iend.x) + { + nodes[i * size.x + j] = id; + masks[i * size.x +j] = mask; + } + } + } + + void clear() + { + size_t size = nodes.length * EntityID.sizeof; + memset(nodes.ptr, 0, size); + memset(masks.ptr, 0, masks.length); + } + + bool test(out EntityID id, vec2 beg, vec2 end, ubyte mask) + { + ivec2 ibeg = cast(ivec2)(beg * inv_node_size); + ivec2 iend = cast(ivec2)(end * inv_node_size + 0.5); + if(ibeg.x < 0)ibeg.x = 0; + if(ibeg.y < 0)ibeg.y = 0; + if(iend.x > size.x)iend.x = size.x; + if(iend.y > size.y)iend.y = size.y; + foreach(i; ibeg.y .. iend.y) + { + foreach(j; ibeg.x .. iend.x) + { + uint index = i * size.x + j; + if(nodes[index].id != 0) + { + if((masks[index] & mask) == 0)continue; + id = nodes[index]; + return true; + } + } + } + return false; + } + + bool test(out EntityID id, vec2 pos, ubyte mask) + { + ivec2 ipos = cast(ivec2)(pos * inv_node_size - 0.5); + if(ipos.x < 0)ipos.x = 0; + if(ipos.y < 0)ipos.y = 0; + if(ipos.x >= size.x)ipos.x = size.x - 1; + if(ipos.y >= size.y)ipos.y = size.y - 1; + size_t index = ipos.y * size.x + ipos.x; + if((masks[index] & mask) == 0)return false; + if(nodes[index].id != 0) + { + id = nodes[index]; + return true; + } + return false; + } + + vec2 inv_node_size; + ivec2 size; + vec2 node_size; + Node[] nodes; + ubyte[] masks; +} + +struct ShootGridCleaner +{ + mixin ECS.System!1; + + struct EntitiesData + { + + } + + ShootGrid* grid; + + bool onBegin() + { + grid = gEM.getSystem!ShootGridManager().grid; + if(grid != null)return true; + else return false; + } + + void onUpdate(EntitiesData data) + { + if(grid)grid.clear(); + } +} + +struct ShootGridManager +{ + mixin ECS.System!128; + + mixin ECS.WritableDependencies!(ShootGridDependency); + + struct EntitiesData + { + uint length; + //uint thread_id; + const (Entity)[] entity; + @readonly CLocation[] locations; + @readonly CShootGrid[] grid_flag; + //@readonly CGuild[] guild; + @optional @readonly CShootGridMask[] mask; + @optional @readonly CScale[] scale; + @optional @readonly CColliderScale[] collider_scale; + } + + ShootGrid* grid; + + void onCreate() + { + //grid = space_invaders.shoot_grid; + grid = Mallocator.make!ShootGrid; + grid.create(ivec2(80,60), vec2(5,5)); + } + + void onDestroy() + { + Mallocator.dispose(grid); + } + + // bool onBegin() + // { + // //if(!grid)return false; + // //grid.clear(); + // return true; + // } + + void onUpdate(EntitiesData data) + { + vec2[] scale; + if(data.collider_scale)scale = cast(vec2[])data.collider_scale; + else if(data.scale)scale = cast(vec2[])data.scale; + else return; + if(data.mask is null) + { + foreach(i; 0..data.length) + { + vec2 half_scale = scale[i] * 0.5; + grid.mark(data.entity[i].id, data.locations[i] - half_scale, data.locations[i] + half_scale, ubyte.max);//cast(ubyte)(1 << data.guild[i].guild)); + } + } + else foreach(i; 0..data.length) + { + vec2 half_scale = scale[i] * 0.5; + grid.mark(data.entity[i].id, data.locations[i] - half_scale, data.locations[i] + half_scale, data.mask[i]);//cast(ubyte)(1 << data.guild[i].guild)); + } + + } +} \ No newline at end of file diff --git a/demos/source/gui/manager.d b/demos/source/gui/manager.d index 3745d9d..b3381ef 100644 --- a/demos/source/gui/manager.d +++ b/demos/source/gui/manager.d @@ -213,7 +213,7 @@ struct GUIManager static if(hasUDA!(member,GUIRange)) { comp_edit.variables[comp_edit.used-1].int_.min = getUDAs!(member,GUIRange)[0].min; - comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[1].max; + comp_edit.variables[comp_edit.used-1].int_.max = getUDAs!(member,GUIRange)[0].max; } /*{ comp_edit.variables[comp_edit.used-1].int_.min = int.min; diff --git a/demos/source/gui/system.d b/demos/source/gui/system.d index 112bed3..b4899fb 100644 --- a/demos/source/gui/system.d +++ b/demos/source/gui/system.d @@ -5,7 +5,8 @@ import bubel.ecs.system; struct SystemGUI { const (char)* name; - System* system; + //System* system; + ushort id; bool enabled = true; } \ No newline at end of file diff --git a/demos/source/gui/tool_circle.d b/demos/source/gui/tool_circle.d index c43ade3..c8968d4 100644 --- a/demos/source/gui/tool_circle.d +++ b/demos/source/gui/tool_circle.d @@ -26,6 +26,7 @@ struct ToolCircle void draw(Renderer* renderer, vec2 position, float size, float edge = 1) { + glDisable(GL_DEPTH_TEST); position = position * renderer.view_size + renderer.view_pos; vec2 sizes = renderer.view_size * size; vec2 sizes2 = vec2(edge,0); diff --git a/demos/utils/source/ecs_utils/math/vector.d b/demos/utils/source/ecs_utils/math/vector.d index adb3a36..c835d05 100644 --- a/demos/utils/source/ecs_utils/math/vector.d +++ b/demos/utils/source/ecs_utils/math/vector.d @@ -95,6 +95,11 @@ struct vec2 } } +float dot(vec2 a, vec2 b) +{ + return a.x*b.x + a.y*b.y; +} + struct vec4 { union From 96bbcb9956cd8e0d3cc2fcceb8c0d0126d41abf8 Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 17 Jul 2020 13:34:08 +0200 Subject: [PATCH 51/58] Fixed issues and bugs -moved system destroy functionality to System structure "destroy()" function -now arrays are properly destroyed (with destructor calling (__xdtor)) -fixed bug which makes BlockAllocator crashing after freeing it's memory -fixed many smaller memory leaks --- source/bubel/ecs/block_allocator.d | 1 + source/bubel/ecs/manager.d | 44 ++++++++++-------------------- source/bubel/ecs/simple_vector.d | 6 ++++ source/bubel/ecs/std.d | 43 +++++++++++++++++++++++------ source/bubel/ecs/system.d | 32 ++++++++++++++++++++++ 5 files changed, 87 insertions(+), 39 deletions(-) diff --git a/source/bubel/ecs/block_allocator.d b/source/bubel/ecs/block_allocator.d index d3070c4..6894a17 100644 --- a/source/bubel/ecs/block_allocator.d +++ b/source/bubel/ecs/block_allocator.d @@ -54,6 +54,7 @@ struct BlockAllocator Mallocator.dispose(pointers); pointers = next_pointers; } + next_block = null; } private: diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 7fb79f8..c26a414 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -96,29 +96,7 @@ export struct EntityManager { foreach (ref system; systems) { - system.disable(); - if (system.m_destroy) - (cast(void function(void*)) system.m_destroy)(system.m_system_pointer); - - if (system.jobs) - Mallocator.dispose(system.jobs); - if (system.m_read_only_components) - Mallocator.dispose(system.m_read_only_components); - if (system.m_writable_components) - Mallocator.dispose(system.m_writable_components); - if (system.m_components) - Mallocator.dispose(system.m_components); - if (system.m_excluded_components) - Mallocator.dispose(system.m_excluded_components); - if (system.m_optional_components) - Mallocator.dispose(system.m_optional_components); - if (system.m_name) - Mallocator.dispose(system.m_name); - if (system.m_event_callers) - Mallocator.dispose(system.m_event_callers); - - if (system.m_system_pointer) - Mallocator.dispose(system.m_system_pointer); + system.destroy(); } foreach (EntityInfo* info; &entities_infos.byValue) @@ -425,7 +403,8 @@ export struct EntityManager enum EventName = fullName!(Unqual!(EventParamType)); // enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof; ushort evt = events_map.get(cast(char[]) EventName, ushort.max); - assert(evt != ushort.max, "Can't register system \"" ~ SystemName + assert(evt != ushort.max, + "Can't register system \"" ~ SystemName ~ "\" due to non existing event \"" ~ EventName ~ "\"."); callers[i].callback = cast(void*)&callEventHandler!(EventParamType); @@ -1188,10 +1167,9 @@ export struct EntityManager ushort sys_id = systems_map.get(cast(char[]) SystemName, ushort.max); if (sys_id < systems.length) { - systems[sys_id].disable(); - if (systems[sys_id].m_destroy) - (cast(void function(void*)) systems[sys_id].m_destroy)( - systems[sys_id].m_system_pointer); + system.m_name = systems[sys_id].m_name; + systems[sys_id].m_name = null; + systems[sys_id].destroy(); if (system.m_create) (cast(void function(void*)) system.m_create)(system.m_system_pointer); @@ -1199,7 +1177,6 @@ export struct EntityManager system.enable(); system.m_id = sys_id; - system.m_name = systems[sys_id].m_name; systems[sys_id] = system; } else @@ -1307,6 +1284,8 @@ export struct EntityManager if (comp_id < components.length) { Comp.component_id = comp_id; + if (components[comp_id].init_data) + Mallocator.dispose(components[comp_id].init_data); components[comp_id] = info; } else @@ -1874,7 +1853,8 @@ export struct EntityManager foreach (i, id; ids) { - if(current_delta == 0)current_delta = ushort.max; + if (current_delta == 0) + current_delta = ushort.max; alignNum(current_delta, components[id].alignment); info.deltas[id] = cast(ushort) current_delta; current_delta += entites_in_block * components[id].size; @@ -3548,6 +3528,10 @@ export struct EntityManager Mallocator.dispose(deltas); if (tmpl_deltas) Mallocator.dispose(tmpl_deltas); + if (comp_add_info) + Mallocator.dispose(comp_add_info); + if (comp_rem_info) + Mallocator.dispose(comp_rem_info); if (systems) Mallocator.dispose(systems); if (add_listeners) diff --git a/source/bubel/ecs/simple_vector.d b/source/bubel/ecs/simple_vector.d index bb4b610..acf01ee 100644 --- a/source/bubel/ecs/simple_vector.d +++ b/source/bubel/ecs/simple_vector.d @@ -12,6 +12,12 @@ struct SimpleVector { @disable this(this); + + ~this() nothrow @nogc + { + if(data) + Mallocator.dispose(data); + } ///Add element to vector void add(ubyte el) nothrow @nogc diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d index 38ad0d8..d99a05c 100644 --- a/source/bubel/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -156,7 +156,7 @@ static struct Mallocator { T[] ret; - if(length > array.length) + if (length > array.length) { ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; static if (__traits(isPOD, T)) @@ -178,21 +178,25 @@ static struct Mallocator } } } - else + else { static if (__traits(hasMember, T, "__xdtor")) + { foreach (i; length .. array.length) { array[i].__xdtor(); } + } else static if (__traits(hasMember, T, "__dtor")) + { foreach (i; length .. array.length) { array[i].__dtor(); } + } ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; } - + return ret; } @@ -297,13 +301,34 @@ static struct Mallocator return ret; } - static void dispose(T)(T object) nothrow @nogc + static void dispose(T)(T object) { - static if (__traits(hasMember, T, "__xdtor")) - object.__xdtor(); - else static if (__traits(hasMember, T, "__dtor")) - object.__dtor(); - free(cast(void*) object); + static if (isArray!T) + { + alias TT = PointerTarget!(typeof(object.ptr)); + static if (!isPointer!TT) + { + static if (__traits(hasMember, TT, "__xdtor")) + { + foreach (ref TT t; object) + t.__xdtor(); + } + else static if (__traits(hasMember, TT, "__dtor")) + { + foreach (TT t; object) + t.__dtor(); + } + } + free(cast(void*) object.ptr); + } + else + { + static if (__traits(hasMember, T, "__xdtor")) + object.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + object.__dtor(); + free(cast(void*) object); + } } static void alignDispose(T)(T object) diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index 7bcaf01..cd8d2e3 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -91,6 +91,38 @@ struct System package: + void destroy() + { + import bubel.ecs.std : Mallocator; + disable(); + if (m_destroy) + (cast(void function(void*)) m_destroy)(m_system_pointer); + + if (m_name) + Mallocator.dispose(m_name); + if (m_components) + Mallocator.dispose(m_components); + if (m_excluded_components) + Mallocator.dispose(m_excluded_components); + if (m_optional_components) + Mallocator.dispose(m_optional_components); + if (jobs) + Mallocator.dispose(jobs); + if (m_read_only_components) + Mallocator.dispose(m_read_only_components); + if (m_writable_components) + Mallocator.dispose(m_writable_components); + if (m_readonly_dependencies) + Mallocator.dispose(m_readonly_dependencies); + if (m_writable_dependencies) + Mallocator.dispose(m_writable_dependencies); + if (m_event_callers) + Mallocator.dispose(m_event_callers); + + if (m_system_pointer) + Mallocator.dispose(m_system_pointer); + } + struct EventCaller { ushort id; From 64dc099e0a868595ae855b43105fdc8cb0b78f2c Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 17 Jul 2020 13:38:41 +0200 Subject: [PATCH 52/58] Demos big update -Added some more math functions -fixed many memory leaks -added AABB and BVHTree support to collision.d *BVHTree has only incrementally adding entities implemented by now (and bad BottomUp algorithm) *ECS Systems use two trees, one for static and one for dynamic entities, dynamic BVH is builded every frame from scratch by now -BrickBreaker now uses BVHTree to collision detection *balls only use tree for checks (they aren't adding to tree) -fixed bug leading to crash --- demos/source/app.d | 19 +- demos/source/demos/brick_breaker.d | 202 ++++-- demos/source/demos/snake.d | 4 +- demos/source/demos/space_invaders.d | 5 +- demos/source/game_core/collision.d | 793 ++++++++++++++++++++- demos/source/gui/manager.d | 6 + demos/utils/source/ecs_utils/gfx/texture.d | 7 +- demos/utils/source/ecs_utils/math/vector.d | 5 + demos/utils/source/ecs_utils/utils.d | 2 + 9 files changed, 973 insertions(+), 70 deletions(-) diff --git a/demos/source/app.d b/demos/source/app.d index 1dbf9f4..5879daf 100644 --- a/demos/source/app.d +++ b/demos/source/app.d @@ -117,12 +117,12 @@ struct Launcher gui_manager.clear(); //launcher.ent - if(this.demo.deinitialize)this.demo.deinitialize(); - manager.begin(); manager.update("clean"); manager.end(); + if(this.demo.deinitialize)this.demo.deinitialize(); + foreach(ref system; manager.systems) { if(system.id != CountSystem.system_id && system.id != CleanSystem.system_id)system.disable(); @@ -946,12 +946,19 @@ void mainLoop(void* arg) void quit() { + import game_core.rendering : TexCoordsManager; launcher.gui_manager.clear(); Mallocator.dispose(launcher.gui_manager); + if(launcher.demo.deinitialize)launcher.demo.deinitialize(); + launcher.manager.destroy(); launcher.manager = null; + TexCoordsManager.destroy(); + + SDL_Quit(); + version(WebAssembly)emscripten_cancel_main_loop(); } @@ -1060,10 +1067,11 @@ int app_main(int argc, char** argv) } } - ImFontConfig* config = ImFontConfig_ImFontConfig(); + //ImFontConfig* config = ImFontConfig_ImFontConfig(); ImGuiIO* io = igGetIO(); const ushort* font_ranges = ImFontAtlas_GetGlyphRangesDefault(io.Fonts); - ImFontAtlas_AddFontFromFileTTF(io.Fonts,"assets/fonts/Ruda-Bold.ttf", 15.0f, config, font_ranges); + ImFontAtlas_AddFontFromFileTTF(io.Fonts,"assets/fonts/Ruda-Bold.ttf", 15.0f, null, font_ranges); + //ImFontConfig_destroy(config); setStyle(3); @@ -1139,9 +1147,6 @@ int app_main(int argc, char** argv) } } - TexCoordsManager.destroy(); - EntityManager.destroy(); - return 0; } diff --git a/demos/source/demos/brick_breaker.d b/demos/source/demos/brick_breaker.d index ec4571f..c15c503 100644 --- a/demos/source/demos/brick_breaker.d +++ b/demos/source/demos/brick_breaker.d @@ -54,6 +54,15 @@ struct CBall ubyte radius; } +struct CHitPoints +{ + mixin ECS.Component; + + alias value this; + + short value; +} + // struct CVelocityFactor // { // mixin ECS.Component; @@ -72,6 +81,13 @@ struct CBall // vec2 value = vec2(0); // } +struct EDamage +{ + mixin ECS.Event; + + ubyte damage = 1; +} + /*####################################################################################################################### ------------------------------------------------ Systems ------------------------------------------------------------------ #######################################################################################################################*/ @@ -152,7 +168,7 @@ struct BallCollisionSystem { mixin ECS.System!64; - mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + mixin ECS.ReadOnlyDependencies!(ShootGridDependency, BVHDependency); struct EntitiesData { @@ -165,72 +181,136 @@ struct BallCollisionSystem @readonly CBall[] ball_flag; } + struct State + { + bool test(EntityID id) + { + Entity* entity = launcher.manager.getEntity(id); + if(entity) + { + CLocation* location = entity.getComponent!CLocation; + CScale* scale = entity.getComponent!CScale; + if(location && scale) + { + float radius = data.scale[i].x; + 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; + + if(abs_rel_pos.x < half_scale.x + radius && + abs_rel_pos.y < half_scale.y + radius) + { + 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; + + 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; + } + } + } + } + } + return true; + } + + EntitiesData data; + uint i; + } + ShootGrid* grid; + BVHTree* tree; + BVHTree* static_tree; bool onBegin() { - grid = launcher.manager.getSystem!ShootGridManager().grid; - if(grid is null)return false; + //grid = launcher.manager.getSystem!ShootGridManager().grid; + tree = launcher.manager.getSystem!BVHBuilder().tree; + static_tree = launcher.manager.getSystem!StaticBVHBuilder().tree; + //if(grid is null)return false; + if(tree is null || static_tree is null)return false; else return true; } void onUpdate(EntitiesData data) { - EntityID id; + // State state; + // state.data = data; + // EntityID id; + // foreach(i; 0..data.length) + // { + // state.i = i; + // float radius = data.scale[i].x; + // if(grid.test(id, data.location[i] - radius, data.location[i] + radius, ubyte.max)) + // { + // state.test(id); + // } + // } + State state; + state.data = data; foreach(i; 0..data.length) { - float radius = data.scale[i].x; - //if(grid.test(id, data.location[i], ubyte.max)) - if(grid.test(id, data.location[i] - radius, data.location[i] + radius, ubyte.max)) - { - Entity* entity = launcher.manager.getEntity(id); - if(entity) - { - CLocation* location = entity.getComponent!CLocation; - CScale* scale = entity.getComponent!CScale; - if(location && scale) - { - 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; - - if(abs_rel_pos.x < half_scale.x + radius && - abs_rel_pos.y < half_scale.y + radius) - { - 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; - } - 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; - } - 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; - - 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, EBulletHit(data.entity[i].id,data.bullet[i].damage)); - //launcher.manager.removeEntity(data.entity[i].id); - } + state.i = i; + //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); + static_tree.test(bounding, cast(bool delegate(EntityID id))&state.test); } } } +struct DamageSystem +{ + mixin ECS.System!64; + + mixin ECS.ReadOnlyDependencies!(ShootGridDependency); + + struct EntitiesData + { + ///variable named "length" contain entites count + uint length; + const (Entity)[] entity; + CHitPoints[] hit_points; + } + + void handleEvent(Entity* entity, EDamage event) + { + EntityMeta meta = entity.getMeta(); + CHitPoints* hp = meta.getComponent!CHitPoints; + hp.value -= event.damage; + if(hp.value < 0)launcher.manager.removeEntity(entity.id); + } + +} + /*####################################################################################################################### ------------------------------------------------ Functions ------------------------------------------------------------------ #######################################################################################################################*/ @@ -239,7 +319,7 @@ struct BrickBreakerDemo { __gshared const (char)* tips = "Brick breaker demo. It's a game about destroying evil bricks."; - EntityTemplate* tmpl; + //EntityTemplate* tmpl; Texture texture; } @@ -268,12 +348,16 @@ void brickBreakerRegister() launcher.manager.registerComponent!CDamping; launcher.manager.registerComponent!CVelocityFactor; launcher.manager.registerComponent!CBall; + launcher.manager.registerComponent!CHitPoints; + + launcher.manager.registerEvent!EDamage; launcher.manager.registerSystem!MoveSystem(-100); launcher.manager.registerSystem!EdgeCollisionSystem(-99); launcher.manager.registerSystem!BallCollisionSystem(-79); launcher.manager.registerSystem!InputMovementSystem(-120); launcher.manager.registerSystem!DampingSystem(-120); + launcher.manager.registerSystem!DamageSystem(-120); launcher.manager.endRegister(); } @@ -289,11 +373,14 @@ void brickBreakerStart() EntityTemplate* brick_tmpl = launcher.manager.allocateTemplate( [CLocation.component_id, CScale.component_id, CColor.component_id, - CTexCoordsIndex.component_id, CShootGrid.component_id].staticArray + CTexCoordsIndex.component_id, CBVH.component_id, CHitPoints.component_id, + CAABB.component_id, CStatic.component_id].staticArray ); brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(304,40,16,8)*px); brick_tmpl.getComponent!CColor().value = 0x80206020; brick_tmpl.getComponent!CScale().value = vec2(16,8); + brick_tmpl.getComponent!CHitPoints().value = 2; + //brick_tmpl.getComponent!CAABB().bounding = AABB(vec2(),vec2()); EntityTemplate* big_brick_tmpl = launcher.manager.allocateTemplate(brick_tmpl); big_brick_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(320,32,16,16)*px); @@ -302,7 +389,8 @@ void brickBreakerStart() EntityTemplate* paddle_tmpl = launcher.manager.allocateTemplate( [CLocation.component_id, CScale.component_id, CInput.component_id, CTexCoordsIndex.component_id, CPaddle.component_id, CVelocity.component_id, - CDamping.component_id, CVelocityFactor.component_id, CShootGrid.component_id].staticArray + CDamping.component_id, CVelocityFactor.component_id, CBVH.component_id, + CAABB.component_id].staticArray ); paddle_tmpl.getComponent!CTexCoordsIndex().value = TexCoordsManager.instance.getCoordIndex(vec4(272,48,64,10)*px); paddle_tmpl.getComponent!CScale().value = vec2(64,10); @@ -330,7 +418,11 @@ void brickBreakerStart() launcher.gui_manager.addComponent(CBall(), "Ball"); launcher.gui_manager.addSystem(MoveSystem.system_id, "Move System"); + launcher.gui_manager.addSystem(EdgeCollisionSystem.system_id, "Edge Collision System"); launcher.gui_manager.addSystem(BallCollisionSystem.system_id, "Ball Collision System"); + launcher.gui_manager.addSystem(InputMovementSystem.system_id, "Input Movement System"); + launcher.gui_manager.addSystem(DampingSystem.system_id, "Damping System"); + launcher.gui_manager.addSystem(DamageSystem.system_id, "Damage System"); launcher.gui_manager.addTemplate(brick_tmpl, "Brick"); launcher.gui_manager.addTemplate(big_brick_tmpl, "Big Brick"); diff --git a/demos/source/demos/snake.d b/demos/source/demos/snake.d index 525b4ab..865ab75 100644 --- a/demos/source/demos/snake.d +++ b/demos/source/demos/snake.d @@ -72,7 +72,7 @@ struct Snake bool move_system = true; bool draw_system = true; - const int map_size = 18; + enum int map_size = 18; MapElement[map_size * map_size] map; @@ -83,7 +83,7 @@ struct Snake if(apple_tmpl)launcher.manager.freeTemplate(apple_tmpl); if(snake_tmpl)launcher.manager.freeTemplate(snake_tmpl); if(snake_destroy_particle)launcher.manager.freeTemplate(snake_destroy_particle); - texture.destory(); + texture.destroy(); } MapElement element(ivec2 pos) diff --git a/demos/source/demos/space_invaders.d b/demos/source/demos/space_invaders.d index 66be099..ece3c2b 100644 --- a/demos/source/demos/space_invaders.d +++ b/demos/source/demos/space_invaders.d @@ -64,7 +64,7 @@ struct SpaceInvaders { if(tmpl)launcher.manager.freeTemplate(tmpl); } - texture.destory(); + texture.destroy(); } } @@ -90,7 +90,7 @@ struct SceneGrid cells = Mallocator.makeArray!Cell(cells_count.x * cells_count.y); } - void destory() + void destroy() { if(cells) { @@ -707,6 +707,7 @@ struct ShipWeaponSystem void onDestroy() { + __xdtor(); /*launcher.manager.freeTemplate(laser1_tmpl); launcher.manager.freeTemplate(laser2_tmpl); launcher.manager.freeTemplate(main_weapon_tmpl);*/ diff --git a/demos/source/game_core/collision.d b/demos/source/game_core/collision.d index 75c46f8..794f8d8 100644 --- a/demos/source/game_core/collision.d +++ b/demos/source/game_core/collision.d @@ -1,10 +1,13 @@ module game_core.collision; import bubel.ecs.attributes; +import bubel.ecs.block_allocator; import bubel.ecs.core; import bubel.ecs.std; +import bubel.ecs.vector; import ecs_utils.math.vector; +import ecs_utils.utils; import game_core.basic; @@ -12,22 +15,54 @@ import game_core.basic; void registerCollisionModule(EntityManager* manager) { manager.registerDependency(ShootGridDependency); + manager.registerDependency(BVHDependency); + manager.registerDependency(StaticBVHDependency); manager.registerComponent!CShootGrid; manager.registerComponent!CShootGridMask; manager.registerComponent!CColliderScale; + manager.registerComponent!CBVH; + manager.registerComponent!CAABB; + manager.registerComponent!CStatic; manager.registerSystem!ShootGridManager(-80); manager.registerSystem!ShootGridCleaner(-101); + manager.registerSystem!BVHBuilder(-80); + manager.registerSystem!StaticBVHBuilder(-80); + //manager.registerSystem!BVHBuilder2(-79); + manager.registerSystem!AABBUpdater(-81); } enum ShootGridDependency = "ShootGridDependency"; +enum BVHDependency = "BVHDependency"; +enum StaticBVHDependency = "StaticBVHDependency"; struct CShootGrid { mixin ECS.Component; } +struct CBVH +{ + mixin ECS.Component; + + uint index; +} + +struct CStatic +{ + mixin ECS.Component; +} + +struct CAABB +{ + mixin ECS.Component; + + alias bounding this; + + AABB bounding; +} + struct CShootGridMask { mixin ECS.Component; @@ -46,6 +81,7 @@ struct CColliderScale vec2 value = vec2(16,16); } + struct ShootGrid { @@ -84,7 +120,7 @@ struct ShootGrid foreach(j; ibeg.x .. iend.x) { nodes[i * size.x + j] = id; - masks[i * size.x +j] = mask; + masks[i * size.x + j] = mask; } } } @@ -229,4 +265,759 @@ struct ShootGridManager } } +} + +struct AABB +{ + vec2 size() + { + return max-min; + } + + vec2 center() + { + return (max+min) * 0.5; + } + + float area() + { + return size.x * size.y; + } + + void set(ref AABB base, vec2 position, float angle, vec2 scale) + { + import std.algorithm.comparison : max; + + float sr = sinf(angle); + float cr = cosf(angle); + /*mat2 m = mat2(cr,-sr, + sr,cr);*/ + + + //vec2 pos = ;//m * ((base.max + base.min)*0.5*scale); + vec2 size = (base.max - base.min)*scale; + vec2[2] axis = [vec2(cr*size.x,sr*size.y),vec2(-sr*size.x,cr*size.y)]; + + this.max.x = max(fabs(axis[0].x),fabs(axis[1].x)); + this.max.y = max(fabs(axis[0].y),fabs(axis[1].y)); + + this.min = -this.max; + + this.min += center + position; + this.max += center + position; + } + + void set(ref AABB base, vec2 position, vec2 scale) + { + vec2 size = (base.max - base.min)*scale; + + this.min = -size; + this.max = size; + + this.min += center + position; + this.max += center + position; + } + + void set(ref AABB base, vec2 position, float angle) + { + import std.algorithm.comparison : max; + + float sr = sinf(angle); + float cr = cosf(angle); + /*mat2 m = mat2(cr,-sr, + sr,cr);*/ + + + //vec2 pos = ;//m * ((base.max + base.min)*0.5*scale); + vec2 size = (base.max - base.min);//*scale; + vec2[2] axis = [vec2(cr*size.x,sr*size.y),vec2(-sr*size.x,cr*size.y)]; + + this.max.x = max(fabs(axis[0].x),fabs(axis[1].x)); + this.max.y = max(fabs(axis[0].y),fabs(axis[1].y)); + + this.min = -this.max; + + this.min += center + position; + this.max += center + position; + } + + void set(ref AABB base, vec2 position) + { + min = base.min + position; + max = base.max + position; + } + + vec2 min; + vec2 max; +} + +bool test(AABB a, AABB b) +{ + if((a.max.x>b.min.x && a.max.y>b.min.y) && + (a.min.x b.max.x && a.max.y > b.max.y)return 2; + else if((a.max.x>b.min.x && a.max.y>b.min.y) && + (a.min.xb.min.x && point.y>b.min.y) && + (point.x Date: Sat, 22 Aug 2020 11:37:23 +0200 Subject: [PATCH 53/58] ECS fixes -fixed bug with addEntityCopy (on create was called for bad entity, and incorrect block was added to update) -added function to retrieve Component pointer from Entity (not template function) -fixed thread_pool bug --- demos/external/sources/mmutils/thread_pool.d | 4 +-- source/bubel/ecs/entity.d | 30 +++++++++++++++++--- source/bubel/ecs/manager.d | 6 ++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/demos/external/sources/mmutils/thread_pool.d b/demos/external/sources/mmutils/thread_pool.d index b830026..bd05fe5 100644 --- a/demos/external/sources/mmutils/thread_pool.d +++ b/demos/external/sources/mmutils/thread_pool.d @@ -396,8 +396,8 @@ version (MM_USE_POSIX_THREADS) void start(DG dg) { threadStart = dg; - int ok = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this); - if(!ok)handle = pthread_t(); + int err = pthread_create(&handle, null, &threadRunFunc, cast(void*)&this); + if(err)handle = pthread_t(); //assert(ok == 0); } diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index 4cd0e70..f713c78 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -34,12 +34,23 @@ struct Entity */ T* getComponent(T)() const { - EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); + /*EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); EntityManager.EntityInfo* info = block.type_info; if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) return null; - return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof); + return cast(T*)(cast(void*)block + info.deltas[T.component_id] + block.entityIndex(&this) * T.sizeof);*/ + return cast(T*)getComponent(T.component_id); + } + + void* getComponent(ushort component_id) const + { + EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); + EntityManager.EntityInfo* info = block.type_info; + if (component_id >= info.deltas.length || info.deltas[component_id] == 0) + return null; + + return (cast(void*)block + info.deltas[component_id] + block.entityIndex(&this) * gEM.components[component_id].size); } bool hasComponent(ushort component_id) const @@ -66,10 +77,21 @@ struct EntityMeta T* getComponent(T)() const { - const (EntityManager.EntityInfo)* info = block.type_info; + /*const (EntityManager.EntityInfo)* info = block.type_info; if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) return null; - return cast(T*)(cast(void*)block + block.type_info.deltas[T.component_id] + index * T.sizeof); + return cast(T*)(cast(void*)block + info.deltas[T.component_id] + index * T.sizeof);*/ + return cast(T*)getComponent(T.component_id); + } + + void* getComponent(ushort component_id) const + { + const (EntityManager.EntityInfo)* info = block.type_info; + + if (component_id >= info.deltas.length || info.deltas[component_id] == 0) + return null; + + return (cast(void*)block + info.deltas[component_id] + index * gEM.components[component_id].size); } bool hasComponent(ushort component_id) const diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index c26a414..8ef4a20 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -2513,17 +2513,17 @@ export struct EntityManager { ushort size = components[comp].size; if (size != 0) - memcpy(cast(void*) new_block + info.deltas[comp] + size * new_id, + memcpy(cast(void*) new_block + info.deltas[comp] + new_id * size, cast(void*) block + info.deltas[comp] + size * index, size); if (components[comp].create_callback) { components[comp].create_callback( - cast(void*) block + info.deltas[comp] + new_id * size); + cast(void*) new_block + info.deltas[comp] + new_id * size); } } - if (new_index == 1 && info.update_block == block) + if (new_index == 1 && info.update_block == new_block) threads[threadID].infosToUpdate.add(info); Entity* new_entity = cast(Entity*) start; From 13c82acad49fe26a3343e488777b20f3cba89234 Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 25 Sep 2020 10:50:11 +0200 Subject: [PATCH 54/58] -removed some unused code --- demos/.gitignore | 3 ++- source/bubel/ecs/manager.d | 37 ------------------------------------- 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/demos/.gitignore b/demos/.gitignore index 974bbb2..d74e2b0 100644 --- a/demos/.gitignore +++ b/demos/.gitignore @@ -15,4 +15,5 @@ !emscripten_shell.html !emscripten_multi_shell.html !compile_android.py -.dub \ No newline at end of file +.dub +Android \ No newline at end of file diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 8ef4a20..1514cbc 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -2542,43 +2542,6 @@ export struct EntityManager */ export Entity* addEntity(EntityTemplate* tmpl) { - /*EntityInfo* info = tmpl.info; - - ushort index = 0; - EntitiesBlock* block; - do - { - block = findBlockWithFreeSpaceMT(info); - index = block.added_count.atomicOp!"+="(1); - } - while (block.entities_count + index > info.max_entities); - - uint id = (block.entities_count + index - 1); //block.added_count); - - void* data_begin = block.dataBegin(); - void* start = data_begin + EntityID.sizeof * id; - - foreach (comp; info.components) - { - memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id, - tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size); - - if (components[comp].create_callback) - { - components[comp].create_callback( - cast(void*) block + info.deltas[comp] + id * components[comp].size); - } - - } - - if (index == 1) - threads[threadID].infosToUpdate.add(block); - - Entity* entity = cast(Entity*) start; - entity.id = id_manager.getNewID(); - id_manager.update(*entity); //entity.updateID(); - - return entity;*/ return addEntity(tmpl, null); } From 3c1c67efd0ebf6d501e7dfc229f172db3e984776 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sun, 3 Jan 2021 13:05:48 +0100 Subject: [PATCH 55/58] -added filterEntity callback (used to filter EntityInfos for system, better control than simply @optional) -removed some redundant code (two times same code) -added some common functions --- source/bubel/ecs/entity.d | 9 ++++ source/bubel/ecs/manager.d | 63 +++++++++++++--------- source/bubel/ecs/system.d | 2 + tests/basic.d | 106 ++++++++++++++++++++++++++++++++++++- 4 files changed, 155 insertions(+), 25 deletions(-) diff --git a/source/bubel/ecs/entity.d b/source/bubel/ecs/entity.d index f713c78..72131b5 100644 --- a/source/bubel/ecs/entity.d +++ b/source/bubel/ecs/entity.d @@ -128,6 +128,15 @@ export struct EntityTemplate if(T.component_id >= info.tmpl_deltas.length || info.tmpl_deltas[T.component_id] == ushort.max)return null; return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]); } + + /************************************************************************************************************************ + Get specified component. If component doesn't exist function return null. Returned pointer is valid during EntityTemplate lifetime. + */ + void* getComponent(ushort component_id) const nothrow @nogc + { + if(component_id >= info.tmpl_deltas.length || info.tmpl_deltas[component_id] == ushort.max)return null; + return cast(void*)(entity_data.ptr + info.tmpl_deltas[component_id]); + } } /************************************************************************************************************************ diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 1514cbc..e82add3 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -1110,6 +1110,32 @@ export struct EntityManager } } + static void catchEntityFilterFunction(string func_name, RetType = void)(void** member) + { + static if (hasMember!(Sys, func_name)) + { + foreach (func; __traits(getOverloads, Sys, func_name)) + { + static if ((Parameters!(func)).length == 1 + && is(Parameters!(func)[0] == EntityInfo*) + && is(ReturnType!(func) == RetType)) + { + static RetType callFunc(void* system_pointer, EntityInfo* info) + { + Sys* s = cast(Sys*) system_pointer; + static if (is(RetTyp == void)) + mixin("s." ~ func_name ~ "(info)"); + else + return mixin("s." ~ func_name ~ "(info)"); + } + + *member = cast(void*)&callFunc; + break; + } + } + } + } + catchFunction!("onEnable")(&system.m_enable); catchFunction!("onDisable")(&system.m_disable); catchFunction!("onCreate")(&system.m_create); @@ -1121,6 +1147,8 @@ export struct EntityManager catchEntityFunction!("onRemoveEntity")(&system.m_remove_entity); catchEntityFunction!("onChangeEntity")(&system.m_change_entity); + catchEntityFilterFunction!("filterEntity", bool)(&system.m_filter_entity); + system.m_system_pointer = cast(void*) Mallocator.make!Sys; system.m_priority = priority; //(cast(Sys*) system.m_system_pointer).__ecsInitialize(); @@ -2035,6 +2063,9 @@ export struct EntityManager is_: } + ///call Custom Entity Filter test if function exists + if(system.m_filter_entity && !(cast(bool function(void* system_pointer, EntityInfo* info) @nogc nothrow)system.m_filter_entity)(system, &entity))return; + entity.systems[system_id] = true; } @@ -2077,30 +2108,8 @@ export struct EntityManager { System* system = &systems[system_id]; - if (system.m_excluded_components) - { - foreach (id; system.m_excluded_components) - { - foreach (id2; info.components) - { - if (id == id2) - return; - } - } - } - - foreach (id; system.m_components) - { - foreach (i2, id2; info.components) - { - if (id2 == id) - goto is_; - } - return; - is_: - } - - info.systems[system_id] = true; + connectListenerToEntityInfo(info, system_id); + if(!info.systems[system_id])return; uint index = 0; for (; index < passes[system.m_pass].system_callers.length; index++) @@ -3483,6 +3492,12 @@ export struct EntityManager return new_info; } + export bool hasComponent(ushort component_id) + { + if(component_id >= deltas.length || !deltas[component_id])return false; + return true; + } + export ~this() @nogc nothrow { if (components) diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index cd8d2e3..e571e8b 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -194,6 +194,8 @@ package: void* m_remove_entity; void* m_change_entity; + void* m_filter_entity; + //void function(ref EntityManager.CallData data) m_initialize; //void function(ref EntityManager.CallData data) m_deinitilize; void* m_initialize; diff --git a/tests/basic.d b/tests/basic.d index 59f88e2..4a9dc6f 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -139,6 +139,7 @@ void afterEveryTest() unittest { EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_); Entity* entity = gEM.addEntity(tmpl_); EntityMeta meta = entity.getMeta(); assert(meta.hasComponent(CInt.component_id)); @@ -1615,4 +1616,107 @@ unittest assert(pass.system_callers[3].dependencies[2].system_id == TestSystem3.system_id); assert(pass.system_callers[4].dependencies[0].system_id == TestSystem2.system_id); assert(pass.system_callers[4].dependencies[1].system_id == TestSystem4.system_id); -} \ No newline at end of file +} + + +@("CustomFilter") +unittest +{ + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @optional CInt[] int_; + @optional CLong[] long_; + @optional CFloat[] float_; + @optional CDouble[] double_; + } + + bool filterEntity(EntityManager.EntityInfo* info) + { + if(!info.hasComponent(CInt.component_id))return false; + int one_from = 0; + if(info.hasComponent(CLong.component_id))one_from++; + if(info.hasComponent(CFloat.component_id))one_from++; + if(info.hasComponent(CDouble.component_id))one_from++; + if(one_from == 1)return true; + return false; + } + + void onUpdate(EntitiesData entities) + { + updates++; + } + + uint updates = 0; + } + + struct TestSystem2 + { + mixin ECS.System; + + struct EntitiesData + { + uint length; + @optional CInt[] int_; + @optional CLong[] long_; + @optional CFloat[] float_; + @optional CDouble[] double_; + } + + bool filterEntity(EntityManager.EntityInfo* info) + { + if(info.hasComponent(CInt.component_id) && info.hasComponent(CFloat.component_id) && !info.hasComponent(CLong.component_id) && !info.hasComponent(CDouble.component_id))return true; + if(info.hasComponent(CLong.component_id) && info.hasComponent(CDouble.component_id) && !info.hasComponent(CInt.component_id) && !info.hasComponent(CFloat.component_id))return true; + return false; + } + + void onUpdate(EntitiesData entities) + { + updates++; + } + + uint updates = 0; + } + + gEM.beginRegister(); + + gEM.registerSystem!TestSystem(0); + gEM.registerSystem!TestSystem2(1); + + gEM.endRegister(); + + + EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CLong.component_id, CFloat.component_id, CDouble.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_); + EntityTemplate* tmpl_2 = gEM.allocateTemplate([CInt.component_id, CFloat.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_2); + EntityTemplate* tmpl_3 = gEM.allocateTemplate([CLong.component_id, CDouble.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_3); + EntityTemplate* tmpl_4 = gEM.allocateTemplate([CInt.component_id, CLong.component_id, CDouble.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_4); + EntityTemplate* tmpl_5 = gEM.allocateTemplate([CInt.component_id, CDouble.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_5); + EntityTemplate* tmpl_6 = gEM.allocateTemplate([CDouble.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_6); + + gEM.addEntity(tmpl_); + gEM.addEntity(tmpl_2); + gEM.addEntity(tmpl_3); + gEM.addEntity(tmpl_4); + gEM.addEntity(tmpl_5); + gEM.addEntity(tmpl_6); + + TestSystem* test_system = gEM.getSystem!TestSystem; + TestSystem2* test_system2 = gEM.getSystem!TestSystem2; + + gEM.begin(); + gEM.update(); + gEM.end(); + + assert(test_system.updates == 2); + assert(test_system2.updates == 2); +} From 84ba5f9eb57d85b48c50ce46df87d64c43ad55f2 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sun, 3 Jan 2021 13:08:29 +0100 Subject: [PATCH 56/58] -fixed emscripten compilation --- .../android/bindbc/loader/sharedlib.d | 53 ------------------- demos/external/sources/cimgui/cimgui.d | 10 +++- .../wasm_imports/bindbc/sdl/bind/sdllog.d | 6 ++- demos/source/demos/brick_breaker.d | 2 + demos/utils/source/ecs_utils/gfx/renderer.d | 30 +++++------ demos/utils/source/ecs_utils/utils.d | 6 ++- 6 files changed, 36 insertions(+), 71 deletions(-) diff --git a/demos/external/android/bindbc/loader/sharedlib.d b/demos/external/android/bindbc/loader/sharedlib.d index ab6c444..ca3c654 100644 --- a/demos/external/android/bindbc/loader/sharedlib.d +++ b/demos/external/android/bindbc/loader/sharedlib.d @@ -213,8 +213,6 @@ void addErr(const(char)* errstr, const(char)* message) version(Windows) { import core.sys.windows.windows; - extern(Windows) @nogc nothrow alias pSetDLLDirectory = BOOL function(const(char)*); - pSetDLLDirectory setDLLDirectory; void* loadLib(const(char)* name) { @@ -255,57 +253,6 @@ version(Windows) } else strncpy(buf, "Unknown Error\0", len); } - - /** - Adds a path to the default search path on Windows, replacing the path set in a previous - call to the same function. - - Any path added to this function will be added to the default DLL search path as documented at - https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setdlldirectoryw. - - Generally, when loading DLLs on a path that is not on the search path, e.g., from a subdirectory - of the application, the path should be prepended to the DLL name passed to the load function, - e.g., "dlls\\SDL2.dll". If `setCustomLoaderSearchPath(".\\dlls")` is called first, then the subdirectory - will become part of the DLL search path and the path may be omitted from the load function. (Be - aware that ".\\dlls" is relative to the current working directory, which may not be the application - directory, so the path should be built appropriately.) - - Some DLLs may depend on other DLLs, perhaps even attempting to load them dynamically at run time - (e.g., SDL2_image only loads dependencies such as libpng if it is initialized at run time with - PNG support). In this case, if the DLL and its dependencies are placed in a subdirectory and - loaded as e.g., "dlls\\SDL2_image.dll", then it will not be able to find its dependencies; the - system loader will look for them on the regular DLL search path. When that happens, the solution - is to call `setCustomLoaderSearchPath` with the subdirectory before initializing the library. - - Calling this function with `null` as the argument will reset the default search path. - - When the function returns `false`, the relevant `ErrorInfo` is added to the global error list and can - be retrieved by looping through the array returned by the `errors` function. - - When placing DLLs in a subdirectory of the application, it should be considered good practice to - call `setCustomLoaderSearchPath` to ensure all DLLs load properly. It should also be considered good - practice to reset the default search path once all DLLs are loaded. - - This function is only available on Windows, so any usage of it should be preceded with - `version(Windows)`. - - Params: - path = the path to add to the DLL search path, or `null` to reset the default. - - Returns: - `true` if the path was successfully added to the DLL search path, otherwise `false`. - */ - public - bool setCustomLoaderSearchPath(const(char)* path) - { - if(!setDLLDirectory) { - auto lib = load("Kernel32.dll"); - if(lib == invalidHandle) return false; - lib.bindSymbol(cast(void**)&setDLLDirectory, "SetDllDirectoryA"); - if(!setDLLDirectory) return false; - } - return setDLLDirectory(path) != 0; - } } else version(Posix) { import core.sys.posix.dlfcn; diff --git a/demos/external/sources/cimgui/cimgui.d b/demos/external/sources/cimgui/cimgui.d index 507f616..1fc119f 100644 --- a/demos/external/sources/cimgui/cimgui.d +++ b/demos/external/sources/cimgui/cimgui.d @@ -2,9 +2,17 @@ //based on imgui.h file version "1.73" from Dear ImGui https://github.com/ocornut/imgui module cimgui.cimgui; -import core.stdc.stdarg; +// import core.stdc.stdarg; //import core.stdc.stdio; +version(WebAssembly) +{ + alias va_list = char*; + pragma(LDC_va_start) + void va_start(T)(out va_list ap, ref T parmn) @nogc; +} +else import core.stdc.stdarg; + extern (C): //alias ImU64 = ulong; diff --git a/demos/external/wasm_imports/bindbc/sdl/bind/sdllog.d b/demos/external/wasm_imports/bindbc/sdl/bind/sdllog.d index 3ff5b4c..36bf76d 100644 --- a/demos/external/wasm_imports/bindbc/sdl/bind/sdllog.d +++ b/demos/external/wasm_imports/bindbc/sdl/bind/sdllog.d @@ -6,7 +6,11 @@ module bindbc.sdl.bind.sdllog; -import core.stdc.stdarg : va_list; +version(WebAssembly) +{ + alias va_list = char*; +} +else import core.stdc.stdarg : va_list; import bindbc.sdl.config; enum SDL_MAX_LOG_MESSAGE = 4096; diff --git a/demos/source/demos/brick_breaker.d b/demos/source/demos/brick_breaker.d index c15c503..a170076 100644 --- a/demos/source/demos/brick_breaker.d +++ b/demos/source/demos/brick_breaker.d @@ -416,6 +416,8 @@ void brickBreakerStart() launcher.gui_manager.addComponent(CInput(), "Velocity"); launcher.gui_manager.addComponent(CDamping(), "Damping"); launcher.gui_manager.addComponent(CBall(), "Ball"); + launcher.gui_manager.addComponent(CBVH(), "BVH"); + launcher.gui_manager.addComponent(CAABB(), "AABB"); launcher.gui_manager.addSystem(MoveSystem.system_id, "Move System"); launcher.gui_manager.addSystem(EdgeCollisionSystem.system_id, "Edge Collision System"); diff --git a/demos/utils/source/ecs_utils/gfx/renderer.d b/demos/utils/source/ecs_utils/gfx/renderer.d index ef53543..b2091cf 100644 --- a/demos/utils/source/ecs_utils/gfx/renderer.d +++ b/demos/utils/source/ecs_utils/gfx/renderer.d @@ -187,6 +187,20 @@ struct Renderer } } + struct DrawData + { + Texture texture; + vec2 position; + vec2 size; + vec4 coords; + short depth = 0; + uint color = uint.max; + float angle = 0; + uint material_id = 0; + uint mesh_id = 0; + uint thread_id = 0; + } + struct Thread { //Vector!VertexBlock block; @@ -430,20 +444,6 @@ struct Renderer } - struct DrawData - { - Texture texture; - vec2 position; - vec2 size; - vec4 coords; - short depth = 0; - uint color = uint.max; - float angle = 0; - uint material_id = 0; - uint mesh_id = 0; - uint thread_id = 0; - } - //void draw(Texture tex, vec2 pos, vec2 size, vec4 coords, short depth = 0, uint color = uint.max, float angle = 0, uint material_id = 0, uint mesh_id = 0, uint thread_id = 0) void draw(scope ref const(DrawData) data) { @@ -570,7 +570,7 @@ struct Renderer memcpy(ptr+16,pos.data.ptr,8); memcpy(ptr+32,coords.data.ptr,16);*/ - short[] verts = cast(short[])block.batch_vertices; + short[] verts = (cast(short*)block.batch_vertices.ptr)[0..block.batch_vertices.length>>1]; uint item_id = block.items; uint mesh_id = data.mesh_id; diff --git a/demos/utils/source/ecs_utils/utils.d b/demos/utils/source/ecs_utils/utils.d index 5073d4e..1896856 100644 --- a/demos/utils/source/ecs_utils/utils.d +++ b/demos/utils/source/ecs_utils/utils.d @@ -77,7 +77,11 @@ version(GNU) else { extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; - public import std.array : staticArray; + // public import std.array : staticArray; + pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) + { + return a; + } } extern(C) int rand() nothrow @nogc @trusted; From edaa2286f436380e3cb3d244523268485b2bda12 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 9 Jan 2021 14:30:56 +0100 Subject: [PATCH 57/58] -fix some memory leaks in unittests -change name in dub.json ecs->bubel_ecs -add dependeny in meson.build --- dub.json | 2 +- meson.build | 2 ++ tests/basic.d | 4 ++++ tests/tests.d | 1 + 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dub.json b/dub.json index ba935ee..4eca570 100755 --- a/dub.json +++ b/dub.json @@ -1,5 +1,5 @@ { - "name": "ecs", + "name": "bubel_ecs", "authors": [ "Michał Masiukiewicz", "Dawid Masiukiewicz" ], diff --git a/meson.build b/meson.build index 2a71fc7..4951584 100644 --- a/meson.build +++ b/meson.build @@ -67,6 +67,8 @@ ecs_lib = library('ecs', src, include_directories : [tests_inc, inc], d_args: ar executable('tests', tests_src, include_directories : [tests_inc, inc], d_args: args, link_args: link_args, link_with: ecs_lib) +bubel_ecs_dep = declare_dependency(include_directories : [inc], link_with : ecs_lib) + if BuildDemos_opt subdir('demos/utils') subdir('demos') diff --git a/tests/basic.d b/tests/basic.d index 4a9dc6f..bcea918 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -158,6 +158,7 @@ unittest unittest { EntityTemplate* tmpl_ = gEM.allocateTemplate([CInt.component_id, CFloat.component_id, CFlag.component_id].staticArray); + scope(exit)gEM.freeTemplate(tmpl_); assert(tmpl_.info.components.length == 3); assert(tmpl_.info.size == (CInt.sizeof + CFloat.sizeof + EntityID.sizeof)); assert(tmpl_.getComponent!CInt); @@ -346,6 +347,7 @@ unittest assert(*tmpl_7.getComponent!CLong == 10); gEM.freeTemplate(tmpl_d); + gEM.freeTemplate(tmpl_cp); gEM.freeTemplate(tmpl_); gEM.freeTemplate(tmpl_2); gEM.freeTemplate(tmpl_3); @@ -369,6 +371,8 @@ unittest assert(*tmpl_.getComponent!CInt == 1); assert(*tmpl_.getComponent!CFloat == 2.0); assert(tmpl_.info == tmpl_2.info); + gEM.freeTemplate(tmpl_); + gEM.freeTemplate(tmpl_2); } @("MultiRegister") diff --git a/tests/tests.d b/tests/tests.d index 9f69987..d539f89 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -1014,6 +1014,7 @@ else: writeEntityComponents(gEM.getEntity(entity)); //import std.stdio; ////writeln((cast(uint*)tmpl.info.first_block)[0..48]); + gEM.freeTemplate(tmpl_empty); gEM.freeTemplate(tmpl); gEM.freeTemplate(tmpl2); gEM.freeTemplate(copy_tempalte); From 9cef882faf3cd182af49893a50dfc0cfb7ee220f Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 9 Jan 2021 15:13:53 +0100 Subject: [PATCH 58/58] -change targetName to "ecs" in order to fix CI guild (need to be renamed in CI in future) --- dub.json | 1 + 1 file changed, 1 insertion(+) diff --git a/dub.json b/dub.json index 4eca570..1a99040 100755 --- a/dub.json +++ b/dub.json @@ -1,5 +1,6 @@ { "name": "bubel_ecs", + "targetName" : "ecs", "authors": [ "Michał Masiukiewicz", "Dawid Masiukiewicz" ],