/* * CraftBook Copyright (C) 2010-2017 sk89q <http://www.sk89q.com> * CraftBook Copyright (C) 2011-2017 me4502 <http://www.me4502.com> * CraftBook Copyright (C) Contributors * * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program. If not, * see <http://www.gnu.org/licenses/>. */ package com.sk89q.craftbook.sponge.st; import com.google.common.collect.ImmutableMap; import com.me4502.modularframework.exception.ModuleNotInstantiatedException; import com.me4502.modularframework.module.ModuleWrapper; import com.sk89q.craftbook.core.st.SelfTriggerClock; import com.sk89q.craftbook.core.st.SelfTriggerManager; import com.sk89q.craftbook.sponge.CraftBookPlugin; import com.sk89q.craftbook.sponge.mechanics.types.SpongeBlockMechanic; import com.sk89q.craftbook.sponge.mechanics.types.SpongeMechanic; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.tileentity.TileEntity; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.world.LoadWorldEvent; import org.spongepowered.api.event.world.UnloadWorldEvent; import org.spongepowered.api.event.world.chunk.LoadChunkEvent; import org.spongepowered.api.event.world.chunk.UnloadChunkEvent; import org.spongepowered.api.world.Chunk; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; import org.spongepowered.api.world.extent.Extent; import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; public class SpongeSelfTriggerManager implements SelfTriggerManager { private Map<Location<World>, SelfTriggeringMechanic> selfTriggeringMechanics = new ConcurrentHashMap<>(); @Override public void initialize() { Sponge.getGame().getScheduler().createTaskBuilder().intervalTicks(2L).execute(new SelfTriggerClock()).submit(CraftBookPlugin.inst()); Sponge.getGame().getEventManager().registerListeners(CraftBookPlugin.inst(), this); for(World world : Sponge.getGame().getServer().getWorlds()) { for(Chunk chunk : world.getLoadedChunks()) { registerAll(chunk); } } } @Override public void unload() { selfTriggeringMechanics.clear(); } public Map<Location<World>,SelfTriggeringMechanic> getSelfTriggeringMechanics() { return ImmutableMap.copyOf(selfTriggeringMechanics); } public void register(SelfTriggeringMechanic mechanic, Location<World> location) { selfTriggeringMechanics.put(location, mechanic); } public void unregister(SelfTriggeringMechanic mechanic, Location<World> location) { selfTriggeringMechanics.remove(location, mechanic); } private void registerAll(World world) { for (Chunk chunk : world.getLoadedChunks()) { registerAll(chunk); } } private void registerAll(Chunk chunk) { for(TileEntity tileEntity : chunk.getTileEntities()) { for (ModuleWrapper module : CraftBookPlugin.spongeInst().moduleController.getModules()) { if(!module.isEnabled()) continue; try { SpongeMechanic mechanic = (SpongeMechanic) module.getModuleUnchecked(); if (mechanic instanceof SpongeBlockMechanic && mechanic instanceof SelfTriggeringMechanic) { if (((SpongeBlockMechanic) mechanic).isValid(tileEntity.getLocation())) { register((SelfTriggeringMechanic) mechanic, tileEntity.getLocation()); } } } catch (ModuleNotInstantiatedException e) { CraftBookPlugin.spongeInst().getLogger().error("Failed to register self-triggering mechanic for module: " + module.getName(), e); } } } } private void unregisterAll(Extent extent) { new HashSet<>(selfTriggeringMechanics.keySet()).stream().filter(loc -> loc.inExtent(extent)).forEach(selfTriggeringMechanics::remove); } @Override public void think() { for (Entry<Location<World>, SelfTriggeringMechanic> entry : selfTriggeringMechanics.entrySet()) { entry.getValue().onThink(entry.getKey()); } } @Listener public void onChunkLoad(LoadChunkEvent event) { registerAll(event.getTargetChunk()); } @Listener public void onChunkUnload(UnloadChunkEvent event) { unregisterAll(event.getTargetChunk()); } @Listener public void onWorldLoad(LoadWorldEvent event) { registerAll(event.getTargetWorld()); } @Listener public void onWorldUnload(UnloadWorldEvent event) { unregisterAll(event.getTargetWorld()); } }