@@ -19,35 +19,47 @@ pub const Client = struct {
1919 state : State ,
2020 game : ? Game = null ,
2121 nameIter : NameIterator = undefined ,
22+ gamesLeft : ? u32 = undefined ,
23+ shouldRun : bool = true ,
2224
2325 /// sets up TCP connection
2426 /// after init .game is still null, .game will be initialized in .parse() if client recieves c message from server
25- pub fn init (hostname : []const u8 , port : u16 ) ! Client {
27+ pub fn init (hostname : []const u8 , port : u16 , gamesToPlay : ? u32 ) ! Client {
2628 const peer = try std .net .Address .parseIp4 (hostname , port );
2729 const strm = try std .net .tcpConnectToAddress (peer );
2830 try std .io .getStdOut ().writer ().print ("connected to: {s}:{d}\n " , .{ hostname , port });
29- return Client { .stream = strm , .state = State .Connected };
31+ return Client {
32+ .stream = strm ,
33+ .state = State .Connected ,
34+ .gamesLeft = gamesToPlay ,
35+ };
3036 }
3137
3238 /// reads from socket stream until delimiter is found
3339 /// if message delimiter \n is found => calls self.parse()
3440 /// should block until finds delimiter, but instead throws error if delimiter not found in stream - TO FIX
35- pub fn read (self : * Client , allocator : Allocator ) ! bool {
41+ pub fn read (self : * Client , allocator : Allocator ) ! void {
3642 var buff = std .ArrayList (u8 ).init (allocator );
3743 defer buff .deinit ();
38- self .stream .reader ().streamUntilDelimiter (buff .writer (), '\n ' , null ) catch {
39- try std .io .getStdOut ().writer ().print ("server closed the connection\n " , .{});
40- return false ;
41- };
4244
43- if (buff .items .len == 0 ) {
44- try std .io .getStdOut ().writer ().print ("server closed the connection\n " , .{});
45- return false ;
45+ var run = true ;
46+ var prevLen = buff .items .len ;
47+ while (run ) {
48+ run = false ;
49+ self .stream .reader ().streamUntilDelimiter (buff .writer (), '\n ' , null ) catch | err | {
50+ if (err == error .EndOfStream ) {
51+ if (buff .items .len == prevLen ) { // no new bytes found - meaning received 0 bytes in last read - meaning server closed connection
52+ try std .io .getStdOut ().writer ().print ("server closed the connection\n " , .{});
53+ self .shouldRun = false ;
54+ return ;
55+ } else run = true ; // end of stream reached, got some bytes, but no delimiter (hopefully remaining bytes will get there soon)
56+ } else return err ;
57+ };
58+ prevLen = buff .items .len ;
4659 }
4760 // print("MSG: {s}\n", .{buff.items});
4861
4962 try self .parse (buff .items , allocator );
50- return true ;
5163 }
5264
5365 /// sends msg to server in a blocking manner
@@ -271,15 +283,30 @@ pub const Client = struct {
271283 }
272284 }
273285
286+ /// decrement value of games left to play
287+ /// if it reaches 0 then set stop operation flag
288+ fn decrementGameCounter (self : * Client ) void {
289+ if (self .gamesLeft ) | * gl | {
290+ std .debug .assert (gl .* > 0 );
291+ gl .* -= 1 ;
292+ if (gl .* == 0 ) self .shouldRun = false ;
293+ }
294+ }
295+
274296 /// client loop
275297 /// runs forever or until an error is thrown somewere
276298 pub fn loop (self : * Client , allocator : Allocator ) void {
277- while (self .read (allocator ) catch false ) {}
299+ while (self .shouldRun ) {
300+ self .read (allocator ) catch | err | {
301+ self .shouldRun = false ;
302+ print ("execution stopped due to error: {s}\n " , .{@errorName (err )});
303+ };
304+ }
278305 }
279306
280307 pub fn deinit (self : * Client ) void {
281308 self .stream .close ();
282- self .game .? .deinit ();
309+ if ( self .game ) | * cgame | cgame .deinit ();
283310 }
284311};
285312
0 commit comments