Mercurial > games > semicongine
view semicongine/background_loader.nim @ 1401:4ecb004ee7f8
did: add horizontal advancment for glyph rendering
author | sam <sam@basx.dev> |
---|---|
date | Mon, 16 Dec 2024 23:58:35 +0700 |
parents | 3dbf77ca78b9 |
children | 3b8a736c45a7 |
line wrap: on
line source
import std/syncio import std/tables type LoaderThreadArgs[T] = ( ptr Channel[(string, string)], ptr Channel[LoaderResponse[T]], proc(f, p: string): T {.gcsafe.}, ) LoaderResponse[T] = object path: string package: string data: T error: string BackgroundLoader[T] = object loadRequestCn: Channel[(string, string)] # used for sending load requests responseCn: Channel[LoaderResponse[T]] # used for sending back loaded data worker: Thread[LoaderThreadArgs[T]] # does the actual loading from the disk responseTable: Table[string, LoaderResponse[T]] # stores results proc loader[T](args: LoaderThreadArgs[T]) {.thread.} = while true: let (path, package) = args[0][].recv() try: args[1][].send( LoaderResponse[T](path: path, package: package, data: args[2](path, package)) ) except Exception as e: args[1][].send(LoaderResponse[T](path: path, package: package, error: e.msg)) proc fetchAll*(ld: var BackgroundLoader) = var (hasData, response) = ld.responseCn.tryRecv() while hasData: ld.responseTable[response.package & ":" & response.path] = response (hasData, response) = ld.responseCn.tryRecv() proc requestLoading*(ld: var BackgroundLoader, path, package: string) = ld.loadRequestCn.send((path, package)) proc isLoaded*(ld: var BackgroundLoader, path, package: string): bool = fetchAll(ld) (package & ":" & path) in ld.responseTable proc getLoadedData*[T](ld: var BackgroundLoader[T], path, package: string): T = var item: LoaderResponse[T] doAssert ld.responseTable.pop(package & ":" & path, item) if item.error != "": raise newException(Exception, item.error) result = item.data proc initBackgroundLoader*[T]( loadFn: proc(path, package: string): T {.gcsafe.} ): ptr BackgroundLoader[T] = result = createShared(BackgroundLoader[T]) open(result.loadRequestCn) open(result.responseCn) createThread[LoaderThreadArgs[T]]( result.worker, loader[T], (addr result.loadRequestCn, addr result.responseCn, loadFn), )