diff options
| author | ubq323 <ubq323@ubq323.website> | 2024-04-13 22:59:07 +0100 | 
|---|---|---|
| committer | ubq323 <ubq323@ubq323.website> | 2024-04-13 22:59:07 +0100 | 
| commit | c95e947d90a02091aef4e63693ce3205fdfba3b6 (patch) | |
| tree | 933a136be180f88741ec89960882ebe494477e1e | |
| parent | 53e2a1d2e8a110b30dd47f0a47574625286e4ff5 (diff) | |
move things
| -rw-r--r-- | server/main.ha | 155 | ||||
| -rw-r--r-- | server/save_load.ha | 96 | 
2 files changed, 100 insertions, 151 deletions
| diff --git a/server/main.ha b/server/main.ha index 6beeee3..1dffbb5 100644 --- a/server/main.ha +++ b/server/main.ha @@ -36,6 +36,7 @@ type connection = struct {  	should_delete: bool,  }; +def save_interval = 20 * time::SECOND;  export fn main() void = {  	// create 4 pictures. later we will have more pictures @@ -53,7 +54,9 @@ export fn main() void = {  		});  	}; -	const listener = match(tcp::listen(ip::ANY_V4, PORT, tcp::reuseaddr)) { +	const listener = match ( +		tcp::listen(ip::ANY_V4, PORT, tcp::reuseaddr) +	) {  	case let err: net::error =>  		fmt::fatalf(net::strerror(err));  	case let sock: net::socket => @@ -91,153 +94,6 @@ export fn main() void = {  }; -def save_interval = 20 * time::SECOND; - -// caller should free return value -fn filename_from_world_pos(pos: pos) str = -	fmt::asprintf("./c.{}.{}.ppm",pos.0,pos.1); - -fn save_world(state: *server_state) (void | fs::error) = { -	fmt::printfln("saving world!")!; -	for (const pic &.. state.pictures) { -		const filename = filename_from_world_pos(pic.world_pos); -		fmt::printfln("\t-> {}",filename)!; -		defer free(filename); - -		const mode = fs::mode::USER_RW | fs::mode::GROUP_RW; -		const file = os::create(filename, mode)?; -		defer io::close(file): void; - -		fmt::fprintf(file, "P6\n{} {}\n{}\n", pic.w, pic.h, 255)?; - -		let buf: []u8 = alloc([0...],3*pic.w*pic.h); -		defer free(buf); -		for (let i = 0z; i < pic.w * pic.h; i += 1) { -			const px = pic.d[i]; -			buf[3*i  ] = ((px>>16)&0xff): u8; -			buf[3*i+1] = ((px>>8) &0xff): u8; -			buf[3*i+2] = ((px)    &0xff): u8; -		}; -		io::writeall(file, buf)?; -	}; -		 -}; - -fn new_picture(world_pos: pos) drawing::picture = { -	let picture_buf: []u32 = alloc([0xffffff...], CHUNKSIZE*CHUNKSIZE); -	return drawing::picture { -		w = CHUNKSIZE, -		h = CHUNKSIZE, -		d = picture_buf: *[*]u32, -		world_pos = world_pos, -	}; -}; - -type bad_header = !void; - -// loads the chunk at the given position from the filesystem, -// or, if no file is found, creates a fresh new chunk -fn load_picture_from_file(world_pos: pos) (drawing::picture | fs::error | bad_header) = { -	const filename = filename_from_world_pos(world_pos); -	defer free(filename); -	const file = match (os::open(filename)) { -		case let f: io::file => yield f; -		case errors::noentry => return new_picture(world_pos); -		case let e: fs::error => return e; -	}; -	fmt::printfln("reading from {}",filename)!; -	defer { -		fmt::printfln("closing {}",filename)!; -		match (io::close(file)) { -			case let err: io::error => fmt::println("error",io::strerror(err))!; -			case => yield; -		}; -	}; - -	const header = fmt::asprintf("P6\n{} {}\n{}\n",CHUNKSIZE,CHUNKSIZE,255); -	defer free(header); -	const header_bytes = strings::toutf8(header); -	let header_buf: []u8 = alloc([0...],len(header_bytes)); -	defer free(header_buf); -	io::readall(file, header_buf)?; -	if (!bytes::equal(header_buf, header_bytes)) return bad_header; - -	let file_buf: []u8 = alloc([0...], 3*CHUNKSIZE*CHUNKSIZE); -	defer free(file_buf); -	io::readall(file, file_buf)?; -	let picture_buf: []u32 = alloc([0...], CHUNKSIZE*CHUNKSIZE); -	for (let i = 0z; i < len(picture_buf); i += 1) { -		picture_buf[i] = (file_buf[3*i]:u32<<16) -						|(file_buf[3*i+1]:u32<<8) -						|(file_buf[3*i+2]:u32); -	}; -	return drawing::picture { -		w = CHUNKSIZE, -		h = CHUNKSIZE, -		d = picture_buf: *[*]u32, -		world_pos = world_pos, -	}; -}; - -// fn old_loop(listener: net::socket, pictures: []drawing::picture) void = { -// 	// pollfds[0] is the listener -// 	// pollfds[n>0] corresponds to packet_readers[n-1] -// 	let pollfds: []poll::pollfd = alloc([ poll::pollfd { -// 		fd = listener, events = poll::event::POLLIN, revents = 0 -// 	}]); -// 	let packet_readers: []packet_reader::packet_reader = []; - - -// 	let now = time::now(time::clock::MONOTONIC); -// 	let next = time::add(now, save_interval); -// 	save_world(pictures); - -// 	for (true) { -// 		fmt::println("poll.")!; -// 		const timeout = time::diff(now, next); -// 		poll::poll(pollfds, timeout)!; - -// 		now = time::now(time::clock::MONOTONIC); -// 		if (time::compare(now, next) >= 0) { -// 			save_world(pictures); -// 			next = time::add(now, save_interval); -// 		}; - -// 		if (0 != pollfds[0].revents & poll::event::POLLIN) { -// 			fmt::println("new conn")!; -// 			const new_conn = tcp::accept(pollfds[0].fd)!; -// 			fmt::println("a")!; -// 			append(pollfds, poll::pollfd { -// 				fd = new_conn, -// 				events = poll::event::POLLIN, revents = 0 -// 			}); -// 			append(packet_readers, packet_reader::new()); -// 			fmt::printfln("there are now {},{} conns.",len(pollfds),len(packet_readers))!; -// 			send_world(new_conn, pictures)!; -// 		}; -// 		for (let connidx = 1z; connidx < len(pollfds); connidx += 1) { -// 			if (0 != pollfds[connidx].revents & poll::event::POLLIN) { -// 				match (packet_reader::read(&packet_readers[connidx-1], pollfds[connidx].fd)) { -// 				case void => -// 					for (const packet => packet_reader::next(&packet_readers[connidx-1])!) { -// 						handle_packet(pictures, pollfds, packet, connidx); -// 					}; -// 				case let err: io::error => -// 					fmt::printfln("#{} error: {}",connidx,io::strerror(err))!; -// 					delete(pollfds[connidx]); -// 					delete(packet_readers[connidx-1]); -// 					connidx -= 1; -// 				case io::EOF => -// 					fmt::printfln("#{} disconnect",connidx)!; -// 					delete(pollfds[connidx]); -// 					delete(packet_readers[connidx-1]); -// 					connidx -= 1; -// 				}; -// 			}; -// 		}; -// 	}; -// }; -  fn loop(state: *server_state, timeout: time::duration) void = {  	// do poll.  	let pollfds: []poll::pollfd = []; @@ -317,13 +173,10 @@ fn read_from_connection(state: *server_state, conn_idx: size) void = {  			case let e: packet_reader::error =>  				fmt::printfln("packet error {}",e)!;  				conn.should_delete = true; -			case => fmt::printfln("eoeugh")!;  			};  	};  }; - -  fn handle_packet(  	state: *server_state,  	conn_idx: size, diff --git a/server/save_load.ha b/server/save_load.ha new file mode 100644 index 0000000..cf82a0d --- /dev/null +++ b/server/save_load.ha @@ -0,0 +1,96 @@ +use bytes; +use errors; +use fmt; +use fs; +use io; +use os; +use strings; + +use drawing; +use drawing::{pos}; + +// caller should free return value +fn filename_from_world_pos(pos: pos) str = +	fmt::asprintf("./c.{}.{}.ppm",pos.0,pos.1); + +fn save_world(state: *server_state) (void | fs::error) = { +	fmt::printfln("saving world!")!; +	for (const pic &.. state.pictures) { +		const filename = filename_from_world_pos(pic.world_pos); +		fmt::printfln("\t-> {}",filename)!; +		defer free(filename); + +		const mode = fs::mode::USER_RW | fs::mode::GROUP_RW; +		const file = os::create(filename, mode)?; +		defer io::close(file): void; + +		fmt::fprintf(file, "P6\n{} {}\n{}\n", pic.w, pic.h, 255)?; + +		let buf: []u8 = alloc([0...],3*pic.w*pic.h); +		defer free(buf); +		for (let i = 0z; i < pic.w * pic.h; i += 1) { +			const px = pic.d[i]; +			buf[3*i  ] = ((px>>16)&0xff): u8; +			buf[3*i+1] = ((px>>8) &0xff): u8; +			buf[3*i+2] = ((px)    &0xff): u8; +		}; +		io::writeall(file, buf)?; +	}; +		 +}; + +fn new_picture(world_pos: pos) drawing::picture = { +	let picture_buf: []u32 = alloc([0xffffff...], CHUNKSIZE*CHUNKSIZE); +	return drawing::picture { +		w = CHUNKSIZE, +		h = CHUNKSIZE, +		d = picture_buf: *[*]u32, +		world_pos = world_pos, +	}; +}; + +type bad_header = !void; + +// loads the chunk at the given position from the filesystem, +// or, if no file is found, creates a fresh new chunk +fn load_picture_from_file(world_pos: pos) (drawing::picture | fs::error | bad_header) = { +	const filename = filename_from_world_pos(world_pos); +	defer free(filename); +	const file = match (os::open(filename)) { +		case let f: io::file => yield f; +		case errors::noentry => return new_picture(world_pos); +		case let e: fs::error => return e; +	}; +	fmt::printfln("reading from {}",filename)!; +	defer { +		fmt::printfln("closing {}",filename)!; +		match (io::close(file)) { +			case let err: io::error => fmt::println("error",io::strerror(err))!; +			case => yield; +		}; +	}; + +	const header = fmt::asprintf("P6\n{} {}\n{}\n",CHUNKSIZE,CHUNKSIZE,255); +	defer free(header); +	const header_bytes = strings::toutf8(header); +	let header_buf: []u8 = alloc([0...],len(header_bytes)); +	defer free(header_buf); +	io::readall(file, header_buf)?; +	if (!bytes::equal(header_buf, header_bytes)) return bad_header; + +	let file_buf: []u8 = alloc([0...], 3*CHUNKSIZE*CHUNKSIZE); +	defer free(file_buf); +	io::readall(file, file_buf)?; +	let picture_buf: []u32 = alloc([0...], CHUNKSIZE*CHUNKSIZE); +	for (let i = 0z; i < len(picture_buf); i += 1) { +		picture_buf[i] = (file_buf[3*i]:u32<<16) +						|(file_buf[3*i+1]:u32<<8) +						|(file_buf[3*i+2]:u32); +	}; +	return drawing::picture { +		w = CHUNKSIZE, +		h = CHUNKSIZE, +		d = picture_buf: *[*]u32, +		world_pos = world_pos, +	}; +}; | 
