Cells/cells/server/src/net/okennedy/cells/state/Table.scala

118 lines
3.0 KiB
Scala

package net.okennedy.cells.state
import scala.collection.mutable
import net.okennedy.cells.Identifier
import net.okennedy.cells.serialized
import net.okennedy.cells.TableRequest
import net.okennedy.cells.RequestSetTablePosition
import net.okennedy.cells.RequestUpdateColumns
import net.okennedy.cells.RequestUpdateRows
import net.okennedy.cells.SetTablePosition
import net.okennedy.cells.WebsocketConnection
import net.okennedy.cells.serialized.ColSpec
import net.okennedy.cells.serialized.RowSpec
import net.okennedy.cells.UpdateTableColumns
import net.okennedy.cells.UpdateTableRows
import net.okennedy.cells.{ SeqOp, SeqInsert, SeqDelete }
import net.okennedy.cells.SeqReplace
class Table(val id: Identifier)
{
var x = 20
var y = 20
val columns = mutable.ArrayBuffer[ColSpec]()
val rows = mutable.ArrayBuffer[RowSpec]()
def serialize =
serialized.Table(
id = id,
x = x,
y = y,
rows = rows.toSeq,
columns = columns.toSeq,
)
def genSafeColId(depth: Int = 0): Identifier =
{
val id = java.util.UUID.randomUUID()
if(columns exists { _.id == id }){
if(depth > 100) { throw new Exception("Too Many Columns!!!") }
return genSafeColId(depth + 1)
}
return id
}
def genSafeRowId(depth: Int = 0): Identifier =
{
val id = java.util.UUID.randomUUID()
if(rows exists { _.id == id }){
if(depth > 100) { throw new Exception("Too Many Rows!!!") }
return genSafeColId(depth + 1)
}
return id
}
def updateColumns(op: SeqOp[ColSpec]): Unit =
{
val opWithValidId =
op match {
case SeqInsert(_, _) => op.map { _.copy(id = genSafeColId()) }
case SeqReplace(pos, _) => op.map { _.copy(id = columns(pos).id) }
case SeqDelete(_) => op
}
// println(s"Update: $op")
opWithValidId.bufferApply(columns)
WebsocketConnection.broadcast(
UpdateTableColumns(id, opWithValidId)
)
}
def addColumn(width: Int = 100): Unit =
{
updateColumns(SeqInsert(columns.length,
ColSpec(id = null, width = width)
))
}
def updateRows(op: SeqOp[RowSpec]): Unit =
{
val opWithValidId =
op match {
case SeqInsert(_, _) => op.map { _.copy(id = genSafeRowId()) }
case SeqReplace(pos, _) => op.map { _.copy(id = rows(pos).id) }
case SeqDelete(_) => op
}
opWithValidId.bufferApply(rows)
WebsocketConnection.broadcast(
UpdateTableRows(id, opWithValidId)
)
}
def addRow(height: Int = 30): Unit =
{
updateRows(SeqInsert(rows.length,
RowSpec(id = null, height = height)
))
}
def setPosition(x: Int, y: Int): Unit =
{
this.x = x
this.y = y
// println(s"Position now $x, $y")
WebsocketConnection.broadcast(SetTablePosition(id, x, y))
}
def update(op: TableRequest): Unit =
{
// println(s"Table update: $op")
op match {
case RequestSetTablePosition(_, x, y) => setPosition(x, y)
case RequestUpdateColumns(_, cop) => updateColumns(cop)
case RequestUpdateRows(_, rop) => updateRows(rop)
}
}
}