aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-05-22 13:39:58 +0000
committers-ol <s+removethis@s-ol.nu>2026-05-22 13:42:01 +0000
commit8aa1a6c2af0b3a5fbd0d892beb27f055f95b94ce (patch)
tree3a3601728e6ee2fa5cd1e5a05bf24a926c1420ce
parentlib/struct: add getdef (diff)
downloadalive-wgsl-view.tar.gz
alive-wgsl-view.zip
wgsl-view: launch via luaposixwgsl-view
-rw-r--r--alv-lib/wgsl-view.moon86
-rw-r--r--docs/gen/shim.moon2
2 files changed, 79 insertions, 9 deletions
diff --git a/alv-lib/wgsl-view.moon b/alv-lib/wgsl-view.moon
index 02d27b4..43acc07 100644
--- a/alv-lib/wgsl-view.moon
+++ b/alv-lib/wgsl-view.moon
@@ -1,6 +1,8 @@
import RTNode, Error, Constant, PureOp, Op, template_subst, Input, T, Primitive, Array, Struct, sig, evt, const, any from require 'alv.base'
import Message, Bundle, Timetag from require 'alv-lib._osc'
+unpack or= table.unpack
+
SCALAR_TYPES = num: 'f32', bool: 'u32'
get_typestr = (type) ->
typestr = tostring type
@@ -150,6 +152,28 @@ sampler = Constant.meta
with @inputs.socket!
\send Message.pack { address: "#{@state}/destroy", types: "" }
+class Subprocess
+ posix = require 'posix'
+ new: (...) =>
+ @pid = assert posix.fork!
+ if @pid == 0
+ -- child
+ posix.chdir COPILOT.active_module.file\match'(.*/)[^/]*$'
+ posix.execp ...
+ posix._exit 127
+
+ is_running: =>
+ rpid = posix.waitpid @pid, posix.WNOHANG
+ rpid == 0
+
+ kill: =>
+ if @pid
+ posix.kill @pid, posix.SIGTERM
+ posix.waitpid @pid, 0
+ @pid = nil
+
+ __gc: => @kill!
+
video_stream = Constant.meta
meta:
name: 'video-stream'
@@ -167,16 +191,62 @@ video_stream = Constant.meta
socket: Input.hot socket or scope\get '*oscout*'
rest: [Input.hot p for p in *rest]
- bin_prefix = (scope\get '*wgsl-view-bin*', default_prefix).result!
+ tsvname = "alv-#{fmttag @tag}"
+
+ @state or= {
+ :tsvname,
+ id: "/texture/#{tsvname}",
+ proc: Subprocess "tsv-video-stream", { "--name", tsvname, "--", unpack @unwrap_all!.rest }
+ }
+ @setup_out '=', T["wgsl/texture_2d<f32>"], @state.id
+
+ tick: =>
+ with @inputs.socket!
+ \send Message.pack { address: @state.id, types: "s", @state.tsvname }
+
+ destroy: =>
+ return unless @state
+ with @inputs.socket!
+ \send Message.pack { address: "#{@state.id}/destroy", types: "" }
+ @state.proc\kill!
+
+video_buffer = Constant.meta
+ meta:
+ name: 'video-buffer'
+ summary: "create a video buffer"
+ examples: { '(video-buffer [socket] [depth] args…)' }
+ description: 'Creates a video buffer from ffmpeg args.'
+
+ value: class extends Op
+ pattern = -sig['osc/out'] + -const.num + const.str!^0
+ default_prefix = RTNode result: Constant.str ""
+ setup: (inputs, scope) =>
+ { socket, depth, rest } = pattern\match inputs
+
+ super
+ socket: Input.hot socket or scope\get '*oscout*'
+ depth: depth and Input.hot depth
+ rest: [Input.hot p for p in *rest]
tsvname = "alv-#{fmttag @tag}"
- id = "/texture/#{tsvname}"
- args = table.concat @unwrap_all!.rest, ' '
+
+ opts = @unwrap_all!
+ args = { "--name", tsvname }
+
+ if opts.depth
+ table.insert args, "--frames"
+ table.insert args, opts.depth
+
+ table.insert args, "--"
+ for p in *opts.rest
+ table.insert args, p
+
@state or= {
- :tsvname, :id
- pipe: io.popen bin_prefix .. "tsv-video-stream --name #{tsvname} -- #{args}",
+ :tsvname,
+ id: "/texture/#{tsvname}",
+ proc: Subprocess "tsv-video-buffer", args
}
- @setup_out '=', T["wgsl/texture_2d<f32>"], id
+ @setup_out '=', T["wgsl/texture_3d<f32>"], @state.id
tick: =>
with @inputs.socket!
@@ -186,6 +256,7 @@ video_stream = Constant.meta
return unless @state
with @inputs.socket!
\send Message.pack { address: "#{@state.id}/destroy", types: "" }
+ @state.proc\kill!
tsv_tex = Constant.meta
meta:
@@ -315,13 +386,12 @@ Constant.meta
summary: "wgsl-view integration via OSC."
value:
- '*wgsl-view-bin*': Constant.str ''
-
:cast
:sampler
'tsv-tex': tsv_tex
'video-stream': video_stream
+ 'video-buffer': video_buffer
shader: shader_
:draw
diff --git a/docs/gen/shim.moon b/docs/gen/shim.moon
index 6d8fbe9..d91e198 100644
--- a/docs/gen/shim.moon
+++ b/docs/gen/shim.moon
@@ -4,7 +4,7 @@ export require
require = do
old_require = require
- blacklist = {'^losc', '^socket$', '^system$', '^luartmidi$', '^abletonlink$'}
+ blacklist = {'^losc', '^socket$', '^system$', '^luartmidi$', '^abletonlink$', '^posix$'}
(mod, ...) ->
for pat in *blacklist
return {} if mod\match pat