From 3d98b0ee5eeac61a71cff1015e4d8cc59a652761 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 23 May 2020 10:55:31 +0200 Subject: [PATCH] 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(); } }