aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-04-19 15:02:54 +0000
committers-ol <s-ol@users.noreply.github.com>2020-04-19 15:02:54 +0000
commit8b9d1ac65083c201d4ce86d1c6950ea02d7b95f3 (patch)
treed550ea40181899ea3aa601728f7afdd04ea4cb7b
parentalso pack source rocks (diff)
downloadalive-8b9d1ac65083c201d4ce86d1c6950ea02d7b95f3.tar.gz
alive-8b9d1ac65083c201d4ce86d1c6950ea02d7b95f3.zip
add wxLua alv-wx
-rw-r--r--alv/copilot.moon20
-rw-r--r--alv/init.moon4
-rwxr-xr-xbin/alv-copilot20
-rwxr-xr-xbin/alv-wx140
-rwxr-xr-xdist/release.sh2
-rw-r--r--dist/rocks/alive-scm-2.rockspec81
6 files changed, 239 insertions, 28 deletions
diff --git a/alv/copilot.moon b/alv/copilot.moon
index a1dc811..3d1523e 100644
--- a/alv/copilot.moon
+++ b/alv/copilot.moon
@@ -26,20 +26,26 @@ class Copilot
--- create a new Copilot.
-- @classmethod
-- @tparam string file name/path of the alive file to watch and execute
- new: (@file) =>
+ new: (file) =>
@registry = Registry!
+ @eval_stream, @run_stream = io.stderr, io.stdout
+ @open file if file
- @last_modification = 0
-
- mode = lfs.attributes @file, 'mode'
+ open: (file) =>
+ mode = lfs.attributes file, 'mode'
if mode != 'file'
- error "not a file: #{@file}"
+ error "not a file: #{file}"
+
+ @last_modification = 0
+ @file = file
--- members
-- @section members
--- poll for changes and tick.
tick: =>
+ return unless @file
+
@poll!
if @root
@@ -76,10 +82,10 @@ class Copilot
return
if @last_modification < modification
- L.stream = io.stderr
+ L.stream = @eval_stream
L\log "#{@file} changed at #{modification}"
@eval!
- L.stream = io.stdout
+ L.stream = @run_stream
@last_modification = os.time!
{
diff --git a/alv/init.moon b/alv/init.moon
index d86cd1f..8b7a01b 100644
--- a/alv/init.moon
+++ b/alv/init.moon
@@ -9,6 +9,7 @@ if _VERSION == 'Lua 5.1'
error msg
a, msg, ...
+version = require 'alv.version'
import Logger from require 'alv.logger'
import ValueStream, EventStream, IOStream from require 'alv.stream'
import Result from require 'alv.result'
@@ -28,6 +29,7 @@ globals = Scope.from_table require 'alv.builtin'
--- exports
-- @table exports
+-- @tfield version version
-- @tfield ValueStream ValueStream
-- @tfield EventStream EventStream
-- @tfield IOStream IOStream
@@ -43,6 +45,8 @@ globals = Scope.from_table require 'alv.builtin'
-- @tfield Scope globals global definitons
-- @tfield parse function to turn a `string` into a root `Cell`
{
+ :version
+
:ValueStream, :EventStream, :IOStream
:Cell, :RootCell
:Result, :Scope, :Error
diff --git a/bin/alv-copilot b/bin/alv-copilot
deleted file mode 100755
index 9f2f113..0000000
--- a/bin/alv-copilot
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-set -e
-
-tmpdir=$(mktemp -d)
-trap 'rm -rf "$tmpdir"' EXIT INT TERM HUP
-
-ARGS=$*
-FIFO=$tmpdir/fifo
-CONF=$tmpdir/conf
-
-cat > "$CONF" << 'EOF'
-split
-screen -t evaltime sh -c 'tty > "$FIFO"; read done < "$FIFO"; screen -X quit'
-focus
-screen -t runtime sh -c 'read tty < "$FIFO"; "alv" $ARGS 2> "$tty"; echo "[press enter to exit]"; read prompt; screen -X quit'
-EOF
-
-mkfifo "$FIFO"
-export FIFO ARGS
-exec screen -mc "$CONF"
diff --git a/bin/alv-wx b/bin/alv-wx
new file mode 100755
index 0000000..85d1875
--- /dev/null
+++ b/bin/alv-wx
@@ -0,0 +1,140 @@
+#!/usr/bin/env moon
+import Copilot, Logger, version from require 'alv'
+import sleep from require 'system'
+
+require 'wx'
+import
+ wxID_ABOUT, wxID_OPEN, wxID_EXIT, wxID_ANY, wxVERTICAL,
+ wxFrame, wxMenuBar, wxMenu, wxPanel, wxBoxSizer, wxTextCtrl, wxSplitterWindow
+from wx
+
+STARTSTOP = 100
+
+class GUIStream
+ new: (@ctrl) =>
+
+ write: (...) =>
+ message = table.concat {...}, ''
+ @ctrl\AppendText message
+
+ flush: =>
+
+class GUICopilot extends Copilot
+ new: (...) =>
+ super ...
+
+ @app = wx.wxGetApp!
+ @app.VendorName = 'alive'
+ @app.AppName = 'alive wxCopilot'
+
+ fileMenu = wxMenu {
+ { wxID_ABOUT, '&About', 'About alive wxCopilot' }
+ { wxID_OPEN, '&Open\tCtrl-O', 'Open Script' }
+ { }
+ { wxID_EXIT, 'E&xit\tCtrl-Q', 'Exit Program' }
+ }
+ runMenu = wxMenu {
+ { STARTSTOP, '&Start/Stop\tCtrl-P', 'Start/Stop Script Execution' }
+ }
+ @menuBar = with wxMenuBar!
+ \Append fileMenu, '&File'
+ \Append runMenu, '&Run'
+
+ @frame = wxFrame wx.NULL, wxID_ANY, @app\GetAppName!
+ @frame\SetMenuBar @menuBar
+ @status = @frame\CreateStatusBar 1
+
+ @update_status!
+
+ splitter = wxSplitterWindow @frame, wx.wxID_ANY
+
+ eval, ctrl = @mkPanel splitter, 'eval-time messages'
+ @eval_stream = GUIStream ctrl
+
+ run, ctrl = @mkPanel splitter, 'run-time messages'
+ @run_stream = GUIStream ctrl
+
+ splitter\SetMinimumPaneSize 60
+ splitter\SplitHorizontally eval, run, 0
+
+ sizer = with wxBoxSizer wx.wxVERTICAL
+ \Add splitter, 1, wx.wxEXPAND + wx.wxALL, 10
+
+ @frame\SetAutoLayout true
+ @frame\SetSizer sizer
+ @frame\Show true
+
+ @frame\Connect wxID_ABOUT, wx.wxEVT_COMMAND_MENU_SELECTED, @\do_about
+ @frame\Connect wxID_OPEN, wx.wxEVT_COMMAND_MENU_SELECTED, @\do_open
+ @frame\Connect wxID_EXIT, wx.wxEVT_COMMAND_MENU_SELECTED, -> @frame\Close!
+ @frame\Connect STARTSTOP, wx.wxEVT_COMMAND_MENU_SELECTED, @\do_startstop
+ @frame\Connect wxID_ANY, wx.wxEVT_IDLE, @\do_idle
+
+ do_about: =>
+ wx.wxMessageBox "alive #{version.tag} wxCopilot.
+
+built using #{wxlua.wxLUA_VERSION_STRING} on #{wx.wxVERSION_STRING}",
+ "About wxCopilot",
+ wx.wxOK + wx.wxICON_INFORMATION,
+ @frame
+
+ do_open: =>
+ dialog = wx.wxFileDialog @frame, 'Change Script', '', '',
+ 'Alive scripts (*.alv)|*.alv|All files (*)|*',
+ wx.wxFD_OPEN + wx.wxFD_FILE_MUST_EXIST
+
+ if dialog\ShowModal! == wx.wxID_OK
+ @paused = false
+ @open dialog\GetPath!
+ @update_status!
+
+ dialog\Destroy!
+
+ do_startstop: (event) =>
+ if @file
+ @paused = not @paused
+ @update_status!
+
+ do_idle: (event) =>
+ if @file and not @paused
+ event\RequestMore true
+ @tick!
+
+ update_status: =>
+ startstop = @menuBar\FindItem STARTSTOP
+ if not @file
+ @status\SetStatusText "No script loaded."
+ startstop\Enable false
+ else
+ startstop\Enable true
+ if @paused
+ @status\SetStatusText "Paused."
+ else
+ @status\SetStatusText "Running."
+
+ mkPanel: (parent, name) =>
+ panel = wxPanel parent, wxID_ANY
+ sizer = wxBoxSizer wxVERTICAL
+ panel\SetSizer sizer
+
+ sizer\Add wx.wxStaticText panel, wx.wxID_ANY, name
+ log = wxTextCtrl panel, wxID_ANY, '', wx.wxDefaultPosition,
+ wx.wxDefaultSize, wx.wxTE_MULTILINE + wx.wxTE_READONLY
+ sizer\Add log, 1, wx.wxEXPAND | wx.wxBOTTOM, 5
+
+ panel, log
+
+arguments, key = {}
+for a in *arg
+ if match = a\match '^%-%-(.*)'
+ key = match
+ arguments[key] = true
+ elseif key
+ arguments[key] = a
+ key = nil
+ else
+ table.insert arguments, a
+
+copilot = GUICopilot arguments[1]
+Logger.init arguments.log, copilot.eval_stream
+copilot.app\MainLoop!
diff --git a/dist/release.sh b/dist/release.sh
index c901372..da6dcb9 100755
--- a/dist/release.sh
+++ b/dist/release.sh
@@ -90,7 +90,7 @@ $(list_modules alv-lib)
},
bin = {
"bin/alv",
- "bin/alv-copilot"
+ "bin/alv-wx"
},
},
}
diff --git a/dist/rocks/alive-scm-2.rockspec b/dist/rocks/alive-scm-2.rockspec
new file mode 100644
index 0000000..fe1c353
--- /dev/null
+++ b/dist/rocks/alive-scm-2.rockspec
@@ -0,0 +1,81 @@
+package = "alive"
+version = "scm-2"
+
+source = {
+ url = "git://github.com/s-ol/alive.git",
+}
+
+description = {
+ summary = "Experimental livecoding environment with persistent expressions",
+ detailed = [[
+This is an experimental livecoding language and environment, in which
+expressions persist and update until they are removed from the source code, and
+the interpreter keeps no state that you cannot manipulate directly in the
+source. This yields a direct-manipulation like experience with a purely
+text-based language and works without special editor support.]],
+ homepage = "https://alive.s-ol.nu",
+ license = "GPL-3",
+}
+
+dependencies = {
+ "lua >= 5.3",
+ "moonscript >= 0.5.0",
+ "lpeg ~> 0.10",
+ "luafilesystem",
+ "luasystem",
+ "luasocket",
+ "osc",
+}
+
+build = {
+ type = "builtin",
+ modules = {},
+ copy_directories = { "docs" },
+ install = {
+ lua = {
+ ["alv.ast"] = "alv/ast.moon",
+ ["alv.base.builtin"] = "alv/base/builtin.moon",
+ ["alv.base.fndef"] = "alv/base/fndef.moon",
+ ["alv.base.init"] = "alv/base/init.moon",
+ ["alv.base.input"] = "alv/base/input.moon",
+ ["alv.base.match"] = "alv/base/match.moon",
+ ["alv.base.op"] = "alv/base/op.moon",
+ ["alv.builtin"] = "alv/builtin.moon",
+ ["alv.cell"] = "alv/cell.moon",
+ ["alv.copilot"] = "alv/copilot.moon",
+ ["alv.cycle"] = "alv/cycle.moon",
+ ["alv.error"] = "alv/error.moon",
+ ["alv.init"] = "alv/init.moon",
+ ["alv.invoke"] = "alv/invoke.moon",
+ ["alv.logger"] = "alv/logger.moon",
+ ["alv.parsing"] = "alv/parsing.moon",
+ ["alv.registry"] = "alv/registry.moon",
+ ["alv.result"] = "alv/result.moon",
+ ["alv.scope"] = "alv/scope.moon",
+ ["alv.stream.base"] = "alv/stream/base.moon",
+ ["alv.stream.event"] = "alv/stream/event.moon",
+ ["alv.stream.init"] = "alv/stream/init.moon",
+ ["alv.stream.io"] = "alv/stream/io.moon",
+ ["alv.stream.value"] = "alv/stream/value.moon",
+ ["alv.tag"] = "alv/tag.moon",
+ ["alv.version"] = "alv/version.moon",
+
+ ["alv-lib.logic"] = "alv-lib/logic.moon",
+ ["alv-lib.math"] = "alv-lib/math.moon",
+ ["alv-lib.midi"] = "alv-lib/midi.moon",
+ ["alv-lib.midi.core"] = "alv-lib/midi/core.moon",
+ ["alv-lib.midi.launchctl"] = "alv-lib/midi/launchctl.moon",
+ ["alv-lib.osc"] = "alv-lib/osc.moon",
+ ["alv-lib.pilot"] = "alv-lib/pilot.moon",
+ ["alv-lib.random"] = "alv-lib/random.moon",
+ ["alv-lib.sc"] = "alv-lib/sc.moon",
+ ["alv-lib.string"] = "alv-lib/string.moon",
+ ["alv-lib.time"] = "alv-lib/time.moon",
+ ["alv-lib.util"] = "alv-lib/util.moon",
+ },
+ bin = {
+ "bin/alv",
+ "bin/alv-wx"
+ },
+ },
+}