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 }