Remove finalize, use a Cleaner instead (#1943)

* Remove finalize, use a Cleaner instead

* Enable tracing by default

* License fix

* Use the more correct extent
This commit is contained in:
Octavia Togami 2021-12-13 20:08:45 -08:00 committed by GitHub
parent 5ca77b8067
commit 6df194e569
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 17 deletions

View File

@ -322,8 +322,7 @@ private Extent wrapExtent(Extent extent, EventBus eventBus, EditSessionEvent eve
return event.getExtent();
}
// pkg private for TracedEditSession only, may later become public API
boolean commitRequired() {
private boolean commitRequired() {
if (reorderExtent != null && reorderExtent.commitRequired()) {
return true;
}

View File

@ -50,7 +50,7 @@ public abstract class LocalConfiguration {
private static final Logger LOGGER = LogManagerCompat.getLogger();
public boolean profile = false;
public boolean traceUnflushedSessions = false;
public boolean traceUnflushedSessions = true;
public Set<String> disallowedBlocks = new HashSet<>();
public int defaultChangeLimit = -1;
public int maxChangeLimit = -1;

View File

@ -21,9 +21,11 @@
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.internal.util.ErrorReporting;
import com.sk89q.worldedit.util.eventbus.EventBus;
import com.sk89q.worldedit.world.World;
import java.lang.ref.Cleaner;
import javax.annotation.Nullable;
/**
@ -31,22 +33,47 @@
*/
class TracedEditSession extends EditSession {
private static final Cleaner cleaner = Cleaner.create();
private static final class TraceRecord implements Runnable {
private final Throwable stacktrace = new Throwable("An EditSession was not closed.");
private final Actor actor;
private volatile boolean committed = false;
private TraceRecord(Actor actor) {
this.actor = actor;
}
@Override
public void run() {
if (!committed) {
WorldEdit.logger.warn("####### EDIT SESSION NOT CLOSED #######");
WorldEdit.logger.warn("This means that some code did not close their EditSession.");
WorldEdit.logger.warn("Here is a stacktrace from the creation of this EditSession:", stacktrace);
ErrorReporting.trigger(actor, stacktrace);
}
}
}
private final TraceRecord record;
private final Cleaner.Cleanable cleanable;
TracedEditSession(EventBus eventBus, @Nullable World world, int maxBlocks, @Nullable BlockBag blockBag,
@Nullable Actor actor,
boolean tracing) {
super(eventBus, world, maxBlocks, blockBag, actor, tracing);
this.record = new TraceRecord(actor);
this.cleanable = cleaner.register(this, record);
}
private final Throwable stacktrace = new Throwable("Creation trace.");
@Override
protected void finalize() throws Throwable {
super.finalize();
if (commitRequired()) {
WorldEdit.logger.warn("####### LEFTOVER BUFFER BLOCKS DETECTED #######");
WorldEdit.logger.warn("This means that some code did not flush their EditSession.");
WorldEdit.logger.warn("Here is a stacktrace from the creation of this EditSession:", stacktrace);
public void close() {
try {
super.close();
} finally {
this.record.committed = true;
cleanable.clean();
}
}
}

View File

@ -19,7 +19,6 @@
package com.sk89q.worldedit.command.tool;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.entity.Player;
@ -53,9 +52,8 @@ public boolean canUse(Actor player) {
public boolean actPrimary(Platform server, LocalConfiguration config, Player player, LocalSession session, Location clicked, @Nullable Direction face) {
World world = (World) clicked.getExtent();
EditSession editSession = session.createEditSession(player);
BlockVector3 blockPoint = clicked.toVector().toBlockPoint();
BaseBlock block = editSession.getFullBlock(blockPoint);
BaseBlock block = world.getFullBlock(blockPoint);
TextComponent.Builder builder = TextComponent.builder();
builder.append(TextComponent.of("@" + clicked.toVector().toBlockPoint() + ": ", TextColor.BLUE));

View File

@ -101,6 +101,7 @@
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
import com.sk89q.worldedit.internal.command.exception.ExceptionConverter;
import com.sk89q.worldedit.internal.command.exception.WorldEditExceptionConverter;
import com.sk89q.worldedit.internal.util.ErrorReporting;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.internal.util.Substring;
import com.sk89q.worldedit.regions.Region;
@ -591,9 +592,8 @@ private MemoizingValueAccess initializeInjectedValues(Arguments arguments, Actor
}
private void handleUnknownException(Actor actor, Throwable t) {
actor.printError(TranslatableComponent.of("worldedit.command.error.report"));
actor.print(TextComponent.of(t.getClass().getName() + ": " + t.getMessage()));
LOGGER.error("An unexpected error while handling a WorldEdit command", t);
ErrorReporting.trigger(actor, t);
}
@Subscribe

View File

@ -0,0 +1,43 @@
/*
* 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.internal.util;
import com.google.common.base.Throwables;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
/**
* Simple class for handling error reporting to users.
*/
public class ErrorReporting {
public static void trigger(Actor actor, Throwable error) {
actor.printError(TranslatableComponent.of("worldedit.command.error.report"));
actor.print(
TextComponent.builder(error.getClass().getName() + ": " + error.getMessage())
.hoverEvent(HoverEvent.showText(TextComponent.of(Throwables.getStackTraceAsString(error))))
.build()
);
}
private ErrorReporting() {
}
}