Помогите Насколько опасен шедулер раз в 1 тик

  • Автор темы Автор темы Mihael_i
  • Дата начала Дата начала

Mihael_i

Активный участник
Пользователь
Баллы
66
Имя в Minecraft
Mihael_i
Здравствуйте. У меня задача следующая: есть некая стена состоящая из блоков, после того как один из блоков этой стены был разрушен(игроков, ТНТ(это я уже сам задетекчу)), мне нужно этот самый блок восстановить через 100/150/200/250 миллисекунд. Для реализации этой задумки я собираюсь записывать дату поломки для каждого блока(взорванные блоки, разумеется, лежат в отдельном ArrayList) и каждый тик проверять, сколько прошло с того момента; если прошло нужное кол-во времени- я восстанавливаю этот блок. Оптимален ли такой алгоритм, если таких итераций в шедулере в 1 тик будет около 100?
 
Боже мой, нельзя просто шедулер на х тиков запускать который просто зарегенит блок?
 
Забей, шедулеры - это копейки, если не перебирать оффлайн игроков и т.д.

Но если очень хочется поиграть в оптимизатора, то:
Если используешь миллисекунды, то и от тиков можно избавиться. Хранить взорванные блоки в отдельном листе не обязательно, есть BlockState - снимок состояния блока. Не проверял, вполне может выскочить CME, тогда поменяй мапу на конкурентную.
PHP:
class BlockBreakHandler {
    private static final int TICKER_DELAY_MS = 100;

    private ScheduledExecutorService executor;
    private Map<BlockState, Long> blocks;

    BlockBreakHandler() {
        executor = Executors.newSingleThreadScheduledExecutor((r) -> new Thread("BlockBreakHandlerThread"));
        blocks = new HashMap<>();
    }

    void start() {
        executor.scheduleWithFixedDelay(this::iterate, 0, TICKER_DELAY_MS, TimeUnit.MILLISECONDS);
    }

    void stop(boolean restoreBlocks) {
        stop();
        executor.execute(() -> blocks.forEach((block, time) -> restoreBlock(block)));
    }

    void stop() {
        executor.shutdown();
    }

    void addBlock(BlockState block, long time) {
        executor.execute(() -> blocks.putIfAbsent(block, System.currentTimeMillis() + time));
    }

    private void iterate() {
        long currentTime = System.currentTimeMillis();
        blocks.forEach(((block, time) -> {
            if (time <= System.currentTimeMillis()) {
                restoreBlock(block);
                blocks.remove(block);
            }
        }));
    }

    private void restoreBlock(BlockState block) {
        Bukkit.getScheduler().runTask(pluginInstance, () -> {
            block.update(true);
        });
    }
}
 
Последнее редактирование:
Боже мой, нельзя просто шедулер на х тиков запускать который просто зарегенит блок?
Если ты про DelayedTask, то разве это будет нормально, если в памяти будет храниться delayed таски для КАЖДОГО недавно взорванного блока? Их же будет достаточно много.
 
Если ты про DelayedTask, то разве это будет нормально, если в памяти будет храниться delayed таски для КАЖДОГО недавно взорванного блока? Их же будет достаточно много.
У меня плагин на ломание стекла стрелами, блоков не так много - всё отлично работает. Всё зависит от их количества.
Насчёт оперирования каждый тик - у @alexandrage есть исходники для TickEvent (можешь жмякать, гитхаб), но если ты будешь в нём оперировать через лист с блоками каждый раз - угробишь сервер.
 
Назад
Верх