diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java index c6979c3d..ad0e9406 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java @@ -1,5 +1,6 @@ package com.bartlomiejpluta.base.api.game.entity; +import com.bartlomiejpluta.base.api.game.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.api.internal.logic.Updatable; import com.bartlomiejpluta.base.api.internal.object.Placeable; import com.bartlomiejpluta.base.api.internal.render.Renderable; @@ -31,4 +32,8 @@ public interface Entity extends Placeable, Renderable, Updatable { int manhattanDistance(Entity other); Direction getDirectionTowards(Entity target); + + void onAdd(ObjectLayer layer); + + void onRemove(ObjectLayer layer); } diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java index 55320cd6..454fbf9c 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java @@ -1,6 +1,7 @@ package com.bartlomiejpluta.base.api.game.entity; import com.bartlomiejpluta.base.api.game.camera.Camera; +import com.bartlomiejpluta.base.api.game.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.api.game.window.Window; import com.bartlomiejpluta.base.api.internal.object.Placeable; import com.bartlomiejpluta.base.api.internal.render.ShaderManager; @@ -9,7 +10,7 @@ import org.joml.Vector2f; import org.joml.Vector2i; public abstract class EntityDelegate implements Entity { - private final Entity entity; + protected final Entity entity; protected EntityDelegate(Entity entity) { this.entity = entity; @@ -160,6 +161,16 @@ public abstract class EntityDelegate implements Entity { return entity.getModelMatrix(); } + @Override + public void onAdd(ObjectLayer layer) { + entity.onAdd(layer); + } + + @Override + public void onRemove(ObjectLayer layer) { + entity.onRemove(layer); + } + @Override public void update(float dt) { entity.update(dt); diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/map/handler/MapHandler.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/map/handler/MapHandler.java index dface72f..69b62bb8 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/map/handler/MapHandler.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/map/handler/MapHandler.java @@ -5,7 +5,9 @@ import com.bartlomiejpluta.base.api.game.map.model.GameMap; import com.bartlomiejpluta.base.api.game.window.Window; public interface MapHandler { - void init(Context context, GameMap map); + void onCreate(Context context, GameMap map); + + void onOpen(Context context, GameMap map); void input(Window window); diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/map/layer/object/ObjectLayer.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/map/layer/object/ObjectLayer.java index 9b6dc424..59ab78c3 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/map/layer/object/ObjectLayer.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/map/layer/object/ObjectLayer.java @@ -12,6 +12,8 @@ public interface ObjectLayer extends Layer { void removeEntity(Entity entity); + void clearEntities(); + List getEntities(); void registerRule(Rule rule); diff --git a/editor/src/main/resources/java_templates/map_handler.ftl b/editor/src/main/resources/java_templates/map_handler.ftl index b47d083d..051748da 100644 --- a/editor/src/main/resources/java_templates/map_handler.ftl +++ b/editor/src/main/resources/java_templates/map_handler.ftl @@ -8,12 +8,12 @@ import com.bartlomiejpluta.base.api.game.window.Window; public class ${className} implements MapHandler { @Override - public void init(Context context, GameMap map) { + public void onCreate(Context context, GameMap map) { } @Override - public void input(Window window) { + public void onOpen(Context context, GameMap map) { } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/project/loader/DefaultClassLoader.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/project/loader/DefaultClassLoader.java index 27f2aaaf..a4af92c8 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/project/loader/DefaultClassLoader.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/project/loader/DefaultClassLoader.java @@ -1,18 +1,18 @@ package com.bartlomiejpluta.base.engine.project.loader; -import com.bartlomiejpluta.base.engine.error.AppException; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; +@Slf4j @Component public class DefaultClassLoader implements ClassLoader { + @SneakyThrows @Override @SuppressWarnings("unchecked") public Class loadClass(String className) { - try { - return (Class) getClass().getClassLoader().loadClass(className); - } catch (ClassNotFoundException e) { - throw new AppException(e); - } + log.info("Loading [{}] class", className); + return (Class) getClass().getClassLoader().loadClass(className); } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/project/model/RenderableContext.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/project/model/RenderableContext.java index 0b740334..d8c88146 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/project/model/RenderableContext.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/project/model/RenderableContext.java @@ -45,11 +45,9 @@ public class RenderableContext implements Context, Updatable, Renderable { @Override public void openMap(String mapUid) { map = mapManager.loadObject(mapUid); + mapHandler = mapManager.loadHandler(this, mapUid); - var handlerClass = classLoader.loadClass(map.getHandler()); - mapHandler = handlerClass.getConstructor().newInstance(); - - mapHandler.init(this, map); + mapHandler.onOpen(this, map); } @Override diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java index 59a8289f..33c69293 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java @@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.engine.world.entity.model; import com.bartlomiejpluta.base.api.game.entity.Direction; import com.bartlomiejpluta.base.api.game.entity.Entity; +import com.bartlomiejpluta.base.api.game.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh; import com.bartlomiejpluta.base.engine.util.math.MathUtil; @@ -93,6 +94,16 @@ public class DefaultEntity extends MovableSprite implements Entity { return Direction.ofVector(new Vector2i(target.getCoordinates()).sub(getCoordinates())); } + @Override + public void onAdd(ObjectLayer layer) { + // Do nothing + } + + @Override + public void onRemove(ObjectLayer layer) { + // Do nothing + } + public DefaultEntity(Mesh mesh, Material material, EntitySpriteConfiguration configuration) { super(mesh, material); this.defaultSpriteColumn = configuration.getDefaultSpriteColumn(); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java index e08ca52d..9682e764 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java @@ -55,15 +55,22 @@ public class DefaultObjectLayer implements ObjectLayer { @Override public void addEntity(Entity entity) { + entity.onAdd(this); entity.setStepSize(stepSize.x, stepSize.y); entities.add(entity); } @Override public void removeEntity(Entity entity) { + entity.onRemove(this); entities.remove(entity); } + @Override + public void clearEntities() { + entities.clear(); + } + @Override public void setPassageAbility(int row, int column, PassageAbility passageAbility) { passageMap[row][column] = passageAbility; diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/DefaultMapManager.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/DefaultMapManager.java index 41833eeb..42d4bf5b 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/DefaultMapManager.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/DefaultMapManager.java @@ -1,11 +1,15 @@ package com.bartlomiejpluta.base.engine.world.map.manager; +import com.bartlomiejpluta.base.api.game.context.Context; +import com.bartlomiejpluta.base.api.game.map.handler.MapHandler; import com.bartlomiejpluta.base.engine.error.AppException; import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration; +import com.bartlomiejpluta.base.engine.project.loader.ClassLoader; import com.bartlomiejpluta.base.engine.world.map.asset.GameMapAsset; import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap; import com.bartlomiejpluta.base.engine.world.map.serial.MapDeserializer; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -19,8 +23,10 @@ import java.util.Map; public class DefaultMapManager implements MapManager { private final Map maps = new HashMap<>(); private final Map assets = new HashMap<>(); + private final Map handlers = new HashMap<>(); private final MapDeserializer mapDeserializer; private final ProjectConfiguration configuration; + private final ClassLoader classLoader; @Override public void registerAsset(GameMapAsset asset) { @@ -52,4 +58,34 @@ public class DefaultMapManager implements MapManager { public void cleanUp() { log.info("There is nothing to clean up here"); } + + @SneakyThrows + @Override + public MapHandler loadHandler(Context context, String uid) { + var handler = handlers.get(uid); + + if (handler == null) { + var asset = assets.get(uid); + + if (asset == null) { + throw new AppException("The map asset with UID: [%s] does not exist", uid); + } + + var map = maps.get(uid); + + if (map == null) { + throw new AppException("The map asset with UID: [%s] has not been loaded yet", uid); + } + + var handlerClassName = map.getHandler(); + log.info("Creating new handler: [{}] for the map with ID: [{}]", handlerClassName, uid); + var handlerClass = classLoader.loadClass(handlerClassName); + handler = handlerClass.getConstructor().newInstance(); + handlers.put(uid, handler); + + handler.onCreate(context, map); + } + + return handler; + } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/MapManager.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/MapManager.java index 634ae638..b1af5cae 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/MapManager.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/manager/MapManager.java @@ -1,9 +1,12 @@ package com.bartlomiejpluta.base.engine.world.map.manager; +import com.bartlomiejpluta.base.api.game.context.Context; +import com.bartlomiejpluta.base.api.game.map.handler.MapHandler; import com.bartlomiejpluta.base.api.internal.gc.Cleanable; import com.bartlomiejpluta.base.engine.common.manager.AssetManager; import com.bartlomiejpluta.base.engine.world.map.asset.GameMapAsset; import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap; public interface MapManager extends AssetManager, Cleanable { + MapHandler loadHandler(Context context, String mapUid); }