Fixed double event handling after failed start attempt
Added stopEvents() call I kinda forgot to add
Made full rendering a (default) option
This commit is contained in:
Norbi Peti 2019-04-12 01:25:29 +02:00
parent ff4ab589e6
commit 99e02f8e7b
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
6 changed files with 132 additions and 41 deletions

View file

@ -32,6 +32,58 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<profiles>
<profile>
<id>XPCOM</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.virtualbox:VirtualBox-MSCOM</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>MSCOM</id>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>org.virtualbox:VirtualBox</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories> <repositories>
<repository> <repository>
<id>spigot-repo</id> <id>spigot-repo</id>
@ -74,6 +126,12 @@
<groupId>net.md-5</groupId> <groupId>net.md-5</groupId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency>
<dependency>
<groupId>org.virtualbox</groupId>
<artifactId>VirtualBox-MSCOM</artifactId>
<version>6.0</version>
<scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>

View file

@ -9,7 +9,6 @@ import org.virtualbox_6_0.*;
import sznp.virtualcomputer.events.MachineEventHandler; import sznp.virtualcomputer.events.MachineEventHandler;
import sznp.virtualcomputer.events.VBoxEventHandler; import sznp.virtualcomputer.events.VBoxEventHandler;
import sznp.virtualcomputer.renderer.GPURenderer; import sznp.virtualcomputer.renderer.GPURenderer;
import sznp.virtualcomputer.renderer.GPURendererInternal;
import sznp.virtualcomputer.renderer.MCFrameBuffer; import sznp.virtualcomputer.renderer.MCFrameBuffer;
import sznp.virtualcomputer.util.Scancode; import sznp.virtualcomputer.util.Scancode;
@ -79,6 +78,8 @@ public final class Computer {
public void onLock(CommandSender sender) { public void onLock(CommandSender sender) {
machine = session.getMachine(); // This is the Machine object we can work with machine = session.getMachine(); // This is the Machine object we can work with
final IConsole console = session.getConsole(); final IConsole console = session.getConsole();
if (handler != null)
handler.disable();
handler = new MachineEventHandler(Computer.this, sender); handler = new MachineEventHandler(Computer.this, sender);
listener = handler.registerTo(console.getEventSource()); listener = handler.registerTo(console.getEventSource());
IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2 IProgress progress = console.powerUp(); // https://marc.info/?l=vbox-dev&m=142780789819967&w=2
@ -222,6 +223,7 @@ public final class Computer {
} }
public void pluginDisable(CommandSender ccs) { public void pluginDisable(CommandSender ccs) {
stopEvents();
if (session.getState() == SessionState.Locked) { if (session.getState() == SessionState.Locked) {
if (session.getMachine().getState().equals(MachineState.Running)) { if (session.getMachine().getState().equals(MachineState.Running)) {
ccs.sendMessage("§aSaving machine state..."); ccs.sendMessage("§aSaving machine state...");

View file

@ -40,6 +40,7 @@ public class PluginMain extends JavaPlugin {
*/ */
//public static PXCLib pxc; //public static PXCLib pxc;
public static boolean direct; public static boolean direct;
public static boolean sendAll;
// Fired when plugin is first enabled // Fired when plugin is first enabled
@Override @Override
@ -48,6 +49,7 @@ public class PluginMain extends JavaPlugin {
try { try {
ConsoleCommandSender ccs = getServer().getConsoleSender(); ConsoleCommandSender ccs = getServer().getConsoleSender();
this.getCommand("computer").setExecutor(new Commands()); this.getCommand("computer").setExecutor(new Commands());
sendAll = getConfig().getBoolean("sendAll", true);
ccs.sendMessage("§bInitializing VirtualBox..."); ccs.sendMessage("§bInitializing VirtualBox...");
String vbpath = System.getProperty("os.name").toLowerCase().contains("mac") String vbpath = System.getProperty("os.name").toLowerCase().contains("mac")
? "/Applications/VirtualBox.app/Contents/MacOS" ? "/Applications/VirtualBox.app/Contents/MacOS"
@ -109,12 +111,14 @@ public class PluginMain extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
ConsoleCommandSender ccs = getServer().getConsoleSender(); ConsoleCommandSender ccs = getServer().getConsoleSender();
if (mousetask != null)
mousetask.cancel(); mousetask.cancel();
/*try { /*try {
source.unregisterListener(listener); source.unregisterListener(listener);
} catch (VBoxException e) { //"Listener was never registered" } catch (VBoxException e) { //"Listener was never registered"
e.printStackTrace(); - VBox claims the listener was never registered (can double register as well) e.printStackTrace(); - VBox claims the listener was never registered (can double register as well)
}*/ }*/
if (listener != null)
((VBoxEventHandler) listener.getTypedWrapped()).disable(); //The save progress wait locks with the event ((VBoxEventHandler) listener.getTypedWrapped()).disable(); //The save progress wait locks with the event
if (Computer.getInstance() != null) if (Computer.getInstance() != null)
Computer.getInstance().pluginDisable(ccs); Computer.getInstance().pluginDisable(ccs);

View file

@ -37,7 +37,7 @@ public class MachineEventHandler extends EventHandlerBase {
case PoweredOff: case PoweredOff:
case Saved: case Saved:
if (starting) { if (starting) {
sender.sendMessage("§cFailed to start computer! See the VM's log for more details."); sender.sendMessage("§cFailed to start computer! See the console for more details.");
sender.sendMessage("§cMake sure that 2D and 3D acceleration is disabled."); sender.sendMessage("§cMake sure that 2D and 3D acceleration is disabled.");
starting = false; starting = false;
Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> { Bukkit.getScheduler().runTaskAsynchronously(PluginMain.Instance, () -> {

View file

@ -7,23 +7,29 @@ import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapPalette; import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer; import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView; import org.bukkit.map.MapView;
import sznp.virtualcomputer.PluginMain;
import sznp.virtualcomputer.util.Timing; import sznp.virtualcomputer.util.Timing;
import java.awt.*; import java.awt.*;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
public class GPURenderer extends MapRenderer implements IRenderer { public class GPURenderer extends MapRenderer implements IRenderer {
private byte[] buffer; private byte[] buffer;
private GPURendererInternal kernel; private final GPURendererInternal kernel;
private WorldMap wmap; private WorldMap wmap;
private int mapx, mapy; private int mapx, mapy;
//Store at central location after conversion //Store at central location after conversion
private static int[] colors_; private static int[] colors_;
private static int changedX, changedY, changedWidth, changedHeight; private int changedX = 0, changedY = 0, changedWidth = 640, changedHeight = 480;
private static ArrayList<GPURenderer> renderers = new ArrayList<>();
public GPURenderer(short id, World world, int mapx, int mapy) throws Exception { public GPURenderer(short id, World world, int mapx, int mapy) throws Exception {
MapView map = IRenderer.prepare(id, world); MapView map = IRenderer.prepare(id, world);
if (map == null) return; //Testing if (map == null) {
kernel = null;
return; //Testing
}
if (colors_ == null) { if (colors_ == null) {
Field field = MapPalette.class.getDeclaredField("colors"); Field field = MapPalette.class.getDeclaredField("colors");
@ -40,8 +46,7 @@ public class GPURenderer extends MapRenderer implements IRenderer {
field.setAccessible(true); field.setAccessible(true);
wmap = (WorldMap) field.get(map); wmap = (WorldMap) field.get(map);
kernel = new GPURendererInternal(mapx, mapy, colors_); kernel = new GPURendererInternal(mapx, mapy, colors_);
renderers.add(this);
//System.setProperty("com.codegen.config.enable.NEW", "true");
map.addRenderer(this); map.addRenderer(this);
} }
@ -56,16 +61,35 @@ public class GPURenderer extends MapRenderer implements IRenderer {
field.setAccessible(true); field.setAccessible(true);
buffer = (byte[]) field.get(canvas); buffer = (byte[]) field.get(canvas);
} }
if (!PluginMain.sendAll) {
synchronized (kernel) {
if (changedX >= (mapx + 1) * 128 || changedY >= (mapy + 1) * 128 if (changedX >= (mapx + 1) * 128 || changedY >= (mapy + 1) * 128
|| changedX + changedWidth < mapx * 128 || changedY + changedHeight < mapy * 128) || changedX + changedWidth < mapx * 128 || changedY + changedHeight < mapy * 128) {
return; //No change for this map - TODO: Test kernel.ignoreChange();
int x = changedX % 128; return; //No change for this map
int y = changedY % 128; }
int w = x + changedWidth >= 128 ? 128 - x - 1 : changedWidth; }
int h = y + changedHeight >= 128 ? 128 - y - 1 : changedHeight; //System.out.println("changed: (" + changedX + ", " + changedY + ") " + changedWidth + "x" + changedHeight);
//System.out.println("map: (" + mapx + ", " + mapy + ")");
int x = changedX - mapx * 128;
int y = changedY - mapy * 128;
if (x < 0) x = 0;
if (y < 0) y = 0;
int xx = x + changedWidth >= 128 ? 127 : x + changedWidth;
int yy = y + changedHeight >= 128 ? 127 : y + changedHeight;
//System.out.println("local: ("+x+", "+y+") "+w+"x"+h);
kernel.render(buffer); kernel.render(buffer);
wmap.flagDirty(x, y); wmap.flagDirty(x, y);
wmap.flagDirty(x + w, y + h); // Send the changes only wmap.flagDirty(xx, yy); // Send the changes only
changedX = Integer.MAX_VALUE; //Finished rendering
changedY = Integer.MAX_VALUE; //TODO: Render as soon as we receive new image
changedWidth = -1; //Finished rendering
changedHeight = -1;
} else {
kernel.render(buffer);
wmap.flagDirty(0, 0);
wmap.flagDirty(127, 127); // Send everything
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -74,10 +98,20 @@ public class GPURenderer extends MapRenderer implements IRenderer {
} }
public static void update(byte[] pixels, int width, int height, int changedX, int changedY, int changedWidth, int changedHeight) { public static void update(byte[] pixels, int width, int height, int changedX, int changedY, int changedWidth, int changedHeight) {
GPURenderer.changedX = changedX; for (GPURenderer r : renderers) {
GPURenderer.changedY = changedY; synchronized (r.kernel) {
GPURenderer.changedWidth = changedWidth; if (!PluginMain.sendAll) {
GPURenderer.changedHeight = changedHeight; if (changedX < r.changedX)
GPURendererInternal.setPixels(pixels, width, height); r.changedX = changedX;
if (changedY < r.changedY)
r.changedY = changedY;
if (changedWidth > r.changedWidth)
r.changedWidth = changedWidth;
if (changedHeight > r.changedHeight)
r.changedHeight = changedHeight;
}
r.kernel.setPixels(pixels, width, height);
}
}
} }
} }

View file

@ -4,9 +4,6 @@ import com.aparapi.Kernel;
import com.aparapi.Range; import com.aparapi.Range;
import lombok.Getter; import lombok.Getter;
import java.util.ArrayList;
import java.util.function.Consumer;
//Accessing the GPURenderer results in ArrayIndexOutOfBoundsExceptions - IT'S THE LAMBDAS //Accessing the GPURenderer results in ArrayIndexOutOfBoundsExceptions - IT'S THE LAMBDAS
public class GPURendererInternal extends Kernel { public class GPURendererInternal extends Kernel {
private int mapx; private int mapx;
@ -21,7 +18,6 @@ public class GPURendererInternal extends Kernel {
private Range range; private Range range;
@Getter @Getter
private boolean rendered; private boolean rendered;
private static ArrayList<GPURendererInternal> renderers = new ArrayList<>();
//public static byte[] test=new byte[1]; - LAMBDAS //public static byte[] test=new byte[1]; - LAMBDAS
public GPURendererInternal(int mapx, int mapy, int[] colors) { public GPURendererInternal(int mapx, int mapy, int[] colors) {
@ -34,8 +30,6 @@ public class GPURendererInternal extends Kernel {
pixels = new byte[1]; pixels = new byte[1];
width = height = 0; width = height = 0;
rendered = false; rendered = false;
renderers.add(this);
} }
@Override @Override
@ -94,17 +88,12 @@ public class GPURendererInternal extends Kernel {
private static final int GREEN = 1; private static final int GREEN = 1;
private static final int BLUE = 0; private static final int BLUE = 0;
@SuppressWarnings("Convert2Lambda") //Aparapi fails with lambdas //Aparapi fails with lambdas
static void setPixels(byte[] pixels, int width, int height) { void setPixels(byte[] pixels, int width, int height) {
renderers.forEach(new Consumer<GPURendererInternal>() { this.pixels = pixels;
@Override //IT'S THE LAMBDAS (exception) this.width = width;
public void accept(GPURendererInternal r) { this.height = height;
r.pixels = pixels; rendered = false;
r.width = width;
r.height = height;
r.rendered = false;
}
});
} }
void render(byte[] buffer) { void render(byte[] buffer) {
@ -113,4 +102,8 @@ public class GPURendererInternal extends Kernel {
put(buffer).put(pixels).execute(range).get(buffer); put(buffer).put(pixels).execute(range).get(buffer);
rendered = true; rendered = true;
} }
void ignoreChange() {
rendered = true;
}
} }