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