diff options
| author | ubq323 <ubq323@ubq323.website> | 2024-04-15 20:19:25 +0100 | 
|---|---|---|
| committer | ubq323 <ubq323@ubq323.website> | 2024-04-15 20:19:25 +0100 | 
| commit | d3eaceebe43cbb6b85125f73fbef3cf2241fe452 (patch) | |
| tree | 64902701cb24bf0715364e8fddd534de1bc97190 | |
| parent | e19852c958838688481422ed3ddd953d2dcd4309 (diff) | |
add stroke drawop and refactor drawop ser/deser a bit
| -rw-r--r-- | client/main.ha | 5 | ||||
| -rw-r--r-- | drawing/drawing.ha | 1 | ||||
| -rw-r--r-- | drawing/op.ha | 97 | ||||
| -rw-r--r-- | server/main.ha | 3 | ||||
| -rw-r--r-- | todo | 1 | 
5 files changed, 83 insertions, 24 deletions
| diff --git a/client/main.ha b/client/main.ha index 4c70892..9b8f92b 100644 --- a/client/main.ha +++ b/client/main.ha @@ -45,7 +45,7 @@ export fn main() void = {  	};  	// connect to server -	const conn = match(dial::dial("tcp","ubq323.website","41460")) { +	const conn = match(dial::dial("tcp","localhost","41460")) {  		case let c: net::socket => yield c;  		case let err: net::error =>  			fmt::fatal("couldn't connect to server:",net::strerror(err)); @@ -139,8 +139,7 @@ export fn main() void = {  			for (const packet => packet_reader::next(&packet_reader)!) {  				match (packet) {  				case let op: packet_reader::packet_drawop => -					const opc = op as drawing::op_circle; -					drawing::perform(pictures, opc); +					drawing::perform(pictures, op);  				case let packet: packet_reader::packet_sendchunk =>  					assert(packet.world_pos.0 % CHUNKSIZE == 0  							&& packet.world_pos.1 % CHUNKSIZE == 0, "bad chunk world pos"); 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],  	};  }; + diff --git a/server/main.ha b/server/main.ha index cf8e720..2043a1d 100644 --- a/server/main.ha +++ b/server/main.ha @@ -197,10 +197,9 @@ fn handle_packet(  	const conn = &state.connections[conn_idx];  	match (packet) {  	case let op: packet_reader::packet_drawop => -		const opc = op as drawing::op_circle;  		// fmt::printfln("#{}: drawop  ({:+6},{:+6}) r{}",  			// conn_idx,opc.pos.0,opc.pos.1, opc.radius)!; -		drawing::perform(state.pictures, opc); +		drawing::perform(state.pictures, op);  		for (let other_idx = 0z;  				other_idx < len(state.connections);  				other_idx += 1) @@ -1,2 +1,3 @@  smooth brush strokes  rle compression +more elegant solution to big packets than just having a giant buffer | 
