From d3eaceebe43cbb6b85125f73fbef3cf2241fe452 Mon Sep 17 00:00:00 2001 From: ubq323 Date: Mon, 15 Apr 2024 20:19:25 +0100 Subject: add stroke drawop and refactor drawop ser/deser a bit --- drawing/op.ha | 97 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 18 deletions(-) (limited to 'drawing/op.ha') diff --git a/drawing/op.ha b/drawing/op.ha index 532fd75..aa7fac4 100644 --- a/drawing/op.ha +++ b/drawing/op.ha @@ -3,33 +3,94 @@ use endian; export type op_circle = struct { pos: pos, + color: u32, radius: u8, - color: u32 }; -export type op_other = void; +export type op_stroke = struct { + pos0: pos, + pos1: pos, + color: u32, + radius: u8, + count: u8, +}; -export type op = (op_circle| op_other); +export type op = (op_circle | op_stroke); +type op_type = enum u8 { + CIRCLE, + STROKE, +}; -def SER_LEN: size = 13; +export type deser_fail = !void; // return value must be freed... for now. ehh -export fn ser_op(op: op) []u8 = { - const opc = op as op_circle; - let buf: []u8 = alloc([0...],SER_LEN); - endian::leputu32(buf[0..4], opc.pos.0: u32); - endian::leputu32(buf[4..8], opc.pos.1: u32); - endian::leputu32(buf[8..12], opc.color: u32); - buf[12] = opc.radius; - return buf; +export fn ser_op(op: op) []u8 = match (op) { + case let opc: op_circle => yield ser_op_circle(opc); + case let ops: op_stroke => yield ser_op_stroke(ops); +}; + +export fn deser_op(bytes: []u8) (op | deser_fail) = switch (bytes[0]) { + case op_type::CIRCLE => yield deser_op_circle(bytes)?; + case op_type::STROKE => yield deser_op_stroke(bytes)?; + case => yield deser_fail; }; -export fn deser_op(bytes: []u8) op = { - assert(len(bytes) == SER_LEN, "wrong length somehow"); + +fn ser_pos(bytes: []u8, pos: pos) void = { + endian::leputu32(bytes[0..4], pos.0: u32); + endian::leputu32(bytes[4..8], pos.1: u32); +}; +fn deser_pos(bytes: []u8) pos = ( + endian::legetu32(bytes[0..4]): i32, + endian::legetu32(bytes[4..8]): i32 +); + + +def SER_LEN_CIRCLE = 14; +// type:1 pos: 8 color: 4, radius:1 +fn ser_op_circle(opc: op_circle) []u8 = { + let buf: []u8 = alloc([0...],SER_LEN_CIRCLE); + buf[0] = op_type::CIRCLE; + let payload = buf[1..]; + + ser_pos(payload[0..8], opc.pos); + endian::leputu32(payload[8..12], opc.color: u32); + payload[12] = opc.radius; + return buf; +}; +fn deser_op_circle(bytes: []u8) (op_circle|deser_fail) = { + if (len(bytes) != SER_LEN_CIRCLE) return deser_fail; + let payload = bytes[1..]; return op_circle { - pos = (endian::legetu32(bytes[0..4]): i32, - endian::legetu32(bytes[4..8]): i32), - color = endian::legetu32(bytes[8..12]), - radius = bytes[12], + pos = deser_pos(payload[0..8]), + color = endian::legetu32(payload[8..12]), + radius = payload[12], + }; +}; + +def SER_LEN_STROKE = 23; +// type:1 pos0:8 pos1:8 color:4 radius:1 count:1 +fn ser_op_stroke(ops: op_stroke) []u8 = { + let buf: []u8 = alloc([0...], SER_LEN_STROKE); + buf[0] = op_type::STROKE; + let payload = buf[1..]; + + ser_pos(payload[0..8], ops.pos0); + ser_pos(payload[8..16], ops.pos1); + endian::leputu32(payload[16..20], ops.color); + payload[20] = ops.radius; + payload[21] = ops.count; + return buf; +}; +fn deser_op_stroke(bytes: []u8) (op_stroke|deser_fail) = { + if (len(bytes) != SER_LEN_STROKE) return deser_fail; + let payload = bytes[1..]; + return op_stroke { + pos0 = deser_pos(payload[0..8]), + pos1 = deser_pos(payload[8..16]), + color = endian::legetu32(payload[16..20]), + radius = payload[20], + count = payload[21], }; }; + -- cgit v1.2.3