From e6dfc1861bba50e6c940b3015b9625640d68831d Mon Sep 17 00:00:00 2001 From: Daniil Date: Sun, 5 Aug 2018 22:56:16 +0700 Subject: [PATCH] Implemented simple resource lock fetchers --- .../mc/core/events/SharedResourceManager.java | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/event-loop/src/main/java/mc/core/events/SharedResourceManager.java b/event-loop/src/main/java/mc/core/events/SharedResourceManager.java index 8fb486f..23bbabd 100644 --- a/event-loop/src/main/java/mc/core/events/SharedResourceManager.java +++ b/event-loop/src/main/java/mc/core/events/SharedResourceManager.java @@ -1,24 +1,64 @@ package mc.core.events; +import lombok.extern.slf4j.Slf4j; +import mc.core.Location; import mc.core.events.api.LockableResource; import mc.core.events.api.Plugin; +import mc.core.events.api.interfaces.LocationProvidingEvent; +import mc.core.events.api.interfaces.PlayerProvidingEvent; +import mc.core.events.api.interfaces.WorldProvidingEvent; import mc.core.events.lock.PoorMansLock; +import mc.core.player.Player; +import mc.core.world.World; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +@Slf4j public class SharedResourceManager { private Map pluginLocks = new ConcurrentHashMap<>(); + // TODO: Memory leak HERE. Fix with introducing field to Player class + private Map playerLocks = new ConcurrentHashMap<>(); + // TODO: Memory leak HERE. Fix with introducing field to World class + private Map worldLocks = new ConcurrentHashMap<>(); public PoorMansLock getPluginLock(Plugin plugin) { return pluginLocks.computeIfAbsent(plugin, s -> new PoorMansLock()); } + public PoorMansLock getPlayerLock(Player player) { + return playerLocks.computeIfAbsent(player, s -> new PoorMansLock()); + } + + public PoorMansLock getWorldLock(World world) { + return worldLocks.computeIfAbsent(world, s -> new PoorMansLock()); + } + + private T require(LockableResource resource, Event event, Class inter) { + if (inter.isInstance(event)) { + //noinspection unchecked + return (T) event; + } else + throw new IllegalArgumentException("Unable to lock " + resource + " while attempting to process event. Event " + event.getClass().getSimpleName() + " must implement " + inter); + } + public Collection getAnnotationLocks(LockableResource resource, Event event) { - // TODO: Implement - return Collections.emptyList(); + switch (resource) { + case PLAYER: + return require(resource, event, PlayerProvidingEvent.class).getAssociatedPlayers().stream().map(this::getPlayerLock).collect(Collectors.toList()); + case PLAYER_WORLD: + return require(resource, event, PlayerProvidingEvent.class).getAssociatedPlayers().stream().map(s -> s.getLocation().getWorld()).map(this::getWorldLock).collect(Collectors.toList()); + case EVENT_LOCATION_WORLD: + return require(resource, event, LocationProvidingEvent.class).getAssociatedLocations().stream().map(Location::getWorld).map(this::getWorldLock).collect(Collectors.toList()); + case EVENT_WORLD: + return require(resource, event, WorldProvidingEvent.class).getAssociatedWorlds().stream().map(this::getWorldLock).collect(Collectors.toList()); + default: + log.warn("Unable to find action for " + resource + " resource definition."); + return Collections.emptyList(); + } } }