changeset 853:f5009fbb2cbc

add: build-time code for resouce importing
author Sam <sam@basx.dev>
date Sat, 09 Dec 2023 01:06:58 +0700
parents 5951a2e31d86
children 48a2ac8bec07 fef5a45056b5
files semicongine/build.nim simporter.nim
diffstat 2 files changed, 66 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/semicongine/build.nim	Wed Dec 06 00:37:34 2023 +0700
+++ b/semicongine/build.nim	Sat Dec 09 01:06:58 2023 +0700
@@ -1,38 +1,33 @@
 import std/strformat
 import std/os
+import std/strutils
 
 import ./core/audiotypes
 
-proc semicongine_outdir*(buildname: string, builddir="./build"): string =
+const BLENDER_CONVERT_SCRIPT = currentSourcePath().parentDir().parentDir().joinPath("scripts/blender_gltf_converter.py")
+
+proc semicongine_builddir*(buildname: string, builddir="./build"): string =
   var platformDir = "unkown"
+
   if defined(linux):
-    switch("define", "VK_USE_PLATFORM_XLIB_KHR")
     platformDir = "linux"
-  if defined(windows):
-    switch("define", "VK_USE_PLATFORM_WIN32_KHR")
+  elif defined(windows):
     platformDir = "windows"
 
   return builddir / buildname / platformDir / projectName()
 
-proc semicongine_build*(buildname: string, bundleType: string, resourceRoot: string, builddir="./build"): string =
+proc semicongine_build_switches*(buildname: string, builddir="./build") =
   switch("experimental", "strictEffects")
   switch("experimental", "strictFuncs")
   switch("define", "nimPreviewHashRef")
-
-  switch("define", &"BUNDLETYPE={bundleType}")
-  switch("define", &"RESOURCEROOT={resourceRoot}")
+  if defined(linux): switch("define", "VK_USE_PLATFORM_XLIB_KHR")
+  if defined(windows): switch("define", "VK_USE_PLATFORM_WIN32_KHR")
+  switch("outdir", semicongine_builddir(buildname, builddir=builddir))
 
-  var platformDir = "unkown"
-  if defined(linux):
-    switch("define", "VK_USE_PLATFORM_XLIB_KHR")
-    platformDir = "linux"
-  if defined(windows):
-    switch("define", "VK_USE_PLATFORM_WIN32_KHR")
-    platformDir = "windows"
+proc semicongine_pack*(outdir: string, bundleType: string, resourceRoot: string) =
+  switch("define", "BUNDLETYPE=" & bundleType)
+  switch("define", "RESOURCEROOT=" & resourceRoot)
 
-  var outdir = builddir / buildname / platformDir / projectName()
-  switch("outdir", outdir)
-  setCommand "c"
   rmDir(outdir)
   mkDir(outdir)
   let resourcedir = joinPath(projectDir(), resourceRoot)
@@ -49,7 +44,6 @@
             exec &"zip -r {outputfile} ."
           elif defined(windows):
             exec &"powershell Compress-Archive * {outputfile}"
-  return outdir
 
 proc semicongine_zip*(dir: string) =
   withdir dir.parentDir:
@@ -58,3 +52,56 @@
     elif defined(windows):
       exec &"powershell Compress-Archive * {dir.lastPathPart}"
 
+
+# need this because fileNewer from std/os does not work in Nim VM
+proc fileNewerStatic(file1, file2: string): bool =
+  assert file1.fileExists
+  assert file2.fileExists
+  when defined(linux):
+    let command = "/usr/bin/test " & file1 & " -nt " & file2
+    let ex = gorgeEx(command)
+    return ex.exitCode == 0
+  elif defined(window):
+    {.error "Resource imports not supported on windows for now".}
+
+proc import_meshes*(files: seq[(string, string)]) =
+  if files.len == 0:
+    return
+
+  var args = @["--background", "--python", BLENDER_CONVERT_SCRIPT, "--"]
+  for (input, output) in files:
+    args.add input
+    args.add output
+
+  exec("blender " & args.join(" "))
+
+proc import_audio*(files: seq[(string, string)]) =
+  for (input, output) in files:
+    let command = "ffmpeg " & ["-y", "-i", input, "-ar", $AUDIO_SAMPLE_RATE, output].join(" ")
+    exec(command)
+
+proc semicongine_import_resource_file*(resourceMap: openArray[(string, string)]) =
+  when not defined(linux):
+    {.warning: "Resource files can only be imported on linux, please make sure that the required files are created by runing the build on a linux machine.".}
+    return
+  var meshfiles: seq[(string, string)]
+  var audiofiles: seq[(string, string)]
+
+  for (target_rel, source_rel) in resourceMap:
+    let target = joinPath(thisDir(), target_rel)
+    let source = joinPath(thisDir(), source_rel)
+    if not source.fileExists:
+      raise newException(IOError, &"Not found: {source}")
+    if not target.fileExists or source.fileNewerStatic(target):
+      echo &"{target} is outdated"
+      if source.endsWith("blend"):
+        meshfiles.add (source, target)
+      elif source.endsWith("mp3") or source.endsWith("ogg") or source.endsWith("wav"):
+        audiofiles.add (source, target)
+      else:
+        raise newException(Exception, &"unkown file type: {source}")
+      target.parentDir().mkDir()
+    else:
+      echo &"{target} is up-to-date"
+  import_meshes meshfiles
+  import_audio audiofiles
--- a/simporter.nim	Wed Dec 06 00:37:34 2023 +0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-import std/os
-import std/paths
-import std/dirs
-import std/osproc
-import std/cmdline
-import std/strutils
-import std/strformat
-
-import ./semicongine/core/audiotypes
-
-proc import_meshes*(files: seq[(string, string)]) =
-  let converter_script = currentSourcePath.parentDir().joinPath("scripts/blender_gltf_converter.py")
-
-  var args = @["--background", "--python", converter_script, "--"]
-  for (input, output) in files:
-    args.add input
-    args.add output
-
-  let p = startProcess("blender", args=args, options={poStdErrToStdOut, poUsePath})
-  let exitCode = p.waitForExit()
-  p.close()
-  if exitCode != 0:
-    raise newException(OSError, &"blender had exit code {exitCode}")
-
-proc import_audio*(files: seq[(string, string)]) =
-  for (input, output) in files:
-    let p = startProcess("ffmpeg", args=["-y", "-i", input, "-ar", $AUDIO_SAMPLE_RATE, output], options={poStdErrToStdOut, poUsePath})
-    let exitCode = p.waitForExit()
-    p.close()
-    if exitCode != 0:
-      raise newException(OSError, &"ffmpeg had exit code {exitCode}")
-
-when isMainModule:
-  var meshfiles: seq[(string, string)]
-  var audiofiles: seq[(string, string)]
-
-  for arg in commandLineParams():
-    if arg.count(':') != 1:
-      raise newException(Exception, &"Argument {arg} requires exactly one colon to separate input from output, but it contains {arg.count(':')} colons.")
-    let
-      input_output = arg.split(':', 1)
-      input = input_output[0]
-      output = input_output[1]
-    if not input.fileExists:
-      raise newException(IOError, &"Not found: {input}")
-    if not output.fileExists or input.fileNewer(output):
-      echo &"{output} is outdated"
-      if input.endsWith("blend"):
-        meshfiles.add (input, output)
-      elif input.endsWith("mp3") or input.endsWith("ogg") or input.endsWith("wav"):
-        audiofiles.add (input, output)
-      else:
-        raise newException(Exception, &"unkown file type: {input}")
-      Path(output.parentDir()).createDir()
-    else:
-      echo &"{output} is up-to-date"
-
-  import_meshes meshfiles
-  import_audio audiofiles