[Editor] Enable choosing base map handler class in map creation/import

This commit is contained in:
2022-08-31 14:53:59 +02:00
parent 0c03bc8a12
commit dda58e3086
9 changed files with 102 additions and 15 deletions

View File

@@ -81,7 +81,7 @@ class MainController : Controller() {
columns = vm.columns columns = vm.columns
handler = vm.handler handler = vm.handler
} }
projectContext.importMap(vm.name, map) projectContext.importMap(vm.name, vm.handlerBaseClass?.takeIf { it.isNotEmpty() }, map)
openItems[scope] = GameMapVM(map) openItems[scope] = GameMapVM(map)
} }
@@ -95,20 +95,28 @@ class MainController : Controller() {
setInScope(vm, scope) setInScope(vm, scope)
find<MapImportFragment>(scope).apply { find<MapImportFragment>(scope).apply {
onComplete { onComplete {
val map = projectContext.importMapFromFile(vm.name, vm.handler, File(vm.file), ::askForNewTileSetAsset, ::askForNewAutoTileAsset) val map = projectContext.importMapFromFile(
vm.name,
vm.handler,
vm.handlerBaseClass?.takeIf { it.isNotEmpty() },
File(vm.file),
::askForNewTileSetAsset,
::askForNewAutoTileAsset
)
openItems[scope] = GameMapVM(map) openItems[scope] = GameMapVM(map)
} }
openModal(block = true, resizable = false) openModal(block = true, resizable = false)
} }
} }
private fun askForNewTileSetAsset(name: String, uid: String): String { private fun askForNewTileSetAsset(name: String, uid: String): String {
var newUid = "" var newUid = ""
find<SelectGraphicAssetFragment<TileSetAsset>>( find<SelectGraphicAssetFragment<TileSetAsset>>(
Scope(), Scope(),
SelectGraphicAssetFragment<TileSetAsset>::assets to projectContext.project?.tileSets!!, SelectGraphicAssetFragment<TileSetAsset>::assets to projectContext.project?.tileSets!!,
SelectGraphicAssetFragment<TileSetAsset>::comment to "You are importing a tile layer which originally was defined\nwith an other Tile Set asset data with UID: [$uid].\nPlease select asset you would like to apply for layer $name.\n".toProperty(), SelectGraphicAssetFragment<TileSetAsset>::comment to "You are importing a tile layer which originally was defined\nwith an other Tile Set asset data with UID: [$uid].\nPlease select asset you would like to apply for layer [$name].\n".toProperty(),
SelectGraphicAssetFragment<TileSetAsset>::cancelable to false.toProperty() SelectGraphicAssetFragment<TileSetAsset>::cancelable to false.toProperty()
).apply { ).apply {
title = "Select Tile Set for layer $name" title = "Select Tile Set for layer $name"
@@ -129,7 +137,7 @@ class MainController : Controller() {
find<SelectGraphicAssetFragment<AutoTileAsset>>( find<SelectGraphicAssetFragment<AutoTileAsset>>(
Scope(), Scope(),
SelectGraphicAssetFragment<AutoTileAsset>::assets to projectContext.project?.autoTiles!!, SelectGraphicAssetFragment<AutoTileAsset>::assets to projectContext.project?.autoTiles!!,
SelectGraphicAssetFragment<AutoTileAsset>::comment to "You are importing a tile layer which originally was defined\nwith an other Auto Tile asset data with UID: [$uid].\nPlease select asset you would like to apply for layer $name.\n".toProperty(), SelectGraphicAssetFragment<AutoTileAsset>::comment to "You are importing a tile layer which originally was defined\nwith an other Auto Tile asset data with UID: [$uid].\nPlease select asset you would like to apply for layer [$name].\n".toProperty(),
SelectGraphicAssetFragment<AutoTileAsset>::cancelable to false.toProperty() SelectGraphicAssetFragment<AutoTileAsset>::cancelable to false.toProperty()
).apply { ).apply {
title = "Select Auto Tile for layer $name" title = "Select Auto Tile for layer $name"

View File

@@ -1,13 +1,9 @@
package com.bartlomiejpluta.base.editor.map.model.map package com.bartlomiejpluta.base.editor.map.model.map
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
import javafx.beans.property.SimpleDoubleProperty
import javafx.beans.property.SimpleIntegerProperty import javafx.beans.property.SimpleIntegerProperty
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty import javafx.beans.property.SimpleStringProperty
import tornadofx.getValue import tornadofx.getValue
import tornadofx.setValue import tornadofx.setValue
import java.io.File
class GameMapBuilder { class GameMapBuilder {
val nameProperty = SimpleStringProperty("") val nameProperty = SimpleStringProperty("")
@@ -28,6 +24,9 @@ class GameMapBuilder {
val handlerProperty = SimpleStringProperty() val handlerProperty = SimpleStringProperty()
var handler by handlerProperty var handler by handlerProperty
val handlerBaseClassProperty = SimpleStringProperty()
var handlerBaseClass by handlerBaseClassProperty
val fileProperty = SimpleStringProperty("") val fileProperty = SimpleStringProperty("")
var file by fileProperty var file by fileProperty
} }

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.map.view.wizard package com.bartlomiejpluta.base.editor.map.view.wizard
import com.bartlomiejpluta.base.editor.code.view.select.SelectJavaClassFragment
import com.bartlomiejpluta.base.editor.map.model.map.GameMapBuilder import com.bartlomiejpluta.base.editor.map.model.map.GameMapBuilder
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM
import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil import com.bartlomiejpluta.base.editor.util.fx.TextFieldUtil
@@ -96,6 +97,26 @@ class MapCreationFragment : Fragment("Basic Data") {
trimWhitespace() trimWhitespace()
} }
} }
field("Map Handler base class") {
hbox {
textfield(mapBuilderVM.handlerBaseClassProperty) {
trimWhitespace()
}
button("Select") {
action {
find<SelectJavaClassFragment>(Scope()).apply {
onComplete { className ->
mapBuilderVM.handlerBaseClassProperty.value = className
}
openModal(block = true, resizable = false)
}
}
}
}
}
} }
buttonbar { buttonbar {

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.map.view.wizard package com.bartlomiejpluta.base.editor.map.view.wizard
import com.bartlomiejpluta.base.editor.code.view.select.SelectJavaClassFragment
import com.bartlomiejpluta.base.editor.map.model.map.GameMapBuilder import com.bartlomiejpluta.base.editor.map.model.map.GameMapBuilder
import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapBuilderVM
import javafx.stage.FileChooser import javafx.stage.FileChooser
@@ -51,7 +52,7 @@ class MapImportFragment : Fragment("Basic Data") {
} }
} }
label("Only tile, object and color layers will be imported. Any image layers will be dropped out.") label("Only tile, auto tile, object and color layers will be imported. Any image layers will be dropped out.")
field("Map name") { field("Map name") {
textfield(mapBuilderVM.nameProperty) { textfield(mapBuilderVM.nameProperty) {
@@ -65,6 +66,26 @@ class MapImportFragment : Fragment("Basic Data") {
trimWhitespace() trimWhitespace()
} }
} }
field("Map Handler base class") {
hbox {
textfield(mapBuilderVM.handlerBaseClassProperty) {
trimWhitespace()
}
button("Select") {
action {
find<SelectJavaClassFragment>(Scope()).apply {
onComplete { className ->
mapBuilderVM.handlerBaseClassProperty.value = className
}
openModal(block = true, resizable = false)
}
}
}
}
}
} }
buttonbar { buttonbar {

View File

@@ -24,6 +24,9 @@ class GameMapBuilderVM : ItemViewModel<GameMapBuilder>(GameMapBuilder()) {
val handlerProperty = bind(GameMapBuilder::handlerProperty, autocommit = true) val handlerProperty = bind(GameMapBuilder::handlerProperty, autocommit = true)
var handler by handlerProperty var handler by handlerProperty
val handlerBaseClassProperty = bind(GameMapBuilder::handlerBaseClassProperty, autocommit = true)
var handlerBaseClass by handlerBaseClassProperty
val fileProperty = bind(GameMapBuilder::fileProperty, autocommit = true) val fileProperty = bind(GameMapBuilder::fileProperty, autocommit = true)
var file by fileProperty var file by fileProperty
} }

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.project.context package com.bartlomiejpluta.base.editor.project.context
import com.bartlomiejpluta.base.api.map.handler.MapHandler
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset import com.bartlomiejpluta.base.editor.animation.asset.AnimationAsset
import com.bartlomiejpluta.base.editor.animation.asset.AnimationAssetData import com.bartlomiejpluta.base.editor.animation.asset.AnimationAssetData
import com.bartlomiejpluta.base.editor.asset.model.Asset import com.bartlomiejpluta.base.editor.asset.model.Asset
@@ -101,7 +102,7 @@ class DefaultProjectContext : ProjectContext {
javaClassService.createClassFile(project.runner, project.codeFSNode, "game_runner.ftl") javaClassService.createClassFile(project.runner, project.codeFSNode, "game_runner.ftl")
} }
override fun importMap(name: String, map: GameMap) { override fun importMap(name: String, handlerBaseClass: String?, map: GameMap) {
project?.let { project?.let {
UID.next(it.maps.map(Asset::uid)).let { uid -> UID.next(it.maps.map(Asset::uid)).let { uid ->
val asset = GameMapAsset(it, uid, name) val asset = GameMapAsset(it, uid, name)
@@ -120,6 +121,9 @@ class DefaultProjectContext : ProjectContext {
} }
} }
model["map_code"] = name.split("\\s+".toRegex()).joinToString("_") { part -> part.lowercase() } model["map_code"] = name.split("\\s+".toRegex()).joinToString("_") { part -> part.lowercase() }
model["inheritanceKeyword"] = handlerBaseClass?.let { "extends " } ?: "implements"
model["mapBaseClassName"] = handlerBaseClass?.substringAfterLast(".") ?: MAP_HANDLER_NAME
model["mapBaseImport"] = handlerBaseClass ?: MAP_HANDLER_CANONICAL_NAME
} }
File(it.mapsDirectory, asset.source).outputStream().use { fos -> mapSerializer.serialize(map, fos) } File(it.mapsDirectory, asset.source).outputStream().use { fos -> mapSerializer.serialize(map, fos) }
@@ -130,6 +134,7 @@ class DefaultProjectContext : ProjectContext {
override fun importMapFromFile( override fun importMapFromFile(
name: String, name: String,
handler: String, handler: String,
handlerBaseClass: String?,
file: File, file: File,
replaceTileSet: (String, String) -> String, replaceTileSet: (String, String) -> String,
replaceAutoTile: (String, String) -> String, replaceAutoTile: (String, String) -> String,
@@ -145,6 +150,17 @@ class DefaultProjectContext : ProjectContext {
javaClassService.createClassFile(handler, project.codeFSNode, "map_handler.ftl") { model -> javaClassService.createClassFile(handler, project.codeFSNode, "map_handler.ftl") { model ->
model["mapUid"] = uid model["mapUid"] = uid
model["mapName"] = name
model["mapCode"] = name.split("\\s+".toRegex()).joinToString("") { part ->
part.replaceFirstChar { c ->
if (c.isLowerCase()) c.titlecase(Locale.getDefault())
else c.toString()
}
}
model["map_code"] = name.split("\\s+".toRegex()).joinToString("_") { part -> part.lowercase() }
model["inheritanceKeyword"] = handlerBaseClass?.let { "extends" } ?: "implements"
model["mapBaseClassName"] = handlerBaseClass?.substringAfterLast(".") ?: MAP_HANDLER_NAME
model["mapBaseImport"] = handlerBaseClass ?: MAP_HANDLER_CANONICAL_NAME
} }
File(project.mapsDirectory, asset.source).outputStream().use { fos -> mapSerializer.serialize(map, fos) } File(project.mapsDirectory, asset.source).outputStream().use { fos -> mapSerializer.serialize(map, fos) }
@@ -361,4 +377,9 @@ class DefaultProjectContext : ProjectContext {
override fun saveScript(code: Code) { override fun saveScript(code: Code) {
code.fileNode.writeText(code.code) code.fileNode.writeText(code.code)
} }
companion object {
private val MAP_HANDLER_NAME = MapHandler::class.java.simpleName
private val MAP_HANDLER_CANONICAL_NAME = MapHandler::class.java.canonicalName
}
} }

View File

@@ -32,9 +32,16 @@ interface ProjectContext {
fun open(file: File) fun open(file: File)
fun createNewProject(project: Project) fun createNewProject(project: Project)
fun importMap(name: String, map: GameMap) fun importMap(name: String, handlerBaseClass: String?, map: GameMap)
fun importMapFromFile(name: String, handler: String, file: File, replaceTileSet: (String, String) -> String, replaceAutoTile: (String, String) -> String, fun importMapFromFile(
name: String,
handler: String,
handlerBaseClass: String?,
file: File,
replaceTileSet: (String, String) -> String,
replaceAutoTile: (String, String) -> String,
): GameMap ): GameMap
fun loadMap(uid: String): GameMap fun loadMap(uid: String): GameMap
fun saveMap(map: GameMap) fun saveMap(map: GameMap)

View File

@@ -10,9 +10,12 @@ import com.bartlomiejpluta.base.api.runner.GameRunner;
public class ${className} implements GameRunner { public class ${className} implements GameRunner {
private static final Logger log = LoggerFactory.getLogger(${className}.class); private static final Logger log = LoggerFactory.getLogger(${className}.class);
private static ${className} INSTANCE;
@Override @Override
public void init(Context context) { public void init(Context context) {
${className}.INSTANCE = this;
// Resume engine, because it is initially paused // Resume engine, because it is initially paused
context.resume(); context.resume();
@@ -21,7 +24,7 @@ public class ${className} implements GameRunner {
} }
@Override @Override
public void input(Screen screen) { public void input(Input input) {
} }
@@ -34,4 +37,8 @@ public class ${className} implements GameRunner {
public void dispose() { public void dispose() {
// Do something after game loop is end // Do something after game loop is end
} }
public static ${className} instance() {
return INSTANCE;
}
} }

View File

@@ -1,12 +1,12 @@
package ${package}; package ${package};
import ${mapBaseImport};
import com.bartlomiejpluta.base.api.context.Context; import com.bartlomiejpluta.base.api.context.Context;
import com.bartlomiejpluta.base.api.input.Input; import com.bartlomiejpluta.base.api.input.Input;
import com.bartlomiejpluta.base.api.map.model.GameMap; import com.bartlomiejpluta.base.api.map.model.GameMap;
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
import com.bartlomiejpluta.base.api.screen.Screen; import com.bartlomiejpluta.base.api.screen.Screen;
public class ${className} implements MapHandler { public class ${className} ${inheritanceKeyword} ${mapBaseClassName} {
@Override @Override
public void onCreate(Context context, GameMap map) { public void onCreate(Context context, GameMap map) {