Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Folia basic support; #2379

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,9 @@ public boolean isActive() {
updateActive();
} else {
// we should update it eventually
Bukkit.getScheduler().callSyncMethod(plugin,
() -> {
updateActive();
return null;
});
plugin.getScheduler().executeAtRegion(
BukkitAdapter.adapt(sender.getBlock().getLocation()),
this::updateActive);
}
return active;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,20 @@ public <T> T getFacet(Class<? extends T> cls) {
return null;
}
}

@Override
public void executeAtEntity(Runnable runnable) {
org.bukkit.entity.Entity entity = entityRef.get();
if (entity != null) {
entity.getScheduler().run(WorldEditPlugin.getInstance(), task -> runnable.run(), null);
}
}

@Override
public void runAtEntityDelayed(Runnable runnable, long delay) {
org.bukkit.entity.Entity entity = entityRef.get();
if (entity != null) {
entity.getScheduler().runDelayed(WorldEditPlugin.getInstance(), task -> runnable.run(), null, delay);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ public void reload() {

@Override
public int schedule(long delay, long period, Runnable task) {
return Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, period);
plugin.getScheduler().runAsyncRate(task, delay, period);
return 0;
// return Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, task, delay, period);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.sk89q.worldedit.bukkit.adapter.AdapterLoadException;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader;
import com.sk89q.worldedit.bukkit.scheduler.BukkitSchedulerAdapters;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
Expand All @@ -40,6 +41,7 @@
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.scheduler.SchedulerAdapter;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.internal.anvil.ChunkDeleter;
import com.sk89q.worldedit.internal.command.CommandUtil;
Expand Down Expand Up @@ -119,6 +121,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {

private final SimpleLifecycled<BukkitImplAdapter> adapter =
SimpleLifecycled.invalid();
private final SchedulerAdapter scheduler = BukkitSchedulerAdapters.create(this);
private BukkitServerInterface platform;
private BukkitConfiguration config;

Expand Down Expand Up @@ -321,7 +324,7 @@ public void onDisable() {
if (config != null) {
config.unload();
}
this.getServer().getScheduler().cancelTasks(this);
scheduler.cancelTasks();
}

/**
Expand Down Expand Up @@ -517,6 +520,10 @@ BukkitImplAdapter getBukkitImplAdapter() {
return adapter.value().orElse(null);
}

SchedulerAdapter getScheduler() {
return scheduler;
}

private class WorldInitListener implements Listener {
private boolean loaded = false;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and 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 <https://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.bukkit.scheduler;

import com.sk89q.worldedit.bukkit.scheduler.adapters.BukkitSchedulerAdapter;
import com.sk89q.worldedit.bukkit.scheduler.adapters.FoliaSchedulerAdapter;
import com.sk89q.worldedit.extension.platform.scheduler.SchedulerAdapter;
import org.bukkit.plugin.Plugin;

public final class BukkitSchedulerAdapters {
private final static boolean FOLIA_SUPPORT = foliaSupport();

private BukkitSchedulerAdapters() {
// Call only through a method
}

public static SchedulerAdapter create(Plugin plugin) {
if (FOLIA_SUPPORT) {
return new FoliaSchedulerAdapter(plugin);
}
return new BukkitSchedulerAdapter(plugin);
}

private static boolean foliaSupport() {
try {
Class.forName("io.papermc.paper.threadedregions.RegionizedServer");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and 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 <https://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.bukkit.scheduler.adapters;

import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.platform.scheduler.SchedulerAdapter;
import com.sk89q.worldedit.util.Location;
import org.bukkit.plugin.Plugin;

public class BukkitSchedulerAdapter implements SchedulerAdapter {

private final Plugin plugin;
@SuppressWarnings("deprecation")
private final org.bukkit.scheduler.BukkitScheduler scheduler;

public BukkitSchedulerAdapter(final Plugin plugin) {
this.plugin = plugin;
this.scheduler = plugin.getServer().getScheduler();
}

@Override
public void runAsyncRate(Runnable runnable, long delay, long period) {
scheduler.runTaskTimerAsynchronously(plugin, runnable, delay, period);
}

@Override
public void executeAtEntity(Entity entity, Runnable runnable) {
scheduler.runTask(plugin, runnable);
}

@Override
public void runAtEntityDelayed(final Entity entity, final Runnable runnable, final long delay) {
scheduler.runTaskLater(plugin, runnable, delay);
}

@Override
public void executeAtRegion(Location location, Runnable runnable) {
scheduler.runTask(plugin, runnable);
}

@Override
public void cancelTasks() {
scheduler.cancelTasks(plugin);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and 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 <https://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.bukkit.scheduler.adapters;

import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.platform.scheduler.SchedulerAdapter;
import com.sk89q.worldedit.util.Location;
import io.papermc.paper.threadedregions.scheduler.AsyncScheduler;
import io.papermc.paper.threadedregions.scheduler.RegionScheduler;
import org.bukkit.plugin.Plugin;

import java.util.concurrent.TimeUnit;

public class FoliaSchedulerAdapter implements SchedulerAdapter {
private final Plugin plugin;
private final AsyncScheduler asyncScheduler;
private final RegionScheduler regionScheduler;

public FoliaSchedulerAdapter(final Plugin plugin) {
this.plugin = plugin;
this.asyncScheduler = plugin.getServer().getAsyncScheduler();
this.regionScheduler = plugin.getServer().getRegionScheduler();
}

@Override
public void runAsyncRate(final Runnable runnable, final long delay, final long period) {
asyncScheduler.runAtFixedRate(plugin, task -> runnable.run(), delay * 50, period * 50, TimeUnit.MILLISECONDS);
}

@Override
public void executeAtRegion(final Location location, final Runnable runnable) {
regionScheduler.execute(plugin, BukkitAdapter.adapt(location), runnable);
}

@Override
public void cancelTasks() {
asyncScheduler.cancelTasks(plugin);
}

}
4 changes: 3 additions & 1 deletion worldedit-bukkit/src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ load: STARTUP
api-version: 1.13
softdepend: [Vault]
author: EngineHub
website: https://enginehub.org/worldedit
website: https://enginehub.org/worldedit

folia-supported: true
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,25 @@ public interface Entity extends Faceted, Locatable {
*/
boolean remove();

/**
* Schedules a task.
*
* @see com.sk89q.worldedit.extension.platform.scheduler.SchedulerAdapter
* @param runnable The task to execute.
*/
default void executeAtEntity(Runnable runnable) {
throw new UnsupportedOperationException("Not implemented in this platform");
}

/**
* Schedules a task with the given delay.
*
* @see com.sk89q.worldedit.extension.platform.scheduler.SchedulerAdapter
* @param runnable The task to execute.
* @param delay The time delay to pass before the task should be executed, in ticks.
*/
default void runAtEntityDelayed(Runnable runnable, long delay) {
throw new UnsupportedOperationException("Not implemented in this platform");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and 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 <https://www.gnu.org/licenses/>.
*/

package com.sk89q.worldedit.extension.platform.scheduler;

import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.util.Location;

public interface SchedulerAdapter {

/**
* Schedules the specified task to be executed asynchronously after the delay has passed,
* and then periodically executed with the specified period.
*
* @param runnable The task to execute.
* @param delay The time delay to pass before the task should be executed.
* @param period The time between task executions after the first execution of the task.
*/
void runAsyncRate(Runnable runnable, long delay, long period);

/**
* Schedules a task. If the task failed to schedule because the scheduler is retired (entity removed),
* then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay,
* or the retired callback will be invoked if the scheduler is retired.
* Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity,
* remove other entities, load chunks, load worlds, modify ticket levels, etc.
*
* <p>
* It is guaranteed that the task and retired callback are invoked on the region which owns the entity.
* </p>
*
* @param entity The entity relative to which the scheduler is obtained.
* @param runnable The task to execute.
*/
default void executeAtEntity(Entity entity, Runnable runnable) {
entity.executeAtEntity(runnable);
}

/**
* Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity removed),
* then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay,
* or the retired callback will be invoked if the scheduler is retired.
* Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity,
* remove other entities, load chunks, load worlds, modify ticket levels, etc.
*
* <p>
* It is guaranteed that the task and retired callback are invoked on the region which owns the entity.
* </p>
*
* @param entity The entity relative to which the scheduler is obtained.
* @param runnable The task to execute.
* @param delay The time delay to pass before the task should be executed, in ticks.
*/
default void runAtEntityDelayed(Entity entity, Runnable runnable, long delay) {
entity.runAtEntityDelayed(runnable, delay);
}

/**
* Schedules a task to be executed on the region which owns the location.
*
* @param location The location at which the region executing should own.
* @param runnable The task to execute.
*/
void executeAtRegion(Location location, Runnable runnable);

/**
* Attempts to cancel all tasks scheduled by the plugin.
*/
void cancelTasks();
}