First Renderer-API implementation

This commit is contained in:
Blue (Lukas Rieger) 2020-04-10 17:16:47 +02:00
parent b7a1150b18
commit bc16ef5d26
8 changed files with 389 additions and 13 deletions

@ -1 +1 @@
Subproject commit 982f01cc47beaf446d4baea47eb167dd642c40fc
Subproject commit 1d7495dffd6d7c72e22a99888a277eb17de55d31

View File

@ -21,7 +21,7 @@
public class RenderManager {
private boolean running;
private volatile boolean running;
private Thread[] renderThreads;
private ArrayDeque<RenderTicket> renderTickets;
@ -38,14 +38,13 @@ public RenderManager(int threadCount) {
public synchronized void start() {
stop(); //ensure everything is stopped first
running = true;
for (int i = 0; i < renderThreads.length; i++) {
renderThreads[i] = new Thread(this::renderThread);
renderThreads[i].setPriority(Thread.MIN_PRIORITY);
renderThreads[i].start();
}
running = true;
}
public synchronized void stop() {
@ -118,7 +117,7 @@ public boolean removeRenderTask(RenderTask renderTask) {
private void renderThread() {
RenderTicket ticket = null;
while (!Thread.interrupted()) {
while (!Thread.interrupted() && running) {
synchronized (renderTickets) {
ticket = renderTickets.poll();
if (ticket != null) renderTicketMap.remove(ticket);
@ -159,6 +158,10 @@ public int getQueueSize() {
return renderTickets.size();
}
public int getRenderThreadCount() {
return renderThreads.length;
}
/**
* Returns a copy of the deque with the render tasks in order as array
*/

View File

@ -11,23 +11,23 @@ public class RenderTicket {
private final Vector2i tile;
private int renderAttempts;
private boolean finished;
private boolean successfullyRendered;
public RenderTicket(MapType map, Vector2i tile) {
this.map = map;
this.tile = tile;
this.renderAttempts = 0;
this.finished = false;
this.successfullyRendered = false;
}
public synchronized void render() throws IOException {
renderAttempts++;
if (!finished) {
if (!successfullyRendered) {
map.renderTile(tile);
finished = true;
successfullyRendered = true;
}
}
@ -43,10 +43,6 @@ public int getRenderAttempts() {
return renderAttempts;
}
public boolean isFinished() {
return finished;
}
@Override
public int hashCode() {
return Objects.hash(map.getId(), tile);

View File

@ -0,0 +1,123 @@
/*
* This file is part of BlueMap, licensed under the MIT License (MIT).
*
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.bluecolored.bluemap.common.api;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import de.bluecolored.bluemap.api.BlueMapAPI;
import de.bluecolored.bluemap.api.renderer.BlueMapMap;
import de.bluecolored.bluemap.api.renderer.BlueMapWorld;
import de.bluecolored.bluemap.api.renderer.Renderer;
import de.bluecolored.bluemap.common.MapType;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.world.World;
public class BlueMapAPIImpl extends BlueMapAPI {
public Plugin blueMap;
public RendererImpl renderer;
public Map<UUID, BlueMapWorldImpl> worlds;
public Map<String, BlueMapMapImpl> maps;
public BlueMapAPIImpl(Plugin blueMap) {
this.blueMap = blueMap;
this.renderer = new RendererImpl(this, blueMap.getRenderManager());
worlds = new HashMap<>();
for (World world : blueMap.getWorlds()) {
BlueMapWorldImpl w = new BlueMapWorldImpl(this, world);
worlds.put(w.getUuid(), w);
}
maps = new HashMap<>();
for (MapType map : blueMap.getMapTypes()) {
BlueMapMapImpl m = new BlueMapMapImpl(this, map);
maps.put(m.getId(), m);
}
}
@Override
public Renderer getRenderer() {
return renderer;
}
@Override
public Collection<BlueMapMap> getMaps() {
return Collections.unmodifiableCollection(maps.values());
}
@Override
public Collection<BlueMapWorld> getWorlds() {
return Collections.unmodifiableCollection(worlds.values());
}
@Override
public String getBlueMapVersion() {
return BlueMap.VERSION;
}
@Override
public Optional<BlueMapWorld> getWorld(UUID uuid) {
return Optional.ofNullable(worlds.get(uuid));
}
@Override
public Optional<BlueMapMap> getMap(String id) {
return Optional.ofNullable(maps.get(id));
}
public BlueMapWorldImpl getWorldForUuid(UUID uuid) {
BlueMapWorldImpl world = worlds.get(uuid);
if (world == null) throw new IllegalArgumentException("There is no world loaded with this UUID: " + uuid.toString());
return world;
}
public BlueMapMapImpl getMapForId(String mapId) {
BlueMapMapImpl map = maps.get(mapId);
if (map == null) throw new IllegalArgumentException("There is no map loaded with this id: " + mapId);
return map;
}
public void register() {
BlueMapAPI.registerInstance(this);
}
public void unregister() {
BlueMapAPI.unregisterInstance(this);
}
}

View File

@ -0,0 +1,71 @@
/*
* This file is part of BlueMap, licensed under the MIT License (MIT).
*
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.bluecolored.bluemap.common.api;
import com.flowpowered.math.vector.Vector2i;
import de.bluecolored.bluemap.api.renderer.BlueMapMap;
import de.bluecolored.bluemap.common.MapType;
public class BlueMapMapImpl implements BlueMapMap {
private BlueMapAPIImpl api;
private MapType delegate;
protected BlueMapMapImpl(BlueMapAPIImpl api, MapType delegate) {
this.api = api;
this.delegate = delegate;
}
@Override
public String getId() {
return delegate.getId();
}
@Override
public String getName() {
return delegate.getName();
}
@Override
public BlueMapWorldImpl getWorld() {
return api.getWorldForUuid(delegate.getWorld().getUUID());
}
@Override
public Vector2i getTileSize() {
return delegate.getTileRenderer().getHiresModelManager().getTileSize();
}
@Override
public Vector2i getTileOffset() {
return delegate.getTileRenderer().getHiresModelManager().getGridOrigin();
}
public MapType getMapType() {
return delegate;
}
}

View File

@ -0,0 +1,75 @@
/*
* This file is part of BlueMap, licensed under the MIT License (MIT).
*
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.bluecolored.bluemap.common.api;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.UUID;
import java.util.stream.Collectors;
import de.bluecolored.bluemap.api.renderer.BlueMapMap;
import de.bluecolored.bluemap.api.renderer.BlueMapWorld;
import de.bluecolored.bluemap.core.world.World;
public class BlueMapWorldImpl implements BlueMapWorld {
private BlueMapAPIImpl api;
private World delegate;
private Collection<BlueMapMap> maps;
protected BlueMapWorldImpl(BlueMapAPIImpl api, World delegate) {
this.api = api;
this.delegate = delegate;
}
@Override
public Path getSaveFolder() {
// TODO Auto-generated method stub
return null;
}
@Override
public UUID getUuid() {
return delegate.getUUID();
}
@Override
public Collection<BlueMapMap> getMaps() {
if (maps == null) {
maps = Collections.unmodifiableCollection(
api.getMaps().stream()
.filter(map -> map.getWorld().equals(this))
.collect(Collectors.toList()));
}
return maps;
}
public World getWorld() {
return delegate;
}
}

View File

@ -0,0 +1,98 @@
/*
* This file is part of BlueMap, licensed under the MIT License (MIT).
*
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package de.bluecolored.bluemap.common.api;
import java.util.UUID;
import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3i;
import de.bluecolored.bluemap.api.renderer.BlueMapMap;
import de.bluecolored.bluemap.api.renderer.Renderer;
import de.bluecolored.bluemap.common.RenderManager;
public class RendererImpl implements Renderer {
private BlueMapAPIImpl api;
private RenderManager renderManager;
protected RendererImpl(BlueMapAPIImpl api, RenderManager renderManager) {
this.api = api;
this.renderManager = renderManager;
}
@Override
public void render(UUID world, Vector3i blockPosition) {
render(api.getWorldForUuid(world), blockPosition);
}
@Override
public void render(String mapId, Vector3i blockPosition) {
render(api.getMapForId(mapId), blockPosition);
}
@Override
public void render(String mapId, Vector2i tile) {
render(api.getMapForId(mapId), tile);
}
@Override
public void render(BlueMapMap map, Vector2i tile) {
BlueMapMapImpl cmap;
if (map instanceof BlueMapMapImpl) {
cmap = (BlueMapMapImpl) map;
} else {
cmap = api.getMapForId(map.getId());
}
renderManager.createTicket(cmap.getMapType(), tile);
}
@Override
public int renderQueueSize() {
return renderManager.getQueueSize();
}
@Override
public int renderThreadCount() {
return renderManager.getRenderThreadCount();
}
@Override
public boolean isRunning() {
return renderManager.isRunning();
}
@Override
public void start() {
if (!isRunning()) renderManager.start();
}
@Override
public void pause() {
renderManager.stop();
}
}

View File

@ -24,6 +24,7 @@
import de.bluecolored.bluemap.common.MapType;
import de.bluecolored.bluemap.common.RenderManager;
import de.bluecolored.bluemap.common.api.BlueMapAPIImpl;
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
import de.bluecolored.bluemap.core.config.ConfigManager;
import de.bluecolored.bluemap.core.config.MainConfig;
@ -50,6 +51,8 @@ public class Plugin {
private static Plugin instance;
private BlueMapAPIImpl api;
private String implementationType;
private ServerInterface serverInterface;
@ -280,10 +283,17 @@ public synchronized void load() throws IOException, ParseResourceException {
metricsThread.start();
loaded = true;
//enable api
this.api = new BlueMapAPIImpl(this);
this.api.register();
}
public synchronized void unload() {
//disable api
if (api != null) api.unregister();
//unregister listeners
serverInterface.unregisterAllListeners();