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, + }; +}; |