[Editor] Convert binary protobuf project files to JSON format

This commit is contained in:
2023-11-04 14:45:26 +01:00
parent 6e04904151
commit a3b89de71a
28 changed files with 263 additions and 60 deletions

View File

@@ -37,6 +37,9 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib" implementation "org.jetbrains.kotlin:kotlin-stdlib"
// JSON Proto
implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}"
// GUI // GUI
implementation "no.tornado:tornadofx:${tornadoFxVersion}" implementation "no.tornado:tornadofx:${tornadoFxVersion}"
implementation platform("org.kordamp.ikonli:ikonli-bom:${ikonliVersion}") implementation platform("org.kordamp.ikonli:ikonli-bom:${ikonliVersion}")

View File

@@ -1,18 +1,23 @@
package com.bartlomiejpluta.base.editor.asset.model package com.bartlomiejpluta.base.editor.asset.model
import javafx.beans.binding.Bindings.createObjectBinding import javafx.beans.binding.Bindings.createObjectBinding
import javafx.beans.property.ObjectProperty
import javafx.beans.property.SimpleStringProperty import javafx.beans.property.SimpleStringProperty
import javafx.beans.value.ObservableValue
import tornadofx.getValue import tornadofx.getValue
import tornadofx.setValue import tornadofx.setValue
import java.io.File import java.io.File
abstract class Asset(directory: ObjectProperty<File>, val uid: String, val source: String, name: String) { abstract class Asset(sourceDirectory: ObservableValue<File>, compiledDirectory: ObservableValue<File>, val uid: String, val source: String, val binarySource: String, name: String) {
constructor(directory: ObservableValue<File>, uid: String, source: String, name: String) : this(directory, directory, uid, source, source, name)
val nameProperty = SimpleStringProperty(name) val nameProperty = SimpleStringProperty(name)
var name by nameProperty var name by nameProperty
val fileProperty = createObjectBinding({ File(directory.value, source) }, directory) val fileProperty = createObjectBinding({ File(sourceDirectory.value, source) }, sourceDirectory)
val file by fileProperty val file by fileProperty
val binaryFileProperty = createObjectBinding({ File(compiledDirectory.value, binarySource) })
val binaryFile by binaryFileProperty
override fun toString() = "${this.javaClass.simpleName}[name=$name, uid=$uid]" override fun toString() = "${this.javaClass.simpleName}[name=$name, uid=$uid]"
} }

View File

@@ -0,0 +1,7 @@
package com.bartlomiejpluta.base.editor.code.build.asset
import com.bartlomiejpluta.base.editor.project.model.Project
interface AssetSerializer {
fun serializeAssets(project: Project)
}

View File

@@ -0,0 +1,47 @@
package com.bartlomiejpluta.base.editor.code.build.asset
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
import com.bartlomiejpluta.base.editor.map.serial.BinaryMapSerializer
import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.project.model.Project
import com.bartlomiejpluta.base.editor.project.serial.BinaryProjectSerializer
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
@Component
class DefaultAssetSerializer : AssetSerializer {
@Autowired
private lateinit var projectContext: ProjectContext
@Autowired
private lateinit var projectSerializer: BinaryProjectSerializer
@Autowired
private lateinit var mapSerializer: BinaryMapSerializer
override fun serializeAssets(project: Project) {
project.buildAssetsDir.mkdirs()
serializeProject(project)
project.buildAssetsMapsDir.mkdirs()
serializeMaps(project)
}
private fun serializeProject(project: Project) {
project.binaryProjectFile.outputStream().use {
projectSerializer.serialize(project, it)
}
}
private fun serializeMaps(project: Project) = project.maps.forEach {
serializeMap(it)
}
private fun serializeMap(asset: GameMapAsset) {
val map = projectContext.loadMap(asset.uid)
asset.binaryFile.outputStream().use {
mapSerializer.serialize(map, it)
}
}
}

View File

@@ -3,7 +3,7 @@ package com.bartlomiejpluta.base.editor.code.build.generator
import com.bartlomiejpluta.base.editor.asset.model.Asset import com.bartlomiejpluta.base.editor.asset.model.Asset
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
import com.bartlomiejpluta.base.editor.map.model.layer.ObjectLayer import com.bartlomiejpluta.base.editor.map.model.layer.ObjectLayer
import com.bartlomiejpluta.base.editor.map.serial.MapDeserializer import com.bartlomiejpluta.base.editor.map.serial.TextMapDeserializer
import com.bartlomiejpluta.base.editor.project.context.ProjectContext import com.bartlomiejpluta.base.editor.project.context.ProjectContext
import com.bartlomiejpluta.base.editor.project.model.Project import com.bartlomiejpluta.base.editor.project.model.Project
import com.squareup.javapoet.* import com.squareup.javapoet.*
@@ -22,7 +22,7 @@ class AssetMapCodeGenerator : CodeGenerator {
private lateinit var projectContext: ProjectContext private lateinit var projectContext: ProjectContext
@Autowired @Autowired
private lateinit var mapDeserializer: MapDeserializer private lateinit var mapDeserializer: TextMapDeserializer
override fun generate() { override fun generate() {
projectContext.project?.let(::generateAssetClasses) projectContext.project?.let(::generateAssetClasses)

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.editor.code.build.pipeline package com.bartlomiejpluta.base.editor.code.build.pipeline
import com.bartlomiejpluta.base.editor.code.build.asset.AssetSerializer
import com.bartlomiejpluta.base.editor.code.build.compiler.Compiler import com.bartlomiejpluta.base.editor.code.build.compiler.Compiler
import com.bartlomiejpluta.base.editor.code.build.database.DatabaseAssembler import com.bartlomiejpluta.base.editor.code.build.database.DatabaseAssembler
import com.bartlomiejpluta.base.editor.code.build.exception.BuildException import com.bartlomiejpluta.base.editor.code.build.exception.BuildException
@@ -38,6 +39,9 @@ class DefaultBuildPipelineService : BuildPipelineService {
@Autowired @Autowired
private lateinit var engineProvider: GameEngineProvider private lateinit var engineProvider: GameEngineProvider
@Autowired
private lateinit var assetSerializer: AssetSerializer
@Autowired @Autowired
private lateinit var projectAssembler: ProjectAssembler private lateinit var projectAssembler: ProjectAssembler
@@ -126,6 +130,9 @@ class DefaultBuildPipelineService : BuildPipelineService {
out.println("Linking compilation units...") out.println("Linking compilation units...")
packager.pack(project.buildClassesDirectory, outputFile, "BOOT-INF/classes") packager.pack(project.buildClassesDirectory, outputFile, "BOOT-INF/classes")
out.println("Serializing project assets...")
assetSerializer.serializeAssets(project)
out.println("Assembling project assets...") out.println("Assembling project assets...")
projectAssembler.assembly(project, outputFile, out, err) projectAssembler.assembly(project, outputFile, out, err)

View File

@@ -24,7 +24,9 @@ class DefaultProjectAssembler : ProjectAssembler {
} }
private fun tryToAssembly(project: Project, targetJar: File) { private fun tryToAssembly(project: Project, targetJar: File) {
packager.pack(project.mapsDirectory, targetJar, "BOOT-INF/classes/project/maps") packager.copy(project.binaryProjectFile, targetJar, "BOOT-INF/classes/project")
packager.pack(project.buildAssetsMapsDir, targetJar, "BOOT-INF/classes/project/maps")
packager.pack(project.tileSetsDirectory, targetJar, "BOOT-INF/classes/project/tilesets") packager.pack(project.tileSetsDirectory, targetJar, "BOOT-INF/classes/project/tilesets")
packager.pack(project.autoTilesDirectory, targetJar, "BOOT-INF/classes/project/autotiles") packager.pack(project.autoTilesDirectory, targetJar, "BOOT-INF/classes/project/autotiles")
packager.pack(project.imagesDirectory, targetJar, "BOOT-INF/classes/project/images") packager.pack(project.imagesDirectory, targetJar, "BOOT-INF/classes/project/images")
@@ -34,7 +36,6 @@ class DefaultProjectAssembler : ProjectAssembler {
packager.pack(project.fontsDirectory, targetJar, "BOOT-INF/classes/project/fonts") packager.pack(project.fontsDirectory, targetJar, "BOOT-INF/classes/project/fonts")
packager.pack(project.widgetsDirectory, targetJar, "BOOT-INF/classes/project/widgets") packager.pack(project.widgetsDirectory, targetJar, "BOOT-INF/classes/project/widgets")
packager.pack(project.audioDirectory, targetJar, "BOOT-INF/classes/project/audio") packager.pack(project.audioDirectory, targetJar, "BOOT-INF/classes/project/audio")
packager.copy(project.projectFile, targetJar, "BOOT-INF/classes/project")
} }
companion object { companion object {

View File

@@ -155,7 +155,7 @@ class MainController : Controller() {
fun openProject() { fun openProject() {
chooseFile( chooseFile(
title = "Load Project", title = "Load Project",
filters = arrayOf(FileChooser.ExtensionFilter("BASE Editor Project (*.bep)", "*.bep")), filters = arrayOf(FileChooser.ExtensionFilter("BASE Editor Project (*.json)", "*.json")),
).getOrNull(0)?.let { ).getOrNull(0)?.let {
clearResources() clearResources()
projectContext.open(it) projectContext.open(it)

View File

@@ -4,4 +4,4 @@ import com.bartlomiejpluta.base.editor.asset.model.Asset
import com.bartlomiejpluta.base.editor.project.model.Project import com.bartlomiejpluta.base.editor.project.model.Project
class GameMapAsset(project: Project, uid: String, name: String) : class GameMapAsset(project: Project, uid: String, name: String) :
Asset(project.mapsDirectoryProperty, uid, "$uid.dat", name) Asset(project.mapsDirectoryProperty, project.buildAssetsMapsDirProperty, uid, "$uid.json", "$uid.dat", name)

View File

@@ -2,10 +2,8 @@ package com.bartlomiejpluta.base.editor.map.serial
import com.bartlomiejpluta.base.editor.common.serial.Deserializer import com.bartlomiejpluta.base.editor.common.serial.Deserializer
import com.bartlomiejpluta.base.editor.map.model.map.GameMap import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
import com.bartlomiejpluta.base.editor.tileset.model.TileSet
import java.io.InputStream import java.io.InputStream
interface MapDeserializer : Deserializer<GameMap> { interface BinaryMapDeserializer : Deserializer<GameMap> {
fun deserialize(input: InputStream, replaceTileSet: (String, String) -> String, replaceAutoTile: (String, String) -> String): GameMap fun deserialize(input: InputStream, replaceTileSet: (String, String) -> String, replaceAutoTile: (String, String) -> String): GameMap
} }

View File

@@ -0,0 +1,6 @@
package com.bartlomiejpluta.base.editor.map.serial
import com.bartlomiejpluta.base.editor.common.serial.Serializer
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
interface BinaryMapSerializer : Serializer<GameMap>

View File

@@ -0,0 +1,24 @@
package com.bartlomiejpluta.base.editor.map.serial
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.bartlomiejpluta.base.proto.GameMapProto
import com.google.protobuf.util.JsonFormat
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.io.InputStream
@Component
class JsonProtobufMapDeserializer : TextMapDeserializer {
@Autowired
private lateinit var deserializer: ProtobufMapDeserializer
override fun deserialize(input: InputStream) = deserialize(input, { _, uid -> uid }, { _, uid -> uid })
override fun deserialize(input: InputStream, replaceTileSet: (String, String) -> String, replaceAutoTile: (String, String) -> String): GameMap =
input.bufferedReader().use { reader ->
val builder = GameMapProto.GameMap.newBuilder()
JsonFormat.parser().merge(reader, builder)
deserializer.buildObject(builder.build(), replaceTileSet, replaceAutoTile)
}
}

View File

@@ -0,0 +1,22 @@
package com.bartlomiejpluta.base.editor.map.serial
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.google.protobuf.util.JsonFormat
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.io.OutputStream
import java.io.PrintWriter
@Component
class JsonProtobufMapSerializer : TextMapSerializer {
@Autowired
private lateinit var serializer: ProtobufMapSerializer
override fun serialize(item: GameMap, output: OutputStream) {
output.bufferedWriter().let(::PrintWriter).use { out ->
JsonFormat.printer().print(serializer.buildProto(item)).lines().forEach { line ->
out.println(line)
}
}
}
}

View File

@@ -15,7 +15,7 @@ import org.springframework.stereotype.Component
import java.io.InputStream import java.io.InputStream
@Component @Component
class ProtobufMapDeserializer : MapDeserializer { open class ProtobufMapDeserializer : BinaryMapDeserializer {
@Autowired @Autowired
private lateinit var appContext: ApplicationContext private lateinit var appContext: ApplicationContext
@@ -30,8 +30,13 @@ class ProtobufMapDeserializer : MapDeserializer {
input: InputStream, input: InputStream,
replaceTileSet: (String, String) -> String, replaceTileSet: (String, String) -> String,
replaceAutoTile: (String, String) -> String replaceAutoTile: (String, String) -> String
): GameMap = buildObject(GameMapProto.GameMap.parseFrom(input), replaceTileSet, replaceAutoTile)
fun buildObject(
proto: GameMapProto.GameMap,
replaceTileSet: (String, String) -> String,
replaceAutoTile: (String, String) -> String
): GameMap { ): GameMap {
val proto = GameMapProto.GameMap.parseFrom(input)
val map = GameMap(proto.tileWidth.toDouble(), proto.tileHeight.toDouble()) val map = GameMap(proto.tileWidth.toDouble(), proto.tileHeight.toDouble())
map.uid = proto.uid map.uid = proto.uid
map.rows = proto.rows map.rows = proto.rows

View File

@@ -9,9 +9,11 @@ import org.springframework.stereotype.Component
import java.io.OutputStream import java.io.OutputStream
@Component @Component
class ProtobufMapSerializer : MapSerializer { open class ProtobufMapSerializer : BinaryMapSerializer {
override fun serialize(item: GameMap, output: OutputStream) { override fun serialize(item: GameMap, output: OutputStream) = buildProto(item).writeTo(output)
fun buildProto(item: GameMap): GameMapProto.GameMap {
val protoMap = GameMapProto.GameMap.newBuilder() val protoMap = GameMapProto.GameMap.newBuilder()
protoMap.uid = item.uid protoMap.uid = item.uid
protoMap.rows = item.rows protoMap.rows = item.rows
@@ -23,7 +25,7 @@ class ProtobufMapSerializer : MapSerializer {
item.layers.forEach { layer -> protoMap.addLayers(serializeLayer(layer)) } item.layers.forEach { layer -> protoMap.addLayers(serializeLayer(layer)) }
protoMap.build().writeTo(output) return protoMap.build()
} }
private fun serializeLayer(layer: Layer): GameMapProto.Layer { private fun serializeLayer(layer: Layer): GameMapProto.Layer {

View File

@@ -0,0 +1,9 @@
package com.bartlomiejpluta.base.editor.map.serial
import com.bartlomiejpluta.base.editor.common.serial.Deserializer
import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import java.io.InputStream
interface TextMapDeserializer : Deserializer<GameMap> {
fun deserialize(input: InputStream, replaceTileSet: (String, String) -> String, replaceAutoTile: (String, String) -> String): GameMap
}

View File

@@ -3,4 +3,4 @@ package com.bartlomiejpluta.base.editor.map.serial
import com.bartlomiejpluta.base.editor.common.serial.Serializer import com.bartlomiejpluta.base.editor.common.serial.Serializer
import com.bartlomiejpluta.base.editor.map.model.map.GameMap import com.bartlomiejpluta.base.editor.map.model.map.GameMap
interface MapSerializer : Serializer<GameMap> interface TextMapSerializer : Serializer<GameMap>

View File

@@ -45,7 +45,7 @@ class MapImportFragment : Fragment("Basic Data") {
action { action {
mapBuilderVM.fileProperty.value = chooseFile( mapBuilderVM.fileProperty.value = chooseFile(
title = "Map file location", title = "Map file location",
filters = arrayOf(FileChooser.ExtensionFilter("Map files (*.dat)", "*.dat")) filters = arrayOf(FileChooser.ExtensionFilter("Map files (*.json)", "*.json"))
).getOrNull(0)?.absolutePath ).getOrNull(0)?.absolutePath
} }
} }

View File

@@ -25,11 +25,11 @@ import com.bartlomiejpluta.base.editor.image.asset.ImageAsset
import com.bartlomiejpluta.base.editor.image.asset.ImageAssetData import com.bartlomiejpluta.base.editor.image.asset.ImageAssetData
import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset import com.bartlomiejpluta.base.editor.map.asset.GameMapAsset
import com.bartlomiejpluta.base.editor.map.model.map.GameMap import com.bartlomiejpluta.base.editor.map.model.map.GameMap
import com.bartlomiejpluta.base.editor.map.serial.MapDeserializer import com.bartlomiejpluta.base.editor.map.serial.TextMapDeserializer
import com.bartlomiejpluta.base.editor.map.serial.MapSerializer import com.bartlomiejpluta.base.editor.map.serial.TextMapSerializer
import com.bartlomiejpluta.base.editor.project.model.Project import com.bartlomiejpluta.base.editor.project.model.Project
import com.bartlomiejpluta.base.editor.project.serial.ProjectDeserializer import com.bartlomiejpluta.base.editor.project.serial.TextProjectDeserializer
import com.bartlomiejpluta.base.editor.project.serial.ProjectSerializer import com.bartlomiejpluta.base.editor.project.serial.TextProjectSerializer
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAsset
import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetData import com.bartlomiejpluta.base.editor.tileset.asset.TileSetAssetData
import com.bartlomiejpluta.base.editor.tileset.model.TileSet import com.bartlomiejpluta.base.editor.tileset.model.TileSet
@@ -53,16 +53,16 @@ class DefaultProjectContext : ProjectContext {
private val autoTileCache = mutableMapOf<String, AutoTile>() private val autoTileCache = mutableMapOf<String, AutoTile>()
@Autowired @Autowired
private lateinit var projectSerializer: ProjectSerializer private lateinit var projectSerializer: TextProjectSerializer
@Autowired @Autowired
private lateinit var projectDeserializer: ProjectDeserializer private lateinit var projectDeserializer: TextProjectDeserializer
@Autowired @Autowired
private lateinit var mapSerializer: MapSerializer private lateinit var mapSerializer: TextMapSerializer
@Autowired @Autowired
private lateinit var mapDeserializer: MapDeserializer private lateinit var mapDeserializer: TextMapDeserializer
@Autowired @Autowired
private lateinit var javaClassService: JavaClassService private lateinit var javaClassService: JavaClassService

View File

@@ -128,6 +128,16 @@ class Project {
createObjectBinding({ File(buildOutDirectory, PROJECT_OUTPUT_JAR_FILE) }, buildOutDirectoryProperty) createObjectBinding({ File(buildOutDirectory, PROJECT_OUTPUT_JAR_FILE) }, buildOutDirectoryProperty)
val buildOutputJarFile by buildOutputJarFileProperty val buildOutputJarFile by buildOutputJarFileProperty
val buildAssetsDirProperty = SimpleObjectProperty<File>()
var buildAssetsDir by buildAssetsDirProperty
private set
val binaryProjectFileProperty = createObjectBinding({ File(buildAssetsDir, BINARY_PROJECT_FILE) }, buildAssetsDirProperty)
val binaryProjectFile by binaryProjectFileProperty
val buildAssetsMapsDirProperty = createObjectBinding({ File(buildAssetsDir, MAPS_DIR) }, buildAssetsDirProperty)
val buildAssetsMapsDir by buildAssetsMapsDirProperty
lateinit var database: H2DBDataSource lateinit var database: H2DBDataSource
init { init {
@@ -148,6 +158,7 @@ class Project {
buildClassesDirectory = File(it, BUILD_CLASSES_DIR) buildClassesDirectory = File(it, BUILD_CLASSES_DIR)
buildDependenciesDirectory = File(it, BUILD_DEPENDENCIES_DIR) buildDependenciesDirectory = File(it, BUILD_DEPENDENCIES_DIR)
buildGeneratedCodeDirectory = File(it, BUILD_GENERATED_DIR) buildGeneratedCodeDirectory = File(it, BUILD_GENERATED_DIR)
buildAssetsDir = File(it, BUILD_ASSETS_DIR)
buildDatabaseDumpDirectory = File(it, BUILD_DATABASE_DUMP_DIR) buildDatabaseDumpDirectory = File(it, BUILD_DATABASE_DUMP_DIR)
buildOutDirectory = File(it, BUILD_OUT_DIR) buildOutDirectory = File(it, BUILD_OUT_DIR)
} }
@@ -179,7 +190,8 @@ class Project {
} }
companion object { companion object {
const val PROJECT_FILE = "project.bep" const val PROJECT_FILE = "project.json"
const val BINARY_PROJECT_FILE = "project.bep"
const val DATABASE_FILE = "data.sql" const val DATABASE_FILE = "data.sql"
const val DATABASE_DUMP_FILE = "data.sql" const val DATABASE_DUMP_FILE = "data.sql"
const val PROJECT_OUTPUT_JAR_FILE = "game.jar" const val PROJECT_OUTPUT_JAR_FILE = "game.jar"
@@ -200,6 +212,7 @@ class Project {
const val BUILD_OUT_DIR = "$BUILD_DIR/out" const val BUILD_OUT_DIR = "$BUILD_DIR/out"
const val BUILD_DEPENDENCIES_DIR = "$BUILD_DIR/dependencies" const val BUILD_DEPENDENCIES_DIR = "$BUILD_DIR/dependencies"
const val BUILD_GENERATED_DIR = "$BUILD_DIR/generated" const val BUILD_GENERATED_DIR = "$BUILD_DIR/generated"
const val BUILD_ASSETS_DIR = "$BUILD_DIR/assets"
const val BUILD_DATABASE_DUMP_DIR = "$BUILD_DIR/db" const val BUILD_DATABASE_DUMP_DIR = "$BUILD_DIR/db"
} }
} }

View File

@@ -0,0 +1,6 @@
package com.bartlomiejpluta.base.editor.project.serial
import com.bartlomiejpluta.base.editor.common.serial.Deserializer
import com.bartlomiejpluta.base.editor.project.model.Project
interface BinaryProjectDeserializer : Deserializer<Project>

View File

@@ -0,0 +1,6 @@
package com.bartlomiejpluta.base.editor.project.serial
import com.bartlomiejpluta.base.editor.common.serial.Serializer
import com.bartlomiejpluta.base.editor.project.model.Project
interface BinaryProjectSerializer : Serializer<Project>

View File

@@ -0,0 +1,20 @@
package com.bartlomiejpluta.base.editor.project.serial
import com.bartlomiejpluta.base.editor.project.model.Project
import com.bartlomiejpluta.base.proto.ProjectProto
import com.google.protobuf.util.JsonFormat
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.io.InputStream
@Component
class JsonProtobufProjectDeserializer : TextProjectDeserializer {
@Autowired
private lateinit var deserializer: ProtobufProjectDeserializer
override fun deserialize(input: InputStream): Project = input.bufferedReader().use { reader ->
val builder = ProjectProto.Project.newBuilder()
JsonFormat.parser().merge(reader, builder)
deserializer.buildObject(builder.build())
}
}

View File

@@ -0,0 +1,22 @@
package com.bartlomiejpluta.base.editor.project.serial
import com.bartlomiejpluta.base.editor.project.model.Project
import com.google.protobuf.util.JsonFormat
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.io.OutputStream
import java.io.PrintWriter
@Component
class JsonProtobufProjectSerializer : TextProjectSerializer {
@Autowired
private lateinit var serializer: ProtobufProjectSerializer
override fun serialize(item: Project, output: OutputStream) {
output.bufferedWriter().let(::PrintWriter).use { out ->
JsonFormat.printer().print(serializer.buildProto(item)).lines().forEach { line ->
out.println(line)
}
}
}
}

View File

@@ -17,25 +17,23 @@ import org.springframework.stereotype.Component
import java.io.InputStream import java.io.InputStream
@Component @Component
class ProtobufProjectDeserializer : ProjectDeserializer { open class ProtobufProjectDeserializer : BinaryProjectDeserializer {
override fun deserialize(input: InputStream): Project { override fun deserialize(input: InputStream): Project = buildObject(ProjectProto.Project.parseFrom(input))
val proto = ProjectProto.Project.parseFrom(input)
return Project().apply { fun buildObject(proto: ProjectProto.Project): Project = Project().apply {
name = proto.name name = proto.name
runner = proto.runner runner = proto.runner
maps.addAll(proto.mapsList.map { deserializeMap(this, it) }) maps.addAll(proto.mapsList.map { deserializeMap(this, it) })
tileSets.addAll(proto.tileSetsList.map { deserializeTileSet(this, it) }) tileSets.addAll(proto.tileSetsList.map { deserializeTileSet(this, it) })
autoTiles.addAll(proto.autoTilesList.map { deserializeAutoTile(this, it) }) autoTiles.addAll(proto.autoTilesList.map { deserializeAutoTile(this, it) })
images.addAll(proto.imagesList.map { deserializeImage(this, it) }) images.addAll(proto.imagesList.map { deserializeImage(this, it) })
characterSets.addAll(proto.characterSetsList.map { deserializeCharacterSet(this, it) }) characterSets.addAll(proto.characterSetsList.map { deserializeCharacterSet(this, it) })
animations.addAll(proto.animationsList.map { deserializeAnimation(this, it) }) animations.addAll(proto.animationsList.map { deserializeAnimation(this, it) })
iconSets.addAll(proto.iconSetsList.map { deserializeIconSet(this, it) }) iconSets.addAll(proto.iconSetsList.map { deserializeIconSet(this, it) })
fonts.addAll(proto.fontsList.map { deserializeFont(this, it) }) fonts.addAll(proto.fontsList.map { deserializeFont(this, it) })
widgets.addAll(proto.widgetsList.map { deserializeWidget(this, it) }) widgets.addAll(proto.widgetsList.map { deserializeWidget(this, it) })
sounds.addAll(proto.soundsList.map { deserializeSound(this, it) }) sounds.addAll(proto.soundsList.map { deserializeSound(this, it) })
}
} }
private fun deserializeMap(project: Project, map: ProjectProto.GameMapAsset) = GameMapAsset( private fun deserializeMap(project: Project, map: ProjectProto.GameMapAsset) = GameMapAsset(

View File

@@ -16,9 +16,11 @@ import org.springframework.stereotype.Component
import java.io.OutputStream import java.io.OutputStream
@Component @Component
class ProtobufProjectSerializer : ProjectSerializer { class ProtobufProjectSerializer : BinaryProjectSerializer {
override fun serialize(item: Project, output: OutputStream) { override fun serialize(item: Project, output: OutputStream) = buildProto(item).writeTo(output)
fun buildProto(item: Project): ProjectProto.Project {
val proto = ProjectProto.Project.newBuilder() val proto = ProjectProto.Project.newBuilder()
proto.name = item.name proto.name = item.name
proto.runner = item.runner proto.runner = item.runner
@@ -32,18 +34,18 @@ class ProtobufProjectSerializer : ProjectSerializer {
proto.addAllFonts(item.fonts.map(this::serializeFont)) proto.addAllFonts(item.fonts.map(this::serializeFont))
proto.addAllWidgets(item.widgets.map(this::serializeWidget)) proto.addAllWidgets(item.widgets.map(this::serializeWidget))
proto.addAllSounds(item.sounds.map(this::serializeSound)) proto.addAllSounds(item.sounds.map(this::serializeSound))
proto.build().writeTo(output) return proto.build()
} }
private fun serializeMap(map: GameMapAsset) = ProjectProto.GameMapAsset.newBuilder() private fun serializeMap(map: GameMapAsset) = ProjectProto.GameMapAsset.newBuilder()
.setUid(map.uid) .setUid(map.uid)
.setSource(map.source) .setSource(map.binarySource)
.setName(map.name) .setName(map.name)
.build() .build()
private fun serializeTileSet(tileSet: TileSetAsset) = ProjectProto.TileSetAsset.newBuilder() private fun serializeTileSet(tileSet: TileSetAsset) = ProjectProto.TileSetAsset.newBuilder()
.setUid(tileSet.uid) .setUid(tileSet.uid)
.setSource(tileSet.source) .setSource(tileSet.binarySource)
.setName(tileSet.name) .setName(tileSet.name)
.setRows(tileSet.rows) .setRows(tileSet.rows)
.setColumns(tileSet.columns) .setColumns(tileSet.columns)
@@ -51,7 +53,7 @@ class ProtobufProjectSerializer : ProjectSerializer {
private fun serializeAutoTile(autoTile: AutoTileAsset) = ProjectProto.AutoTileSetAsset.newBuilder() private fun serializeAutoTile(autoTile: AutoTileAsset) = ProjectProto.AutoTileSetAsset.newBuilder()
.setUid(autoTile.uid) .setUid(autoTile.uid)
.setSource(autoTile.source) .setSource(autoTile.binarySource)
.setName(autoTile.name) .setName(autoTile.name)
.setRows(autoTile.rows) .setRows(autoTile.rows)
.setColumns(autoTile.columns) .setColumns(autoTile.columns)
@@ -60,13 +62,13 @@ class ProtobufProjectSerializer : ProjectSerializer {
private fun serializeImage(image: ImageAsset) = ProjectProto.ImageAsset.newBuilder() private fun serializeImage(image: ImageAsset) = ProjectProto.ImageAsset.newBuilder()
.setUid(image.uid) .setUid(image.uid)
.setSource(image.source) .setSource(image.binarySource)
.setName(image.name) .setName(image.name)
.build() .build()
private fun serializeCharacterSet(characterSet: CharacterSetAsset) = ProjectProto.CharacterSetAsset.newBuilder() private fun serializeCharacterSet(characterSet: CharacterSetAsset) = ProjectProto.CharacterSetAsset.newBuilder()
.setUid(characterSet.uid) .setUid(characterSet.uid)
.setSource(characterSet.source) .setSource(characterSet.binarySource)
.setName(characterSet.name) .setName(characterSet.name)
.setRows(characterSet.rows) .setRows(characterSet.rows)
.setColumns(characterSet.columns) .setColumns(characterSet.columns)
@@ -74,7 +76,7 @@ class ProtobufProjectSerializer : ProjectSerializer {
private fun serializeAnimation(animation: AnimationAsset) = ProjectProto.AnimationAsset.newBuilder() private fun serializeAnimation(animation: AnimationAsset) = ProjectProto.AnimationAsset.newBuilder()
.setUid(animation.uid) .setUid(animation.uid)
.setSource(animation.source) .setSource(animation.binarySource)
.setName(animation.name) .setName(animation.name)
.setRows(animation.rows) .setRows(animation.rows)
.setColumns(animation.columns) .setColumns(animation.columns)
@@ -82,7 +84,7 @@ class ProtobufProjectSerializer : ProjectSerializer {
private fun serializeIconSet(iconSet: IconSetAsset) = ProjectProto.IconSetAsset.newBuilder() private fun serializeIconSet(iconSet: IconSetAsset) = ProjectProto.IconSetAsset.newBuilder()
.setUid(iconSet.uid) .setUid(iconSet.uid)
.setSource(iconSet.source) .setSource(iconSet.binarySource)
.setName(iconSet.name) .setName(iconSet.name)
.setRows(iconSet.rows) .setRows(iconSet.rows)
.setColumns(iconSet.columns) .setColumns(iconSet.columns)
@@ -90,19 +92,19 @@ class ProtobufProjectSerializer : ProjectSerializer {
private fun serializeFont(font: FontAsset) = ProjectProto.FontAsset.newBuilder() private fun serializeFont(font: FontAsset) = ProjectProto.FontAsset.newBuilder()
.setUid(font.uid) .setUid(font.uid)
.setSource(font.source) .setSource(font.binarySource)
.setName(font.name) .setName(font.name)
.build() .build()
private fun serializeWidget(widget: WidgetAsset) = ProjectProto.WidgetAsset.newBuilder() private fun serializeWidget(widget: WidgetAsset) = ProjectProto.WidgetAsset.newBuilder()
.setUid(widget.uid) .setUid(widget.uid)
.setSource(widget.source) .setSource(widget.binarySource)
.setName(widget.name) .setName(widget.name)
.build() .build()
private fun serializeSound(sound: SoundAsset) = ProjectProto.SoundAsset.newBuilder() private fun serializeSound(sound: SoundAsset) = ProjectProto.SoundAsset.newBuilder()
.setUid(sound.uid) .setUid(sound.uid)
.setSource(sound.source) .setSource(sound.binarySource)
.setName(sound.name) .setName(sound.name)
.build() .build()
} }

View File

@@ -3,4 +3,4 @@ package com.bartlomiejpluta.base.editor.project.serial
import com.bartlomiejpluta.base.editor.common.serial.Deserializer import com.bartlomiejpluta.base.editor.common.serial.Deserializer
import com.bartlomiejpluta.base.editor.project.model.Project import com.bartlomiejpluta.base.editor.project.model.Project
interface ProjectDeserializer : Deserializer<Project> interface TextProjectDeserializer : Deserializer<Project>

View File

@@ -3,4 +3,4 @@ package com.bartlomiejpluta.base.editor.project.serial
import com.bartlomiejpluta.base.editor.common.serial.Serializer import com.bartlomiejpluta.base.editor.common.serial.Serializer
import com.bartlomiejpluta.base.editor.project.model.Project import com.bartlomiejpluta.base.editor.project.model.Project
interface ProjectSerializer : Serializer<Project> interface TextProjectSerializer : Serializer<Project>