From 0ca5b1cd2077136e99a4ff349b665db8f97824d1 Mon Sep 17 00:00:00 2001 From: rexim Date: Fri, 11 Oct 2019 15:48:02 +0700 Subject: [PATCH 1/3] (#33) Add config module --- src/config.nim | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/config.nim diff --git a/src/config.nim b/src/config.nim new file mode 100644 index 0000000..9603dce --- /dev/null +++ b/src/config.nim @@ -0,0 +1,56 @@ +import macros + +type Config* = object + scrollSpeed: float + dragVelocityFactor: float + dragFriction: float + scaleFriction: float + +macro saveConfig*(config: typed, filePath: typed): untyped = + if config.getType.typeKind != ntyObject: + error("Expected object kind", config) + + result = nnkStmtList.newTree( + nnkVarSection.newTree( + nnkIdentDefs.newTree( + newIdentNode("f"), + newEmptyNode(), + nnkCall.newTree( + newIdentNode("open"), + newLit("hello.conf"), + newIdentNode("fmWrite") + ) + ) + ), + nnkLetSection.newTree( + nnkIdentDefs.newTree( + newIdentNode("config"), + newEmptyNode(), + config + ) + )) + + for i in config.getType[2].children: + result.add(nnkCall.newTree( + nnkDotExpr.newTree( + newIdentNode("f"), + newIdentNode("writeLine") + ), + newLit(i.repr), + newLit("="), + nnkDotExpr.newTree( + newIdentNode("config"), + newIdentNode(i.repr) + ) + )) + +# proc saveConfig(config: Config, filePath: string) = +# var f = open(filePath, fmWrite) +# defer: f.close +# f.writeLine("scroll_speed=", config.scrollSpeed) +# f.writeLine("drag_velocity_factor=", config.drag_velocity_factor) +# f.writeLine("drag_friction=", config.drag_friction) +# f.writeLine("scale_friction=", config.scale_friction) + +proc loadConfig(filePath: string): Config = + discard From 3e1f4f4de40db2ae08aa2a76fa0215e1cd87bc24 Mon Sep 17 00:00:00 2001 From: rexim Date: Fri, 11 Oct 2019 19:50:41 +0700 Subject: [PATCH 2/3] (#33) Get rid of macro madness and just read the config --- src/boomer.nim | 12 +++---- src/config.nim | 83 ++++++++++++++++++---------------------------- src/navigation.nim | 12 +++---- 3 files changed, 42 insertions(+), 65 deletions(-) diff --git a/src/boomer.nim b/src/boomer.nim index 3c92cd1..d965531 100644 --- a/src/boomer.nim +++ b/src/boomer.nim @@ -5,8 +5,7 @@ import math import vec2 import navigation import image - -const FPS: int = 60 +import config template checkError(context: string) = let error = glGetError() @@ -148,6 +147,7 @@ proc main() = var quitting = false var camera = Camera(scale: 1.0) var mouse: Mouse + var config = defaultConfig while not quitting: var xev: TXEvent @@ -163,7 +163,7 @@ proc main() = if mouse.drag: camera.position += camera.world(mouse.curr) - camera.world(mouse.prev) - camera.velocity = (mouse.curr - mouse.prev) * DRAG_VELOCITY_FACTOR + camera.velocity = (mouse.curr - mouse.prev) * config.drag_velocity_factor mouse.prev = mouse.curr of ClientMessage: @@ -187,10 +187,10 @@ proc main() = mouse.drag = true of WHEEL_UP: - camera.delta_scale += SCROLL_SPEED + camera.delta_scale += config.scroll_speed of WHEEL_DOWN: - camera.delta_scale -= SCROLL_SPEED + camera.delta_scale -= config.scroll_speed else: discard @@ -204,7 +204,7 @@ proc main() = else: discard - camera.update(1.0 / FPS.float, mouse) + camera.update(config, 1.0 / config.fps.float, mouse) screenshot.display(camera) glXSwapBuffers(display, win) diff --git a/src/config.nim b/src/config.nim index 9603dce..58046ab 100644 --- a/src/config.nim +++ b/src/config.nim @@ -1,56 +1,37 @@ import macros +import strutils type Config* = object - scrollSpeed: float - dragVelocityFactor: float - dragFriction: float - scaleFriction: float + scrollSpeed*: float + dragVelocityFactor*: float + dragFriction*: float + scaleFriction*: float + fps*: int -macro saveConfig*(config: typed, filePath: typed): untyped = - if config.getType.typeKind != ntyObject: - error("Expected object kind", config) +const defaultConfig* = Config( + scroll_speed: 1.0, + drag_velocity_factor: 20.0, + drag_friction: 2000.0, + scale_friction: 5.0, + fps: 60 +) - result = nnkStmtList.newTree( - nnkVarSection.newTree( - nnkIdentDefs.newTree( - newIdentNode("f"), - newEmptyNode(), - nnkCall.newTree( - newIdentNode("open"), - newLit("hello.conf"), - newIdentNode("fmWrite") - ) - ) - ), - nnkLetSection.newTree( - nnkIdentDefs.newTree( - newIdentNode("config"), - newEmptyNode(), - config - ) - )) - - for i in config.getType[2].children: - result.add(nnkCall.newTree( - nnkDotExpr.newTree( - newIdentNode("f"), - newIdentNode("writeLine") - ), - newLit(i.repr), - newLit("="), - nnkDotExpr.newTree( - newIdentNode("config"), - newIdentNode(i.repr) - ) - )) - -# proc saveConfig(config: Config, filePath: string) = -# var f = open(filePath, fmWrite) -# defer: f.close -# f.writeLine("scroll_speed=", config.scrollSpeed) -# f.writeLine("drag_velocity_factor=", config.drag_velocity_factor) -# f.writeLine("drag_friction=", config.drag_friction) -# f.writeLine("scale_friction=", config.scale_friction) - -proc loadConfig(filePath: string): Config = - discard +proc loadConfig*(filePath: string): Config = + result = defaultConfig + for line in filePath.lines: + let pair = line.split('=') + let key = pair[0].strip + let value = pair[1].strip + case key + of "scroll_speed": + result.scroll_speed = value.parseFloat + of "drag_velocity_factor": + result.drag_velocity_factor = value.parseFloat + of "drag_friction": + result.drag_friction = value.parseFloat + of "scale_friction": + result.scale_friction = value.parseFloat + of "fps": + result.fps = value.parseInt + else: + raise newException(Exception, "Unknown config key " & key) diff --git a/src/navigation.nim b/src/navigation.nim index ae1f05a..60e284c 100644 --- a/src/navigation.nim +++ b/src/navigation.nim @@ -1,10 +1,6 @@ import vec2 import math - -const SCROLL_SPEED* = 1.0 -const DRAG_VELOCITY_FACTOR*: float = 20.0 -const FRICTION*: float = 2000.0 -const SCALE_FRICTION*: float = 5.0 +import config type Mouse* = object curr*: Vec2 @@ -23,15 +19,15 @@ proc world*(camera: Camera, v: Vec2): Vec2 = proc screen*(camera: Camera, v: Vec2): Vec2 = v * camera.scale + camera.position -proc update*(camera: var Camera, dt: float, mouse: Mouse) = +proc update*(camera: var Camera, config: Config, dt: float, mouse: Mouse) = if abs(camera.delta_scale) > 0.5: let wp0 = camera.world(mouse.curr) camera.scale = max(camera.scale + camera.delta_scale * dt, 1.0) let wp1 = camera.world(mouse.curr) let dwp = wp1 - wp0 camera.position += dwp - camera.delta_scale -= sgn(camera.delta_scale).float * SCALE_FRICTION * dt + camera.delta_scale -= sgn(camera.delta_scale).float * config.scale_friction * dt if not mouse.drag and (camera.velocity.len > 20.0): camera.position += camera.velocity * dt - camera.velocity = camera.velocity - camera.velocity.norm * FRICTION * dt + camera.velocity = camera.velocity - camera.velocity.norm * config.drag_friction * dt From 0619f472dd1fb5dd743e7c507ace3aeede7c400c Mon Sep 17 00:00:00 2001 From: rexim Date: Fri, 11 Oct 2019 20:04:34 +0700 Subject: [PATCH 3/3] (#33) Make the config reloadable --- src/boomer.nim | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/boomer.nim b/src/boomer.nim index d965531..3e9b06b 100644 --- a/src/boomer.nim +++ b/src/boomer.nim @@ -1,6 +1,8 @@ +import os +import math + import x11/xlib, x11/x, x11/xutil import opengl, opengl/glx -import math import vec2 import navigation @@ -48,6 +50,15 @@ const WHEEL_DOWN = 5 proc main() = + var config = defaultConfig + var configFile = "" + + if paramCount() > 0: + configFile = paramStr(1) + config = loadConfig(configFile) + + echo "Using config: ", config + var display = XOpenDisplay(nil) if display == nil: quit "Failed to open display" @@ -147,7 +158,7 @@ proc main() = var quitting = false var camera = Camera(scale: 1.0) var mouse: Mouse - var config = defaultConfig + while not quitting: var xev: TXEvent @@ -177,6 +188,11 @@ proc main() = camera.delta_scale = 0.0 camera.position = (0.0, 0.0) camera.velocity = (0.0, 0.0) + of 24: + quitting = true + of 27: + if configFile.len > 0: + config = loadConfig(configFile) else: discard