summaryrefslogtreecommitdiff
path: root/drawing
diff options
context:
space:
mode:
Diffstat (limited to 'drawing')
-rw-r--r--drawing/drawing.ha1
-rw-r--r--drawing/op.ha97
2 files changed, 79 insertions, 19 deletions
diff --git a/drawing/drawing.ha b/drawing/drawing.ha
index 54a877b..063577d 100644
--- a/drawing/drawing.ha
+++ b/drawing/drawing.ha
@@ -100,7 +100,6 @@ export fn circle_hollow(picture: *picture, c: pos, r: i32, color: u32) void = {
};
export fn perform(pictures: []picture, op: op) void = {
match (op) {
- case op_other => abort("oopsy");
case let o: op_circle =>
const x = o.pos.0, y=o.pos.1;
const r = o.radius;
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],
};
};
+