1 /** 2 Copyright: Copyright (c) 2016-2017 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 7 module voxelman.entity.entityobservermanager; 8 9 import voxelman.log; 10 import datadriven.api; 11 import datadriven.entityman; 12 import voxelman.container.hashmap; 13 import voxelman.container.hashset; 14 import voxelman.container.intkeyhashset; 15 import voxelman.world.storage; 16 import voxelman.entity.plugin; 17 import voxelman.net.plugin; 18 19 struct EntityObserverManager 20 { 21 HashMap!(ulong, IntKeyHashSet!EntityId) chunkToEntitySet; 22 //HashSet!ChunkWorldPos observedEntityChunks; 23 HashMap!(EntityId, ChunkWorldPos) entityToChunk; 24 25 void addEntity(EntityId eid, ChunkWorldPos cwp) 26 { 27 entityToChunk[eid] = cwp; 28 addEntityToChunk(eid, cwp); 29 } 30 31 void updateEntityPos(EntityId eid, ChunkWorldPos newCwp) 32 { 33 ChunkWorldPos* cwp = entityToChunk.getOrCreate(eid, newCwp); 34 if (*cwp != newCwp) 35 { 36 removeEntityFromChunk(eid, *cwp); 37 addEntityToChunk(eid, newCwp); 38 } 39 *cwp = newCwp; 40 } 41 42 void removeEntity(EntityId eid) 43 { 44 if (auto cwp = eid in entityToChunk) 45 { 46 removeEntityFromChunk(eid, *cwp); 47 entityToChunk.remove(eid); 48 } 49 } 50 51 private void addEntityToChunk(EntityId eid, ChunkWorldPos cwp) 52 { 53 auto entitySetPtr = chunkToEntitySet.getOrCreate(cwp.asUlong); 54 entitySetPtr.put(eid); 55 //observedEntityChunks.put(cwp); 56 } 57 58 private void removeEntityFromChunk(EntityId eid, ChunkWorldPos cwp) 59 { 60 if (auto set = cwp.asUlong in chunkToEntitySet) 61 { 62 set.remove(eid); 63 if (set.empty) 64 { 65 chunkToEntitySet.remove(cwp.asUlong); 66 //observedEntityChunks.remove(cwp); 67 } 68 } 69 } 70 71 package NetworkSaver netSaver; 72 package ChunkObserverManager chunkObserverManager; 73 package NetServerPlugin connection; 74 package EntityManager* eman; 75 76 void sendEntitiesToObservers() 77 { 78 connection.sendToAll(ComponentSyncStartPacket()); 79 foreach(cwp, entities; chunkToEntitySet) 80 { 81 auto observers = chunkObserverManager.getChunkObservers(ChunkWorldPos(cwp)); 82 //auto entities = chunkToEntitySet[cwp]; 83 eman.savePartial(netSaver, entities); 84 connection.sendTo(observers, ComponentSyncPacket(netSaver.data)); 85 netSaver.reset(); 86 } 87 connection.sendToAll(ComponentSyncEndPacket()); 88 } 89 }