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 module voxelman.world.storage.dimensionobservermanager;
7 
8 import voxelman.log;
9 import voxelman.container.buffer;
10 import voxelman.container.hashmap;
11 import voxelman.container.multihashset;
12 import netlib : SessionId;
13 import voxelman.core.config : DimensionId;
14 
15 struct DimensionObserverManager {
16 	void delegate(DimensionId, SessionId) dimensionObserverAdded;
17 	HashMap!(DimensionId, MultiHashSet!SessionId) dimObservers;
18 	// current observer dimension
19 	HashMap!(SessionId, DimensionId) observerDimensions;
20 
21 	void updateObserver(SessionId sessionId, DimensionId dimensionId) {
22 		DimensionId* observerDim = sessionId in observerDimensions;
23 		if (observerDim is null)
24 		{
25 			observerDimensions[sessionId] = dimensionId;
26 			dimensionObserverAdded(dimensionId, sessionId);
27 			return;
28 		}
29 
30 		if (dimensionId != (*observerDim))
31 		{
32 			if (auto oldObservers = (*observerDim) in dimObservers)
33 				oldObservers.remove(sessionId);
34 			auto observers = dimObservers.getOrCreate(dimensionId);
35 			if (observers.add(sessionId))
36 				dimensionObserverAdded(dimensionId, sessionId);
37 			(*observerDim) = dimensionId;
38 		}
39 	}
40 
41 	void removeObserver(SessionId sessionId) {
42 		if (auto observerDim = sessionId in observerDimensions)
43 		{
44 			if (auto oldObservers = (*observerDim) in dimObservers)
45 			{
46 				oldObservers.remove(sessionId);
47 			}
48 			observerDimensions.remove(sessionId);
49 		}
50 	}
51 
52 	// can use result in foreach
53 	auto getDimensionObservers(DimensionId dimensionId) {
54 		return dimObservers.get(dimensionId);
55 	}
56 }