diff --git a/pom.xml b/pom.xml
index b656796..e63af11 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
justice-core
com.drcorchit
- 1.0-SNAPSHOT
+ 1.0.0
jar
justice-core
@@ -90,7 +90,7 @@
com.github.DrCorchit
justice-utils
- 1.1.3
+ 1.2.1
org.jetbrains.kotlin
diff --git a/src/main/kotlin/com/drcorchit/justice/games/AbstractElement.kt b/src/main/kotlin/com/drcorchit/justice/games/AbstractElement.kt
index 8c14dc2..fef4f53 100644
--- a/src/main/kotlin/com/drcorchit/justice/games/AbstractElement.kt
+++ b/src/main/kotlin/com/drcorchit/justice/games/AbstractElement.kt
@@ -29,7 +29,9 @@ abstract class AbstractElement(private val parent: AbstractMechanic<*>, name: St
}
override fun sync(info: JsonObject) {
- this.info = info.deepCopy()
+ preSync(info)
+ this.info = info
+ postSync(info)
touch()
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/drcorchit/justice/games/AbstractMechanic.kt b/src/main/kotlin/com/drcorchit/justice/games/AbstractMechanic.kt
index 40c0124..fbf67d1 100644
--- a/src/main/kotlin/com/drcorchit/justice/games/AbstractMechanic.kt
+++ b/src/main/kotlin/com/drcorchit/justice/games/AbstractMechanic.kt
@@ -1,7 +1,7 @@
package com.drcorchit.justice.games
import com.drcorchit.utils.Logger
-import com.drcorchit.utils.json.get
+import com.drcorchit.utils.json.getOrDefault
import com.google.gson.JsonObject
private val log = Logger.getLogger(AbstractMechanic::class.java)
@@ -47,6 +47,7 @@ abstract class AbstractMechanic(game: Game, info: JsonObjec
val message = "Mechanic info for $name is missing \"elements\". Found keys: ${info.keySet()}"
throw IllegalArgumentException(message)
}
+ preSync(info)
elementsByName.clear()
@@ -59,7 +60,7 @@ abstract class AbstractMechanic(game: Game, info: JsonObjec
//Use "key" if present, otherwise default to name
val name = eleInfo["name"].asString
- val key = eleInfo["key", { nextId() }, { it.asInt }]
+ val key = eleInfo.getOrDefault("key", { nextId() }, { it.asInt })
var element: T
if (has(key)) {
@@ -85,6 +86,7 @@ abstract class AbstractMechanic(game: Game, info: JsonObjec
//Remove all elements still marked for deletion
deleteThese.forEach { elementsById.remove(it.key) }
+ postSync(info)
val message = String.format("Synced AbstractMechanic $name", name)
log.info("sync", message)
}
diff --git a/src/main/kotlin/com/drcorchit/justice/games/GameElement.kt b/src/main/kotlin/com/drcorchit/justice/games/GameElement.kt
index 01c1cc9..26c2905 100644
--- a/src/main/kotlin/com/drcorchit/justice/games/GameElement.kt
+++ b/src/main/kotlin/com/drcorchit/justice/games/GameElement.kt
@@ -5,7 +5,7 @@ import com.drcorchit.utils.normalize
import com.google.gson.JsonElement
import com.google.gson.JsonObject
-interface GameElement {
+interface GameElement : Syncable {
//The name of the object as seen by the client
//The name is encouraged to be unique. It may also change from time to time.
fun name(): String
@@ -28,8 +28,6 @@ interface GameElement {
parent().touch()
}
- fun sync(info: JsonObject)
-
//Serializes the object so it can be recreated
fun serialize(): JsonElement {
return GSON.toJsonTree(this)
diff --git a/src/main/kotlin/com/drcorchit/justice/games/GameMechanic.kt b/src/main/kotlin/com/drcorchit/justice/games/GameMechanic.kt
index 1c613bf..fa7a986 100644
--- a/src/main/kotlin/com/drcorchit/justice/games/GameMechanic.kt
+++ b/src/main/kotlin/com/drcorchit/justice/games/GameMechanic.kt
@@ -3,7 +3,7 @@ package com.drcorchit.justice.games
import com.drcorchit.utils.json.GSON
import com.google.gson.JsonObject
-interface GameMechanic : Iterable {
+interface GameMechanic : Syncable, Iterable {
val name: String get() = javaClass.simpleName
val parent: Game
@@ -23,8 +23,6 @@ interface GameMechanic : Iterable {
//Call this method whenever the mechanic is modified. This should also update lastModified
fun touch()
- fun sync(info: JsonObject)
-
fun serialize(): JsonObject {
return GSON.toJsonTree(this).asJsonObject
}
diff --git a/src/main/kotlin/com/drcorchit/justice/games/GridElement.kt b/src/main/kotlin/com/drcorchit/justice/games/GridElement.kt
new file mode 100644
index 0000000..5fa1bcc
--- /dev/null
+++ b/src/main/kotlin/com/drcorchit/justice/games/GridElement.kt
@@ -0,0 +1,29 @@
+package com.drcorchit.justice.games
+
+import com.drcorchit.utils.json.getString
+import com.drcorchit.utils.math.Space
+import com.google.gson.JsonObject
+
+abstract class GridElement(val parent: GridMechanic<*>, val coord: Space.Coordinate) : GameElement {
+
+ protected var info = JsonObject()
+
+ override fun name(): String {
+ return coord.toString()
+ }
+
+ override fun description(): String {
+ return info.getString("description", "No description is available.")
+ }
+
+ override fun parent(): GridMechanic<*> {
+ return parent
+ }
+
+ override fun sync(info: JsonObject) {
+ preSync(info)
+ this.info = info
+ postSync(info)
+ touch()
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/drcorchit/justice/games/GridMechanic.kt b/src/main/kotlin/com/drcorchit/justice/games/GridMechanic.kt
new file mode 100644
index 0000000..198ac2e
--- /dev/null
+++ b/src/main/kotlin/com/drcorchit/justice/games/GridMechanic.kt
@@ -0,0 +1,106 @@
+package com.drcorchit.justice.games
+
+import com.drcorchit.utils.Logger
+import com.drcorchit.utils.json.getBool
+import com.drcorchit.utils.json.getOrDefault
+import com.drcorchit.utils.math.Grid
+import com.drcorchit.utils.math.Layout
+import com.drcorchit.utils.math.Space
+import com.google.gson.JsonObject
+
+private val log = Logger.getLogger(GridMechanic::class.java)
+
+abstract class GridMechanic(game: Game, info: JsonObject, date: Long) : GameMechanic {
+
+ init {
+ sync(info)
+ }
+
+ override val parent: Game = game
+
+ override var lastModified: Long = date
+
+ override var defaultElement: T? = null
+
+ override fun size(): Int {
+ return grid.space.size
+ }
+
+ override fun has(key: Any): Boolean {
+ return if (key is Space.Coordinate) {
+ grid.space.within(key.x, key.y)
+ } else throw java.lang.IllegalArgumentException("Supplied key is not a valid coordinate")
+ }
+
+ override fun get(key: Any): T {
+ if (key is Space.Coordinate) {
+ return grid.get(key)
+ } else {
+ throw IllegalArgumentException("Supplied key is not a valid coordinate")
+ }
+ }
+
+ override fun touch() {
+ lastModified = System.currentTimeMillis()
+ }
+
+ final override fun sync(info: JsonObject) {
+ if (!info.has("elements")) {
+ val message = "Mechanic info for $name is missing \"elements\". Found keys: ${info.keySet()}"
+ throw IllegalArgumentException(message)
+ }
+
+ preSync(info)
+
+ val rows = info.getAsJsonArray("elements").asJsonArray
+ if (rows.size() != grid.height) {
+ throw IllegalArgumentException("Incorrect grid size; expected ${grid.height} but got ${rows.size()}")
+ }
+
+ for ((j, row) in rows.withIndex()) {
+ val actualWidth = row.asJsonArray.size()
+ if (actualWidth != grid.width) {
+ throw java.lang.IllegalArgumentException("Incorrect grid size; expected ${grid.width} but got $actualWidth")
+ }
+ for ((i, ele) in row.asJsonArray.withIndex()) {
+ val eleInfo = ele.asJsonObject
+ val element: T = grid[i, j] ?: create(grid.space.coordinate(i, j))
+ element.sync(eleInfo)
+ }
+ }
+
+ defaultElement =
+ if (info.has("default")) {
+ val rawKey = info["default"].asJsonPrimitive
+ if (rawKey.isString) get(rawKey.asString)
+ else if (rawKey.isNumber) get(rawKey.asInt)
+ else throw IllegalArgumentException("That type of JsonPrimitive cannot specify a default element")
+ } else {
+ null
+ }
+
+ postSync(info)
+ val message = String.format("Synced GridMechanic $name", name)
+ log.info("sync", message)
+ }
+
+
+ override fun iterator(): Iterator {
+ return grid.iterator()
+ }
+
+ //New (non-inherited) functionality
+
+ val grid: Grid by lazy {
+ val w = info["width"].asInt
+ val h = info["height"].asInt
+ val wrapH = info.getBool("wrapHoriz", false)
+ val wrapV = info.getBool("wrapVert", false)
+ val layout = info.getOrDefault("layout", { Layout.CARTESIAN }, { Layout.valueOf(it.asString) })
+ val space = Space(w, h, wrapH, wrapV, layout)
+ Grid(space)
+ }
+
+ abstract fun create(coordinate: Space.Coordinate): T
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/drcorchit/justice/games/Syncable.kt b/src/main/kotlin/com/drcorchit/justice/games/Syncable.kt
new file mode 100644
index 0000000..aba4966
--- /dev/null
+++ b/src/main/kotlin/com/drcorchit/justice/games/Syncable.kt
@@ -0,0 +1,13 @@
+package com.drcorchit.justice.games
+
+interface Syncable {
+
+ //This method is not intended to be called except by sync()
+ fun preSync(info: T)
+
+ fun sync(info: T)
+
+ //This method is not intended to be called except by sync()
+ fun postSync(info: T)
+
+}
\ No newline at end of file