Archived
0

Implemented simple resource lock fetchers

This commit is contained in:
Daniil
2018-08-05 22:56:16 +07:00
parent 3b24c2fed4
commit e6dfc1861b

View File

@@ -1,24 +1,64 @@
package mc.core.events; package mc.core.events;
import lombok.extern.slf4j.Slf4j;
import mc.core.Location;
import mc.core.events.api.LockableResource; import mc.core.events.api.LockableResource;
import mc.core.events.api.Plugin; 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.events.lock.PoorMansLock;
import mc.core.player.Player;
import mc.core.world.World;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@Slf4j
public class SharedResourceManager { public class SharedResourceManager {
private Map<Plugin, PoorMansLock> pluginLocks = new ConcurrentHashMap<>(); private Map<Plugin, PoorMansLock> pluginLocks = new ConcurrentHashMap<>();
// TODO: Memory leak HERE. Fix with introducing field to Player class
private Map<Player, PoorMansLock> playerLocks = new ConcurrentHashMap<>();
// TODO: Memory leak HERE. Fix with introducing field to World class
private Map<World, PoorMansLock> worldLocks = new ConcurrentHashMap<>();
public PoorMansLock getPluginLock(Plugin plugin) { public PoorMansLock getPluginLock(Plugin plugin) {
return pluginLocks.computeIfAbsent(plugin, s -> new PoorMansLock()); 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> T require(LockableResource resource, Event event, Class<T> 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<PoorMansLock> getAnnotationLocks(LockableResource resource, Event event) { public Collection<PoorMansLock> getAnnotationLocks(LockableResource resource, Event event) {
// TODO: Implement switch (resource) {
return Collections.emptyList(); 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();
}
} }
} }