diff --git a/libs/loadable/loadable.nim b/libs/loadable/loadable.nim index a5122ba..70bfcda 100644 --- a/libs/loadable/loadable.nim +++ b/libs/loadable/loadable.nim @@ -75,15 +75,16 @@ proc newLoadableResource*[T: LoadableResource]( result.str = proc(): string = "" result.use_threads = use_threads -# main -> thread channels -var to_start: Channel[LoadableResource] -# main <- thread channels -var to_return: Channel[(LoadableResource, bool, string, SliceMem[byte])] +when compileOption("threads"): + # main -> thread channels + var to_start: Channel[LoadableResource] + # main <- thread channels + var to_return: Channel[(LoadableResource, bool, string, SliceMem[byte])] proc start*[T: LoadableResource](self: T) = self.status = Started if self.use_threads: - to_start.send self + when compileOption("threads"): to_start.send self else: self.start_func(self) @@ -97,7 +98,8 @@ proc onload*[T: LoadableResource](self: T, ok: bool, err: string, data = SliceMe # self.result[] = (ok, err, data) if self.onload_func != nil: if self.use_threads: - to_return.send((self.LoadableResource, ok, err, data)) + when compileOption("threads"): + to_return.send((self.LoadableResource, ok, err, data)) else: self.onload_func(ok, err, data) @@ -124,30 +126,31 @@ proc cancel*[T: LoadableResource](self: T) = # results.add res.result[] # res.result = nil -var worker: Thread[void] -proc workerThreadProc() {.thread.} = - while true: - let res = to_start.recv() - if res == nil: - break - cast[proc(self: LoadableResource) {.gcsafe.}](res.start_func)(res) +when compileOption("threads"): + var worker: Thread[void] + proc workerThreadProc() {.thread.} = + while true: + let res = to_start.recv() + if res == nil: + break + cast[proc(self: LoadableResource) {.gcsafe.}](res.start_func)(res) -worker.createThread(workerThreadProc) -to_start.open() -to_return.open() + worker.createThread(workerThreadProc) + to_start.open() + to_return.open() -proc updateLoadableWorkerThreads*() = - while true: - let tried = to_return.tryRecv() - if not tried.dataAvailable: - break - let (res, ok, err, data) = tried.msg - res.onload_func(ok, err, data) + proc updateLoadableWorkerThreads*() = + while true: + let tried = to_return.tryRecv() + if not tried.dataAvailable: + break + let (res, ok, err, data) = tried.msg + res.onload_func(ok, err, data) -proc terminateLoadableWorkerThreads*() = - # TODO: test this - to_start.send(nil.LoadableResource) - worker.joinThread() + proc terminateLoadableWorkerThreads*() = + # TODO: test this + to_start.send(nil.LoadableResource) + worker.joinThread() type Fetch* = ref object of LoadableResource custom: pointer @@ -246,7 +249,10 @@ proc loadUri*( var start_func: proc(self: LoadableResource) var self: Fetch var uri = uri - var use_threads = use_threads + when compileOption("threads"): + var use_threads = use_threads + else: + var use_threads = false when not defined(onlyLocalFiles): when defined(emscripten): const is_remote = true diff --git a/src/gpu_formats/texture_optimize.nim b/src/gpu_formats/texture_optimize.nim index df1d827..f399ff2 100644 --- a/src/gpu_formats/texture_optimize.nim +++ b/src/gpu_formats/texture_optimize.nim @@ -367,32 +367,33 @@ proc loadOptimized*(tex: Texture, slices: seq[SliceMem[byte]], , flip = flip, min_channels = min_channels) -# main -> thread channels -type DecodeChanMsg = tuple[ - tex: Texture, slices: seq[SliceMem[byte]], - callback_uncompressed: CallbackUncompressed, - callback_compressed: CallbackCompressed, - flip: bool, min_channels: int, -] -var decode_chan: Channel[DecodeChanMsg] -# main <- thread channels -type DecodeReturnChanMsg = tuple[ - callback: CallbackUncompressed, - tex: Texture, data: SliceMem[byte], -] -var decode_return_chan: Channel[DecodeReturnChanMsg] -type CompressedReturnChanMsg = tuple[ - callback: CallbackCompressed, - tex: Texture, data: KtxInfoParts, refdata: seq[SliceMem[byte]], -] -var compressed_return_chan: Channel[CompressedReturnChanMsg] +when compileOption("threads"): + # main -> thread channels + type DecodeChanMsg = tuple[ + tex: Texture, slices: seq[SliceMem[byte]], + callback_uncompressed: CallbackUncompressed, + callback_compressed: CallbackCompressed, + flip: bool, min_channels: int, + ] + var decode_chan: Channel[DecodeChanMsg] + # main <- thread channels + type DecodeReturnChanMsg = tuple[ + callback: CallbackUncompressed, + tex: Texture, data: SliceMem[byte], + ] + var decode_return_chan: Channel[DecodeReturnChanMsg] + type CompressedReturnChanMsg = tuple[ + callback: CallbackCompressed, + tex: Texture, data: KtxInfoParts, refdata: seq[SliceMem[byte]], + ] + var compressed_return_chan: Channel[CompressedReturnChanMsg] proc loadOptimizedThreaded*(tex: Texture, slices: seq[SliceMem[byte]], callback_uncompressed: CallbackUncompressed = nil, callback_compressed: CallbackCompressed = nil, flip = true, min_channels = 0) = - when false: + when not compileOption("threads"): loadOptimized(tex, slices, callback_uncompressed, callback_compressed, flip, min_channels) else: decode_chan.send((tex: tex, slices: slices, @@ -400,45 +401,46 @@ proc loadOptimizedThreaded*(tex: Texture, slices: seq[SliceMem[byte]], callback_compressed: callback_compressed, flip: flip, min_channels: min_channels)) -var workers = newSeq[Thread[void]](myouEngineNumTextureThreads) -proc workerThreadProc() {.thread.} = - # TODO: handle errors - while true: - let to_decode = decode_chan.recv() - if to_decode.tex == nil: - break - proc cb(tex: Texture, data: SliceMem[byte]) = - decode_return_chan.send((callback: to_decode.callback_uncompressed, tex: tex, data: data)) - proc cbc(tex: Texture, data: KtxInfoParts, refdata: seq[SliceMem[byte]]) = - compressed_return_chan.send((callback: to_decode.callback_compressed, tex: tex, data: data, refdata: refdata)) - let cb_out = if to_decode.callback_uncompressed != nil: cb else: nil - let cbc_out = if to_decode.callback_compressed != nil: cbc else: nil - loadOptimized(to_decode.tex, to_decode.slices, cb_out, cbc_out, - to_decode.flip, to_decode.min_channels) +when compileOption("threads"): + var workers = newSeq[Thread[void]](myouEngineNumTextureThreads) + proc workerThreadProc() {.thread.} = + # TODO: handle errors + while true: + let to_decode = decode_chan.recv() + if to_decode.tex == nil: + break + proc cb(tex: Texture, data: SliceMem[byte]) = + decode_return_chan.send((callback: to_decode.callback_uncompressed, tex: tex, data: data)) + proc cbc(tex: Texture, data: KtxInfoParts, refdata: seq[SliceMem[byte]]) = + compressed_return_chan.send((callback: to_decode.callback_compressed, tex: tex, data: data, refdata: refdata)) + let cb_out = if to_decode.callback_uncompressed != nil: cb else: nil + let cbc_out = if to_decode.callback_compressed != nil: cbc else: nil + loadOptimized(to_decode.tex, to_decode.slices, cb_out, cbc_out, + to_decode.flip, to_decode.min_channels) -decode_chan.open() -decode_return_chan.open() -compressed_return_chan.open() -for worker in workers.mitems: - worker.createThread(workerThreadProc) + decode_chan.open() + decode_return_chan.open() + compressed_return_chan.open() + for worker in workers.mitems: + worker.createThread(workerThreadProc) -proc updateTextureWorkerThreads*() = - # TODO: handle errors - while true: - let tried = decode_return_chan.tryRecv() - if not tried.dataAvailable: - break - let (cb, tex, data) = tried.msg - cb(tex, data) - while true: - let tried = compressed_return_chan.tryRecv() - if not tried.dataAvailable: - break - let (cb, tex, data, refdata) = tried.msg - cb(tex, data, refdata) + proc updateTextureWorkerThreads*() = + # TODO: handle errors + while true: + let tried = decode_return_chan.tryRecv() + if not tried.dataAvailable: + break + let (cb, tex, data) = tried.msg + cb(tex, data) + while true: + let tried = compressed_return_chan.tryRecv() + if not tried.dataAvailable: + break + let (cb, tex, data, refdata) = tried.msg + cb(tex, data, refdata) -proc terminateTextureWorkerThreads*() = - for worker in workers: - decode_chan.send(DecodeChanMsg.default) - for worker in workers: - worker.joinThread() + proc terminateTextureWorkerThreads*() = + for worker in workers: + decode_chan.send(DecodeChanMsg.default) + for worker in workers: + worker.joinThread() diff --git a/src/myou_engine.nim b/src/myou_engine.nim index 04320b1..875c336 100644 --- a/src/myou_engine.nim +++ b/src/myou_engine.nim @@ -77,8 +77,9 @@ import ./screen import ./platform/platform import ./loaders/blend import ./util -from loadable import updateLoadableWorkerThreads -from ./gpu_formats/texture_optimize import updateTextureWorkerThreads +when compileOption("threads"): + from loadable import updateLoadableWorkerThreads + from ./gpu_formats/texture_optimize import updateTextureWorkerThreads import arr_ref export arr_ref @@ -167,8 +168,10 @@ proc myou_main_loop*(self: MyouEngine) = ## ## You usually don't need to call this. Use `run <#run,MyouEngine>`_ ## instead. - updateTextureWorkerThreads() - updateLoadableWorkerThreads() + self.renderer.unbind_all_ubos() + when compileOption("threads"): + updateTextureWorkerThreads() + updateLoadableWorkerThreads() # TODO: make a table object that can be iterated while changing, e.g. with a # seq and a dirty flag to update the seq if self.new_scenes.len != 0: diff --git a/src/platform/glfw_wrap.nim b/src/platform/glfw_wrap.nim index 1cc9c82..a0f75e6 100644 --- a/src/platform/glfw_wrap.nim +++ b/src/platform/glfw_wrap.nim @@ -46,8 +46,9 @@ import ../screen import ../util import ../graphics/render import ../input -from loadable import terminateLoadableWorkerThreads -from ../gpu_formats/texture_optimize import terminateTextureWorkerThreads +when compileOption("threads"): + from loadable import terminateLoadableWorkerThreads + from ../gpu_formats/texture_optimize import terminateTextureWorkerThreads proc screen*(window: Window): Screen {.inline.} = cast[Screen](window.getWindowUserPointer) @@ -234,8 +235,9 @@ proc start_platform_main_loop*(engine: MyouEngine, main_loop: proc(self: MyouEng for i in 0 ..< window.screen.frame_interval: window.swapBuffers() glfw.pollEvents() - terminateLoadableWorkerThreads() - terminateTextureWorkerThreads() + when compileOption("threads"): + terminateLoadableWorkerThreads() + terminateTextureWorkerThreads() glfw.terminate() proc myouAndroidGetActivity*(): pointer =