1 /** 2 Copyright: Copyright (c) 2016-2018 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.hash.map; 13 import voxelman.container.hash.set; 14 import voxelman.world.storage; 15 import voxelman.entity.plugin; 16 import voxelman.net.plugin; 17 18 struct EntityObserverManager 19 { 20 HashMap!(ChunkWorldPos, HashSet!EntityId) chunkToEntitySet; 21 //HashSet!ChunkWorldPos observedEntityChunks; 22 HashMap!(EntityId, ChunkWorldPos) entityToChunk; 23 24 void addEntity(EntityId eid, ChunkWorldPos cwp) 25 { 26 entityToChunk[eid] = cwp; 27 addEntityToChunk(eid, cwp); 28 } 29 30 void updateEntityPos(EntityId eid, ChunkWorldPos newCwp) 31 { 32 bool wasCreated; 33 ChunkWorldPos* cwp = entityToChunk.getOrCreate(eid, wasCreated, newCwp); 34 if (wasCreated) 35 { 36 addEntityToChunk(eid, newCwp); 37 } 38 else if (*cwp != newCwp) 39 { 40 removeEntityFromChunk(eid, *cwp); 41 addEntityToChunk(eid, newCwp); 42 *cwp = newCwp; 43 } 44 } 45 46 void removeEntity(EntityId eid) 47 { 48 if (auto cwp = eid in entityToChunk) 49 { 50 removeEntityFromChunk(eid, *cwp); 51 entityToChunk.remove(eid); 52 } 53 } 54 55 private void addEntityToChunk(EntityId eid, ChunkWorldPos cwp) 56 { 57 auto entitySetPtr = chunkToEntitySet.getOrCreate(cwp); 58 entitySetPtr.put(eid); 59 //observedEntityChunks.put(cwp); 60 } 61 62 private void removeEntityFromChunk(EntityId eid, ChunkWorldPos cwp) 63 { 64 if (auto set = cwp in chunkToEntitySet) 65 { 66 set.remove(eid); 67 if (set.empty) 68 { 69 chunkToEntitySet.remove(cwp); 70 //observedEntityChunks.remove(cwp); 71 } 72 } 73 } 74 75 package NetworkSaver netSaver; 76 package ChunkObserverManager chunkObserverManager; 77 package NetServerPlugin connection; 78 package EntityManager* eman; 79 80 void sendEntitiesToObservers() 81 { 82 connection.sendToAll(ComponentSyncStartPacket()); 83 foreach(cwp, entities; chunkToEntitySet) 84 { 85 auto observers = chunkObserverManager.getChunkObservers(cwp); 86 if (observers.length == 0) continue; 87 88 eman.savePartial(netSaver, entities); 89 connection.sendTo(observers, ComponentSyncPacket(netSaver.data)); 90 netSaver.reset(); 91 } 92 connection.sendToAll(ComponentSyncEndPacket()); 93 } 94 }