aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/main.ha155
-rw-r--r--server/save_load.ha96
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,
+ };
+};