From 9e120951115415f533b78c02fba50ae9cf9c98d0 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 22 Aug 2020 17:09:22 +0200 Subject: [PATCH] gg: image: return an optional instead of panic(); darwin: fix nsstring() --- thirdparty/fontstash/fontstash.h | 2 + thirdparty/fontstash/stb_truetype.h | 108 ++++++++++++++-------------- vlib/builtin/builtin.v | 16 +++++ vlib/darwin/darwin.m | 9 +++ vlib/darwin/darwin.v | 11 ++- vlib/gg/image.v | 8 ++- vlib/sokol/f/f.v | 2 +- vlib/stbi/stbi.v | 8 +-- vlib/x/net/tcp.v | 3 +- 9 files changed, 101 insertions(+), 66 deletions(-) create mode 100644 vlib/darwin/darwin.m diff --git a/thirdparty/fontstash/fontstash.h b/thirdparty/fontstash/fontstash.h index 45f1560a7..649feda8d 100644 --- a/thirdparty/fontstash/fontstash.h +++ b/thirdparty/fontstash/fontstash.h @@ -174,6 +174,8 @@ FONS_DEF void fonsDrawDebug(FONScontext* s, float x, float y); #undef FONS_USE_FREETYPE +//#define FONS_USE_FREETYPE + #ifdef FONS_USE_FREETYPE #include diff --git a/thirdparty/fontstash/stb_truetype.h b/thirdparty/fontstash/stb_truetype.h index 767f005ab..c4010f557 100644 --- a/thirdparty/fontstash/stb_truetype.h +++ b/thirdparty/fontstash/stb_truetype.h @@ -46,7 +46,7 @@ // Rob Loach Cort Stratton // Kenney Phillis Jr. github:oyvindjam // Brian Costabile github:vassvik -// +// // VERSION HISTORY // // 1.21 (2019-02-25) fix warning @@ -208,7 +208,7 @@ // // Advancing for the next character: // Call GlyphHMetrics, and compute 'current_point += SF * advance'. -// +// // // ADVANCED USAGE // @@ -333,7 +333,7 @@ int main(int argc, char **argv) } return 0; } -#endif +#endif // // Output: // @@ -347,9 +347,9 @@ int main(int argc, char **argv) // :@@. M@M // @@@o@@@@ // :M@@V:@@. -// +// ////////////////////////////////////////////////////////////////////////////// -// +// // Complete program: print "Hello World!" banner, with bugs // #if 0 @@ -650,7 +650,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, cons // Calling these functions in sequence is roughly equivalent to calling // stbtt_PackFontRanges(). If you more control over the packing of multiple // fonts, or if you want to pack custom data into a font texture, take a look -// at the source to of stbtt_PackFontRanges() and create a custom version +// at the source to of stbtt_PackFontRanges() and create a custom version // using these functions, e.g. call GatherRects multiple times, // building up a single array of rects, then call PackRects once, // then call RenderIntoRects repeatedly. This may result in a @@ -958,7 +958,7 @@ STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, floa // and computing from that can allow drop-out prevention). // // The algorithm has not been optimized at all, so expect it to be slow -// if computing lots of characters or very large sizes. +// if computing lots of characters or very large sizes. @@ -1715,7 +1715,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s if (i != 0) num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); - // now start the new one + // now start the new one start_off = !(flags & 1); if (start_off) { // if we start off with an off-curve point, then when we need to find a point on the curve @@ -1768,7 +1768,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s int comp_num_verts = 0, i; stbtt_vertex *comp_verts = 0, *tmp = 0; float mtx[6] = {1,0,0,1,0,0}, m, n; - + flags = ttSHORT(comp); comp+=2; gidx = ttSHORT(comp); comp+=2; @@ -1798,7 +1798,7 @@ static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, s mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; } - + // Find transformation scales. m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); @@ -2727,7 +2727,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); STBTT_assert(z != NULL); if (!z) return z; - + // round dx down to avoid overshooting if (dxdy < 0) z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); @@ -2805,7 +2805,7 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac } } } - + e = e->next; } } @@ -2978,7 +2978,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, float x_top, x_bottom; float sy0,sy1; float dy = e->fdy; - STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); +// STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); // compute endpoints of line segment clipped to this scanline (if the // line segment starts on this scanline. x0 is the intersection of the @@ -3533,7 +3533,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info { int ix0,iy0,ix1,iy1; stbtt__bitmap gbm; - stbtt_vertex *vertices; + stbtt_vertex *vertices; int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); if (scale_x == 0) scale_x = scale_y; @@ -3556,7 +3556,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info if (height) *height = gbm.h; if (xoff ) *xoff = ix0; if (yoff ) *yoff = iy0; - + if (gbm.w && gbm.h) { gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); if (gbm.pixels) { @@ -3567,7 +3567,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info } STBTT_free(vertices, info->userdata); return gbm.pixels; -} +} STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) { @@ -3579,7 +3579,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigne int ix0,iy0; stbtt_vertex *vertices; int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - stbtt__bitmap gbm; + stbtt__bitmap gbm; stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); gbm.pixels = output; @@ -3601,7 +3601,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char * STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); -} +} STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint) { @@ -3616,7 +3616,7 @@ STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, uns STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); -} +} STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) { @@ -3741,7 +3741,7 @@ static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *no con->y = 0; con->bottom_y = 0; STBTT__NOTUSED(nodes); - STBTT__NOTUSED(num_nodes); + STBTT__NOTUSED(num_nodes); } static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) @@ -4126,7 +4126,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char n = 0; for (i=0; i < num_ranges; ++i) n += ranges[i].num_chars; - + rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); if (rects == NULL) return 0; @@ -4137,7 +4137,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); stbtt_PackFontRangesPackRects(spc, rects, n); - + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); STBTT_free(rects, spc->user_allocator_context); @@ -4298,7 +4298,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; - if (x_inter < x) + if (x_inter < x) winding += (y0 < y1) ? 1 : -1; } } @@ -4324,7 +4324,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex y1 = (int)verts[i ].y; if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; - if (x_inter < x) + if (x_inter < x) winding += (y0 < y1) ? 1 : -1; } } else { @@ -4336,7 +4336,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex if (hits[1][0] < 0) winding += (hits[1][1] < 0 ? -1 : 1); } - } + } } } return winding; @@ -4417,7 +4417,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc // invert for y-downwards bitmaps scale_y = -scale_y; - + { int x,y,i,j; float *precompute; @@ -4566,7 +4566,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc STBTT_free(verts, info->userdata); } return data; -} +} STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) { @@ -4584,7 +4584,7 @@ STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) // // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string -static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) { stbtt_int32 i=0; @@ -4623,7 +4623,7 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, s return i; } -static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) +static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) { return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); } @@ -4752,7 +4752,7 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) { - return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); + return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); } STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) @@ -4845,38 +4845,38 @@ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ diff --git a/vlib/builtin/builtin.v b/vlib/builtin/builtin.v index 363ab020f..e8ed60de9 100644 --- a/vlib/builtin/builtin.v +++ b/vlib/builtin/builtin.v @@ -113,11 +113,27 @@ pub fn print(s string) { const ( new_line_character = '\n' ) + +//#include "@VROOT/vlib/darwin/darwin.m" + +//fn C.nsstring2(s string) voidptr +//fn C.NSLog(x voidptr) +#include + + +fn C.asl_log(voidptr, voidptr, int, charptr) + pub fn println(s string) { $if windows { print(s) print(new_line_character) } $else { + // For debugging .app applications (no way to read stdout) so that it's printed to macOS Console + /* + $if macos { + C.asl_log(0, 0, C.ASL_LEVEL_ERR, s.str) + } + */ // TODO: a syscall sys_write on linux works, except for the v repl. // Probably it is a stdio buffering issue. Needs more testing... // $if linux { diff --git a/vlib/darwin/darwin.m b/vlib/darwin/darwin.m new file mode 100644 index 000000000..5cab83ad6 --- /dev/null +++ b/vlib/darwin/darwin.m @@ -0,0 +1,9 @@ + +///void NSLog(id x); + +#include + +NSString* nsstring2(string s) { + return [ [ NSString alloc ] initWithBytesNoCopy:s.str length:s.len + encoding:NSUTF8StringEncoding freeWhenDone: false]; +} diff --git a/vlib/darwin/darwin.v b/vlib/darwin/darwin.v index 3bf2d0fc8..e5b5f9781 100644 --- a/vlib/darwin/darwin.v +++ b/vlib/darwin/darwin.v @@ -8,13 +8,18 @@ module darwin struct C.NSString { } +#include "@VROOT/vlib/darwin/darwin.m" + +fn C.nsstring2(s string) voidptr + // macOS and iOS helpers //pub fn nsstring(s string) *C.NSString { pub fn nsstring(s string) voidptr { + return C.nsstring2(s) // println('ns $s len=$s.len') - # return [ [ NSString alloc ] initWithBytesNoCopy:s.str length:s.len - # encoding:NSUTF8StringEncoding freeWhenDone: false]; - return 0 + //# return [ [ NSString alloc ] initWithBytesNoCopy:s.str length:s.len + //# encoding:NSUTF8StringEncoding freeWhenDone: false]; + //return 0 //ns := C.alloc_NSString() //return ns.initWithBytesNoCopy(s.str, length: s.len, diff --git a/vlib/gg/image.v b/vlib/gg/image.v index 2d2e3130d..28c796008 100644 --- a/vlib/gg/image.v +++ b/vlib/gg/image.v @@ -26,10 +26,12 @@ pub mut: fn C.sg_isvalid() bool +// TODO return ?Image pub fn (mut ctx Context) create_image(file string) Image { if !C.sg_isvalid() { + // Sokol is not initialized yet, add stbi object to a queue/cache //ctx.image_queue << file - stb_img := stbi.load(file) + stb_img := stbi.load(file) or { return Image{} } img := Image{ width: stb_img.width height: stb_img.height @@ -55,7 +57,7 @@ fn create_image(file string) Image { println('gg.create_image(): file not found: $file') return Image{} // none } - stb_img := stbi.load(file) + stb_img := stbi.load(file) or { return Image{} } mut img := Image{ width: stb_img.width height: stb_img.height @@ -70,7 +72,7 @@ fn create_image(file string) Image { } pub fn create_image_from_memory(buf byteptr, bufsize int) Image { - stb_img := stbi.load_from_memory(buf, bufsize) + stb_img := stbi.load_from_memory(buf, bufsize) or { return Image{} } mut img := Image{ width: stb_img.width height: stb_img.height diff --git a/vlib/sokol/f/f.v b/vlib/sokol/f/f.v index 3f072a35b..2054bf916 100644 --- a/vlib/sokol/f/f.v +++ b/vlib/sokol/f/f.v @@ -6,10 +6,10 @@ pub const ( used_import = 1 + fontstash.used_import ) +/* #flag windows -I @VROOT/thirdparty/freetype/include #flag windows -L @VROOT/thirdparty/freetype/win64 -/* #flag linux -I/usr/include/freetype2 #flag darwin -I/usr/local/include/freetype2 // MacPorts diff --git a/vlib/stbi/stbi.v b/vlib/stbi/stbi.v index eb19b7e45..763bd1aa0 100644 --- a/vlib/stbi/stbi.v +++ b/vlib/stbi/stbi.v @@ -28,7 +28,7 @@ fn init() { set_flip_vertically_on_load(false) } -pub fn load(path string) Image { +pub fn load(path string) ?Image { ext := path.all_after_last('.') mut res := Image { ok: true @@ -38,12 +38,12 @@ pub fn load(path string) Image { flag := if ext == 'png' { C.STBI_rgb_alpha } else { 0 } res.data = C.stbi_load(path.str, &res.width, &res.height, &res.nr_channels, flag) if isnil(res.data) { - panic('stbi image failed to load from "$path"') + return error('stbi image failed to load from "$path"') } return res } -pub fn load_from_memory(buf byteptr, bufsize int) Image { +pub fn load_from_memory(buf byteptr, bufsize int) ?Image { mut res := Image { ok: true data: 0 @@ -51,7 +51,7 @@ pub fn load_from_memory(buf byteptr, bufsize int) Image { flag := C.STBI_rgb_alpha res.data = C.stbi_load_from_memory(buf, bufsize, &res.width, &res.height, &res.nr_channels, flag) if isnil(res.data) { - panic('stbi image failed to load from memory') + return error('stbi image failed to load from memory') } return res } diff --git a/vlib/x/net/tcp.v b/vlib/x/net/tcp.v index 5032f7d3e..9f303a5ca 100644 --- a/vlib/x/net/tcp.v +++ b/vlib/x/net/tcp.v @@ -274,6 +274,7 @@ fn new_tcp_socket() ?TcpSocket { handle: sockfd } s.set_option_bool(.reuse_addr, true)? + //s.set_option_int(.reuse_addr, 1)? $if windows { t := true socket_error(C.ioctlsocket(sockfd, fionbio, &t))? @@ -352,4 +353,4 @@ pub fn (s TcpSocket) address() ?Addr { sockaddr := &C.sockaddr(&addr) C.getsockname(s.handle, sockaddr, &size) return new_addr(sockaddr, '', 0) -} \ No newline at end of file +} -- 2.30.2