@devaloop/devalang 0.0.1-beta.2 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -146
- package/out-tsc/api.d.ts +180 -0
- package/out-tsc/api.d.ts.map +1 -0
- package/out-tsc/api.js +286 -0
- package/out-tsc/api.js.map +1 -0
- package/out-tsc/bin/index.d.ts +12 -0
- package/out-tsc/bin/index.d.ts.map +1 -0
- package/out-tsc/bin/index.js +20 -54
- package/out-tsc/bin/index.js.map +1 -0
- package/out-tsc/examples/basic-usage.d.ts +8 -0
- package/out-tsc/examples/basic-usage.d.ts.map +1 -0
- package/out-tsc/examples/basic-usage.js +113 -0
- package/out-tsc/examples/basic-usage.js.map +1 -0
- package/out-tsc/index.d.ts +19 -5
- package/out-tsc/index.d.ts.map +1 -0
- package/out-tsc/index.js +24 -6
- package/out-tsc/index.js.map +1 -0
- package/out-tsc/scripts/copy-wasm-dts.d.ts +7 -0
- package/out-tsc/scripts/copy-wasm-dts.d.ts.map +1 -0
- package/out-tsc/scripts/copy-wasm-dts.js +36 -32
- package/out-tsc/scripts/copy-wasm-dts.js.map +1 -0
- package/out-tsc/scripts/postinstall.d.ts +1 -0
- package/out-tsc/scripts/postinstall.d.ts.map +1 -0
- package/out-tsc/scripts/postinstall.js +4 -1
- package/out-tsc/scripts/postinstall.js.map +1 -0
- package/out-tsc/scripts/version/bump.d.ts +5 -1
- package/out-tsc/scripts/version/bump.d.ts.map +1 -0
- package/out-tsc/scripts/version/bump.js +114 -44
- package/out-tsc/scripts/version/bump.js.map +1 -0
- package/out-tsc/scripts/version/fetch.d.ts +12 -1
- package/out-tsc/scripts/version/fetch.d.ts.map +1 -0
- package/out-tsc/scripts/version/fetch.js +68 -24
- package/out-tsc/scripts/version/fetch.js.map +1 -0
- package/out-tsc/scripts/version/index.d.ts +6 -0
- package/out-tsc/scripts/version/index.d.ts.map +1 -0
- package/out-tsc/scripts/version/index.js +44 -22
- package/out-tsc/scripts/version/index.js.map +1 -0
- package/out-tsc/scripts/version/sync.d.ts +5 -1
- package/out-tsc/scripts/version/sync.d.ts.map +1 -0
- package/out-tsc/scripts/version/sync.js +78 -29
- package/out-tsc/scripts/version/sync.js.map +1 -0
- package/out-tsc/types.d.ts +68 -0
- package/out-tsc/types.d.ts.map +1 -0
- package/out-tsc/{core/types/value.js → types.js} +4 -0
- package/out-tsc/types.js.map +1 -0
- package/out-tsc/wasm.d.ts +8 -0
- package/out-tsc/wasm.d.ts.map +1 -0
- package/out-tsc/{core/index.js → wasm.js} +9 -6
- package/out-tsc/wasm.js.map +1 -0
- package/package.json +50 -37
- package/.cargo/config.toml +0 -2
- package/.devalang +0 -9
- package/.github/workflows/ci.yml +0 -103
- package/Cargo.toml +0 -81
- package/docs/CHANGELOG.md +0 -581
- package/docs/CONTRIBUTING.md +0 -101
- package/docs/ROADMAP.md +0 -38
- package/docs/TODO.md +0 -71
- package/examples/automation.deva +0 -42
- package/examples/bank.deva +0 -7
- package/examples/bus.deva +0 -10
- package/examples/condition.deva +0 -20
- package/examples/duration.deva +0 -9
- package/examples/effect.deva +0 -2
- package/examples/events.deva +0 -12
- package/examples/filter.deva +0 -11
- package/examples/function.deva +0 -15
- package/examples/group.deva +0 -12
- package/examples/index.deva +0 -63
- package/examples/lfo.deva +0 -9
- package/examples/loop.deva +0 -10
- package/examples/pattern.deva +0 -8
- package/examples/plugin.deva +0 -16
- package/examples/samples/hat-808.wav +0 -0
- package/examples/samples/kick-808.wav +0 -0
- package/examples/synth.deva +0 -24
- package/examples/synth_types.deva +0 -17
- package/examples/variables.deva +0 -9
- package/out-tsc/core/functions/index.d.ts +0 -42
- package/out-tsc/core/functions/index.js +0 -87
- package/out-tsc/core/index.d.ts +0 -6
- package/out-tsc/core/types/index.d.ts +0 -4
- package/out-tsc/core/types/index.js +0 -20
- package/out-tsc/core/types/plugin.d.ts +0 -18
- package/out-tsc/core/types/plugin.js +0 -2
- package/out-tsc/core/types/result.d.ts +0 -27
- package/out-tsc/core/types/result.js +0 -2
- package/out-tsc/core/types/statement.d.ts +0 -106
- package/out-tsc/core/types/statement.js +0 -2
- package/out-tsc/core/types/value.d.ts +0 -43
- package/out-tsc/pkg/devalang_core.d.ts +0 -15
- package/out-tsc/pkg/devalang_core.js +0 -65
- package/out-tsc/pkg/devalang_core_bg.wasm.d.ts +0 -34
- package/project-version.json +0 -6
- package/rust/cli/bank/api.rs +0 -122
- package/rust/cli/bank/commands.rs +0 -306
- package/rust/cli/bank/mod.rs +0 -29
- package/rust/cli/build/commands.rs +0 -153
- package/rust/cli/build/mod.rs +0 -2
- package/rust/cli/build/process.rs +0 -165
- package/rust/cli/check/mod.rs +0 -208
- package/rust/cli/discover/commands.rs +0 -253
- package/rust/cli/discover/config.rs +0 -111
- package/rust/cli/discover/fs.rs +0 -19
- package/rust/cli/discover/install.rs +0 -103
- package/rust/cli/discover/metadata.rs +0 -48
- package/rust/cli/discover/mod.rs +0 -5
- package/rust/cli/init/commands.rs +0 -88
- package/rust/cli/init/mod.rs +0 -1
- package/rust/cli/install/addon.rs +0 -118
- package/rust/cli/install/bank.rs +0 -72
- package/rust/cli/install/commands.rs +0 -35
- package/rust/cli/install/mod.rs +0 -4
- package/rust/cli/install/plugin.rs +0 -80
- package/rust/cli/login/commands.rs +0 -124
- package/rust/cli/login/mod.rs +0 -1
- package/rust/cli/mod.rs +0 -12
- package/rust/cli/parser.rs +0 -359
- package/rust/cli/play/commands.rs +0 -375
- package/rust/cli/play/io.rs +0 -17
- package/rust/cli/play/mod.rs +0 -5
- package/rust/cli/play/process.rs +0 -159
- package/rust/cli/play/realtime.rs +0 -91
- package/rust/cli/play/utils.rs +0 -23
- package/rust/cli/telemetry/commands.rs +0 -22
- package/rust/cli/telemetry/event_creator.rs +0 -80
- package/rust/cli/telemetry/mod.rs +0 -3
- package/rust/cli/telemetry/send.rs +0 -51
- package/rust/cli/template/commands.rs +0 -69
- package/rust/cli/template/mod.rs +0 -1
- package/rust/cli/update/commands.rs +0 -6
- package/rust/cli/update/mod.rs +0 -1
- package/rust/config/driver.rs +0 -112
- package/rust/config/mod.rs +0 -3
- package/rust/config/ops.rs +0 -26
- package/rust/config/settings.rs +0 -101
- package/rust/core/audio/engine/driver.rs +0 -220
- package/rust/core/audio/engine/export.rs +0 -169
- package/rust/core/audio/engine/helpers.rs +0 -178
- package/rust/core/audio/engine/mod.rs +0 -56
- package/rust/core/audio/engine/notes/dsp.rs +0 -85
- package/rust/core/audio/engine/notes/mod.rs +0 -44
- package/rust/core/audio/engine/notes/params.rs +0 -294
- package/rust/core/audio/engine/sample/insert.rs +0 -199
- package/rust/core/audio/engine/sample/mod.rs +0 -40
- package/rust/core/audio/engine/sample/padding.rs +0 -170
- package/rust/core/audio/evaluator/condition.rs +0 -61
- package/rust/core/audio/evaluator/mod.rs +0 -9
- package/rust/core/audio/evaluator/numeric.rs +0 -152
- package/rust/core/audio/evaluator/rhs.rs +0 -16
- package/rust/core/audio/evaluator/string_expr.rs +0 -94
- package/rust/core/audio/interpreter/driver.rs +0 -574
- package/rust/core/audio/interpreter/mod.rs +0 -2
- package/rust/core/audio/interpreter/statements/arrow_call/interprete.rs +0 -175
- package/rust/core/audio/interpreter/statements/arrow_call/methods/chord.rs +0 -384
- package/rust/core/audio/interpreter/statements/arrow_call/methods/mod.rs +0 -2
- package/rust/core/audio/interpreter/statements/arrow_call/methods/note.rs +0 -316
- package/rust/core/audio/interpreter/statements/arrow_call/mod.rs +0 -3
- package/rust/core/audio/interpreter/statements/arrow_call/types/arp.rs +0 -192
- package/rust/core/audio/interpreter/statements/arrow_call/types/mod.rs +0 -24
- package/rust/core/audio/interpreter/statements/arrow_call/types/pad.rs +0 -116
- package/rust/core/audio/interpreter/statements/arrow_call/types/pluck.rs +0 -97
- package/rust/core/audio/interpreter/statements/arrow_call/types/sub.rs +0 -100
- package/rust/core/audio/interpreter/statements/automate.rs +0 -16
- package/rust/core/audio/interpreter/statements/call.rs +0 -295
- package/rust/core/audio/interpreter/statements/condition.rs +0 -72
- package/rust/core/audio/interpreter/statements/function.rs +0 -24
- package/rust/core/audio/interpreter/statements/let_.rs +0 -36
- package/rust/core/audio/interpreter/statements/load.rs +0 -17
- package/rust/core/audio/interpreter/statements/loop_.rs +0 -115
- package/rust/core/audio/interpreter/statements/mod.rs +0 -12
- package/rust/core/audio/interpreter/statements/sleep.rs +0 -28
- package/rust/core/audio/interpreter/statements/spawn.rs +0 -253
- package/rust/core/audio/interpreter/statements/tempo.rs +0 -40
- package/rust/core/audio/interpreter/statements/trigger.rs +0 -239
- package/rust/core/audio/loader/mod.rs +0 -1
- package/rust/core/audio/loader/trigger.rs +0 -98
- package/rust/core/audio/mod.rs +0 -6
- package/rust/core/audio/player.rs +0 -70
- package/rust/core/audio/special/easing.rs +0 -189
- package/rust/core/audio/special/env.rs +0 -45
- package/rust/core/audio/special/math.rs +0 -134
- package/rust/core/audio/special/mod.rs +0 -9
- package/rust/core/audio/special/modulator.rs +0 -143
- package/rust/core/builder/mod.rs +0 -129
- package/rust/core/debugger/lexer.rs +0 -27
- package/rust/core/debugger/logs.rs +0 -52
- package/rust/core/debugger/mod.rs +0 -30
- package/rust/core/debugger/preprocessor.rs +0 -27
- package/rust/core/debugger/store.rs +0 -38
- package/rust/core/error/mod.rs +0 -269
- package/rust/core/lexer/driver.rs +0 -59
- package/rust/core/lexer/handler/arrow.rs +0 -82
- package/rust/core/lexer/handler/at.rs +0 -21
- package/rust/core/lexer/handler/brace.rs +0 -41
- package/rust/core/lexer/handler/colon.rs +0 -21
- package/rust/core/lexer/handler/comment.rs +0 -30
- package/rust/core/lexer/handler/dot.rs +0 -21
- package/rust/core/lexer/handler/driver.rs +0 -337
- package/rust/core/lexer/handler/identifier.rs +0 -47
- package/rust/core/lexer/handler/indent.rs +0 -66
- package/rust/core/lexer/handler/mod.rs +0 -15
- package/rust/core/lexer/handler/newline.rs +0 -23
- package/rust/core/lexer/handler/number.rs +0 -31
- package/rust/core/lexer/handler/operator.rs +0 -46
- package/rust/core/lexer/handler/parenthesis.rs +0 -41
- package/rust/core/lexer/handler/slash.rs +0 -21
- package/rust/core/lexer/handler/string.rs +0 -63
- package/rust/core/lexer/mod.rs +0 -3
- package/rust/core/lexer/token.rs +0 -91
- package/rust/core/mod.rs +0 -9
- package/rust/core/parser/driver/block.rs +0 -111
- package/rust/core/parser/driver/cursor.rs +0 -82
- package/rust/core/parser/driver/driver_impl.rs +0 -139
- package/rust/core/parser/driver/mod.rs +0 -6
- package/rust/core/parser/driver/parse_array.rs +0 -120
- package/rust/core/parser/driver/parse_map.rs +0 -223
- package/rust/core/parser/driver/parser.rs +0 -160
- package/rust/core/parser/handler/arrow_call.rs +0 -277
- package/rust/core/parser/handler/at.rs +0 -279
- package/rust/core/parser/handler/bank.rs +0 -104
- package/rust/core/parser/handler/condition.rs +0 -83
- package/rust/core/parser/handler/dot.rs +0 -148
- package/rust/core/parser/handler/identifier/automate.rs +0 -254
- package/rust/core/parser/handler/identifier/call.rs +0 -91
- package/rust/core/parser/handler/identifier/emit.rs +0 -70
- package/rust/core/parser/handler/identifier/function.rs +0 -113
- package/rust/core/parser/handler/identifier/group.rs +0 -89
- package/rust/core/parser/handler/identifier/let_.rs +0 -173
- package/rust/core/parser/handler/identifier/mod.rs +0 -55
- package/rust/core/parser/handler/identifier/on.rs +0 -107
- package/rust/core/parser/handler/identifier/print.rs +0 -49
- package/rust/core/parser/handler/identifier/sleep.rs +0 -96
- package/rust/core/parser/handler/identifier/spawn.rs +0 -91
- package/rust/core/parser/handler/identifier/synth.rs +0 -135
- package/rust/core/parser/handler/loop_.rs +0 -194
- package/rust/core/parser/handler/mod.rs +0 -9
- package/rust/core/parser/handler/pattern.rs +0 -74
- package/rust/core/parser/handler/tempo.rs +0 -105
- package/rust/core/parser/mod.rs +0 -3
- package/rust/core/parser/statement.rs +0 -10
- package/rust/core/plugin/loader.rs +0 -137
- package/rust/core/plugin/mod.rs +0 -2
- package/rust/core/plugin/runner/mod.rs +0 -11
- package/rust/core/plugin/runner/non_wasm.rs +0 -297
- package/rust/core/plugin/runner/wasm32.rs +0 -43
- package/rust/core/preprocessor/loader/inject.rs +0 -278
- package/rust/core/preprocessor/loader/loader_helpers.rs +0 -110
- package/rust/core/preprocessor/loader/mod.rs +0 -235
- package/rust/core/preprocessor/mod.rs +0 -4
- package/rust/core/preprocessor/module.rs +0 -55
- package/rust/core/preprocessor/processor/handlers.rs +0 -107
- package/rust/core/preprocessor/processor/mod.rs +0 -1
- package/rust/core/preprocessor/resolver/bank.rs +0 -49
- package/rust/core/preprocessor/resolver/call.rs +0 -124
- package/rust/core/preprocessor/resolver/condition.rs +0 -95
- package/rust/core/preprocessor/resolver/driver.rs +0 -324
- package/rust/core/preprocessor/resolver/function.rs +0 -69
- package/rust/core/preprocessor/resolver/group.rs +0 -122
- package/rust/core/preprocessor/resolver/let_.rs +0 -32
- package/rust/core/preprocessor/resolver/loop_.rs +0 -318
- package/rust/core/preprocessor/resolver/mod.rs +0 -16
- package/rust/core/preprocessor/resolver/pattern.rs +0 -83
- package/rust/core/preprocessor/resolver/spawn.rs +0 -99
- package/rust/core/preprocessor/resolver/synth.rs +0 -54
- package/rust/core/preprocessor/resolver/tempo.rs +0 -48
- package/rust/core/preprocessor/resolver/trigger.rs +0 -116
- package/rust/core/preprocessor/resolver/value.rs +0 -176
- package/rust/core/store/global.rs +0 -57
- package/rust/core/store/mod.rs +0 -1
- package/rust/lib.rs +0 -323
- package/rust/main.rs +0 -388
- package/rust/types/Cargo.toml +0 -11
- package/rust/types/src/addons.rs +0 -55
- package/rust/types/src/ast.rs +0 -202
- package/rust/types/src/config.rs +0 -84
- package/rust/types/src/lib.rs +0 -15
- package/rust/types/src/plugin.rs +0 -20
- package/rust/types/src/store.rs +0 -139
- package/rust/types/src/telemetry.rs +0 -85
- package/rust/utils/Cargo.toml +0 -26
- package/rust/utils/src/error.rs +0 -186
- package/rust/utils/src/file.rs +0 -94
- package/rust/utils/src/first_usage.rs +0 -97
- package/rust/utils/src/lib.rs +0 -9
- package/rust/utils/src/logger.rs +0 -200
- package/rust/utils/src/path.rs +0 -129
- package/rust/utils/src/signature.rs +0 -41
- package/rust/utils/src/spinner.rs +0 -20
- package/rust/utils/src/version.rs +0 -27
- package/rust/utils/src/watcher.rs +0 -46
- package/rust/web/api.rs +0 -5
- package/rust/web/cdn.rs +0 -34
- package/rust/web/mod.rs +0 -3
- package/rust/web/sso.rs +0 -5
- package/templates/minimal/.devalang +0 -5
- package/templates/minimal/README.md +0 -218
- package/templates/minimal/src/index.deva +0 -2
- package/templates/welcome/.devalang +0 -5
- package/templates/welcome/README.md +0 -218
- package/templates/welcome/samples/kick-808.wav +0 -0
- package/templates/welcome/src/index.deva +0 -61
- package/templates/welcome/src/variables.deva +0 -3
- package/tests/integration.rs +0 -21
- package/tests/rust/cli_check_build.rs +0 -21
- package/tests/rust/cli_help.rs +0 -12
- package/tests/rust/cli_template_list.rs +0 -10
- package/tests/rust/cli_version.rs +0 -11
- package/tests/typescript/index.spec.ts +0 -136
- package/tests/typescript/playhead.spec.ts +0 -36
- package/tests/typescript/render_e2e.spec.ts +0 -77
- package/tsconfig.json +0 -115
- package/typescript/bin/index.ts +0 -28
- package/typescript/core/functions/index.ts +0 -94
- package/typescript/core/index.ts +0 -6
- package/typescript/core/types/index.ts +0 -4
- package/typescript/core/types/plugin.ts +0 -19
- package/typescript/core/types/result.ts +0 -29
- package/typescript/core/types/statement.ts +0 -47
- package/typescript/core/types/value.ts +0 -29
- package/typescript/index.ts +0 -8
- package/typescript/pkg/devalang_core.d.ts +0 -4
- package/typescript/pkg/devalang_core.ts +0 -65
- package/typescript/scripts/copy-wasm-dts.ts +0 -41
- package/typescript/scripts/postinstall.ts +0 -85
- package/typescript/scripts/version/bump.ts +0 -44
- package/typescript/scripts/version/fetch.ts +0 -18
- package/typescript/scripts/version/index.ts +0 -25
- package/typescript/scripts/version/sync.ts +0 -24
|
@@ -1,375 +0,0 @@
|
|
|
1
|
-
use crate::config::driver::ProjectConfig;
|
|
2
|
-
use devalang_utils::logger::{LogLevel, Logger};
|
|
3
|
-
use devalang_utils::path::{find_entry_file, normalize_path};
|
|
4
|
-
use std::{sync::mpsc::channel, thread};
|
|
5
|
-
|
|
6
|
-
pub use crate::cli::play::io::wav_duration_seconds;
|
|
7
|
-
pub use crate::cli::play::realtime::{
|
|
8
|
-
RtContext, join_realtime_runner, start_realtime_runner, stop_realtime_runner,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
use super::process::process_play;
|
|
12
|
-
use super::utils::{files_changed, snapshot_files};
|
|
13
|
-
|
|
14
|
-
use crate::core::audio::player::AudioPlayer;
|
|
15
|
-
|
|
16
|
-
#[cfg(feature = "cli")]
|
|
17
|
-
pub fn handle_play_command(
|
|
18
|
-
config: Option<ProjectConfig>,
|
|
19
|
-
entry: Option<String>,
|
|
20
|
-
output: Option<String>,
|
|
21
|
-
audio_format: crate::cli::parser::AudioFormat,
|
|
22
|
-
sample_rate: u32,
|
|
23
|
-
watch: bool,
|
|
24
|
-
repeat: bool,
|
|
25
|
-
debug: bool,
|
|
26
|
-
) -> Result<(), String> {
|
|
27
|
-
let logger = Logger::new();
|
|
28
|
-
|
|
29
|
-
// Determine final audio_format and sample_rate, preferring CLI values but falling back to config defaults
|
|
30
|
-
let mut final_audio_format = audio_format;
|
|
31
|
-
let mut final_sample_rate = sample_rate;
|
|
32
|
-
if let Some(cfg) = config.as_ref() {
|
|
33
|
-
if let Some(af) = cfg.defaults.audio_format.as_ref() {
|
|
34
|
-
let af_low = af.to_lowercase();
|
|
35
|
-
final_audio_format = match af_low.as_str() {
|
|
36
|
-
"wav24" => crate::cli::parser::AudioFormat::Wav24,
|
|
37
|
-
"wav32" => crate::cli::parser::AudioFormat::Wav32,
|
|
38
|
-
_ => crate::cli::parser::AudioFormat::Wav16,
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
if let Some(sr) = cfg.defaults.sample_rate {
|
|
42
|
-
// Only override if CLI provided a 0 or unrealistic value (we assume CLI provides a valid value)
|
|
43
|
-
if final_sample_rate == 0 {
|
|
44
|
-
final_sample_rate = sr;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let entry_path = entry
|
|
50
|
-
.or_else(|| config.as_ref().and_then(|c| c.defaults.entry.clone()))
|
|
51
|
-
.unwrap_or_default();
|
|
52
|
-
|
|
53
|
-
let output_path = output
|
|
54
|
-
.or_else(|| config.as_ref().and_then(|c| c.defaults.output.clone()))
|
|
55
|
-
.unwrap_or_default();
|
|
56
|
-
|
|
57
|
-
let fetched_repeat = if repeat {
|
|
58
|
-
true
|
|
59
|
-
} else {
|
|
60
|
-
config
|
|
61
|
-
.as_ref()
|
|
62
|
-
.and_then(|c| c.defaults.repeat)
|
|
63
|
-
.unwrap_or(false)
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
if entry_path.is_empty() || output_path.is_empty() {
|
|
67
|
-
logger.log_message(LogLevel::Error, "Entry or output path not specified.");
|
|
68
|
-
return Err("missing entry or output".to_string());
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let entry_file = match find_entry_file(&entry_path) {
|
|
72
|
-
Some(p) => p,
|
|
73
|
-
None => {
|
|
74
|
-
logger.log_message(LogLevel::Error, "index.deva not found");
|
|
75
|
-
return Err("index.deva not found".to_string());
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
let audio_file = format!("{}/audio/index.wav", normalize_path(&output_path));
|
|
80
|
-
let mut audio_player = AudioPlayer::new();
|
|
81
|
-
|
|
82
|
-
if watch && fetched_repeat {
|
|
83
|
-
logger.log_message(
|
|
84
|
-
LogLevel::Error,
|
|
85
|
-
"Watch and repeat cannot be used together. Use repeat instead.",
|
|
86
|
-
);
|
|
87
|
-
return Err("invalid options: watch and repeat cannot be combined".to_string());
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if watch {
|
|
91
|
-
let (tx, rx) = channel::<()>();
|
|
92
|
-
|
|
93
|
-
// Thread 1 : Watcher sending changes
|
|
94
|
-
let entry_clone = entry_path.clone();
|
|
95
|
-
thread::spawn(move || {
|
|
96
|
-
let _ = devalang_utils::watcher::watch_directory(entry_clone, move || {
|
|
97
|
-
let _ = tx.send(()); // signal a change
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Main thread: build + play in a loop
|
|
102
|
-
let (bpm, entry_stmts, variables, functions, global_store) = process_play(
|
|
103
|
-
&config,
|
|
104
|
-
&entry_file,
|
|
105
|
-
&output_path,
|
|
106
|
-
final_audio_format,
|
|
107
|
-
final_sample_rate,
|
|
108
|
-
debug,
|
|
109
|
-
)?;
|
|
110
|
-
audio_player.play_file_once(&audio_file);
|
|
111
|
-
// Estimate duration: base on statement count plus extra for loop iterations (1 beat per iter)
|
|
112
|
-
let loop_iters: usize = entry_stmts
|
|
113
|
-
.iter()
|
|
114
|
-
.map(|s| match &s.kind {
|
|
115
|
-
crate::core::parser::statement::StatementKind::Loop => {
|
|
116
|
-
use devalang_types::Value;
|
|
117
|
-
if let Value::Map(m) = &s.value {
|
|
118
|
-
if let Some(Value::Array(items)) = m.get("array") {
|
|
119
|
-
items.len()
|
|
120
|
-
} else if let Some(Value::Number(n)) = m.get("iterator") {
|
|
121
|
-
(*n).max(0.0) as usize
|
|
122
|
-
} else {
|
|
123
|
-
0
|
|
124
|
-
}
|
|
125
|
-
} else {
|
|
126
|
-
0
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
_ => 0,
|
|
130
|
-
})
|
|
131
|
-
.sum();
|
|
132
|
-
let est_beats = (entry_stmts.len() as f32) + (loop_iters as f32);
|
|
133
|
-
let est_by_len = ((60.0 / bpm).max(0.01) * est_beats).max(1.0);
|
|
134
|
-
let total_secs = wav_duration_seconds(&audio_file)
|
|
135
|
-
.unwrap_or(0.0)
|
|
136
|
-
.max(est_by_len);
|
|
137
|
-
let mut rt_runner = Some(start_realtime_runner(
|
|
138
|
-
RtContext {
|
|
139
|
-
bpm,
|
|
140
|
-
entry_stmts,
|
|
141
|
-
variables,
|
|
142
|
-
functions,
|
|
143
|
-
global_store,
|
|
144
|
-
},
|
|
145
|
-
total_secs,
|
|
146
|
-
));
|
|
147
|
-
|
|
148
|
-
logger.log_message(
|
|
149
|
-
LogLevel::Watcher,
|
|
150
|
-
"Watching for changes... Press Ctrl+C to exit.",
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
while rx.recv().is_ok() {
|
|
154
|
-
logger.log_message(LogLevel::Watcher, "Change detected, rebuilding...");
|
|
155
|
-
|
|
156
|
-
// Stop previous real-time runner before restarting playback
|
|
157
|
-
stop_realtime_runner(&mut rt_runner);
|
|
158
|
-
|
|
159
|
-
let (bpm, entry_stmts, variables, functions, global_store) = match process_play(
|
|
160
|
-
&config,
|
|
161
|
-
&entry_file,
|
|
162
|
-
&output_path,
|
|
163
|
-
final_audio_format,
|
|
164
|
-
final_sample_rate,
|
|
165
|
-
debug,
|
|
166
|
-
) {
|
|
167
|
-
Ok(v) => v,
|
|
168
|
-
Err(e) => {
|
|
169
|
-
logger.log_message(LogLevel::Error, &format!("Rebuild failed: {}", e));
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
logger.log_message(LogLevel::Info, "🎵 Playback started (once mode)...");
|
|
175
|
-
|
|
176
|
-
audio_player.play_file_once(&audio_file);
|
|
177
|
-
let loop_iters: usize = entry_stmts
|
|
178
|
-
.iter()
|
|
179
|
-
.map(|s| match &s.kind {
|
|
180
|
-
crate::core::parser::statement::StatementKind::Loop => {
|
|
181
|
-
use devalang_types::Value;
|
|
182
|
-
if let Value::Map(m) = &s.value {
|
|
183
|
-
if let Some(Value::Array(items)) = m.get("array") {
|
|
184
|
-
items.len()
|
|
185
|
-
} else if let Some(Value::Number(n)) = m.get("iterator") {
|
|
186
|
-
(*n).max(0.0) as usize
|
|
187
|
-
} else {
|
|
188
|
-
0
|
|
189
|
-
}
|
|
190
|
-
} else {
|
|
191
|
-
0
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
_ => 0,
|
|
195
|
-
})
|
|
196
|
-
.sum();
|
|
197
|
-
let est_beats = (entry_stmts.len() as f32) + (loop_iters as f32);
|
|
198
|
-
let est_by_len = ((60.0 / bpm).max(0.01) * est_beats).max(1.0);
|
|
199
|
-
let total_secs = wav_duration_seconds(&audio_file)
|
|
200
|
-
.unwrap_or(0.0)
|
|
201
|
-
.max(est_by_len);
|
|
202
|
-
rt_runner = Some(start_realtime_runner(
|
|
203
|
-
RtContext {
|
|
204
|
-
bpm,
|
|
205
|
-
entry_stmts: entry_stmts.clone(),
|
|
206
|
-
variables: variables.clone(),
|
|
207
|
-
functions: functions.clone(),
|
|
208
|
-
global_store: global_store.clone(),
|
|
209
|
-
},
|
|
210
|
-
total_secs,
|
|
211
|
-
));
|
|
212
|
-
}
|
|
213
|
-
} else if fetched_repeat {
|
|
214
|
-
// Initial build to start from a clean slate
|
|
215
|
-
let (bpm, entry_stmts, variables, functions, global_store) = process_play(
|
|
216
|
-
&config,
|
|
217
|
-
&entry_file,
|
|
218
|
-
&output_path,
|
|
219
|
-
final_audio_format,
|
|
220
|
-
final_sample_rate,
|
|
221
|
-
debug,
|
|
222
|
-
)?;
|
|
223
|
-
|
|
224
|
-
logger.log_message(LogLevel::Info, "🎵 Playback started (repeat mode)...");
|
|
225
|
-
|
|
226
|
-
let mut last_snapshot = snapshot_files(&entry_path);
|
|
227
|
-
let mut audio_player = AudioPlayer::new();
|
|
228
|
-
audio_player.play_file_once(&audio_file);
|
|
229
|
-
|
|
230
|
-
let loop_iters: usize = entry_stmts
|
|
231
|
-
.iter()
|
|
232
|
-
.map(|s| match &s.kind {
|
|
233
|
-
crate::core::parser::statement::StatementKind::Loop => {
|
|
234
|
-
use devalang_types::Value;
|
|
235
|
-
|
|
236
|
-
if let Value::Map(m) = &s.value {
|
|
237
|
-
if let Some(Value::Array(items)) = m.get("array") {
|
|
238
|
-
items.len()
|
|
239
|
-
} else if let Some(Value::Number(n)) = m.get("iterator") {
|
|
240
|
-
(*n).max(0.0) as usize
|
|
241
|
-
} else {
|
|
242
|
-
0
|
|
243
|
-
}
|
|
244
|
-
} else {
|
|
245
|
-
0
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
_ => 0,
|
|
249
|
-
})
|
|
250
|
-
.sum();
|
|
251
|
-
let est_beats = (entry_stmts.len() as f32) + (loop_iters as f32);
|
|
252
|
-
let est_by_len = ((60.0 / bpm).max(0.01) * est_beats).max(1.0);
|
|
253
|
-
let total_secs = wav_duration_seconds(&audio_file)
|
|
254
|
-
.unwrap_or(0.0)
|
|
255
|
-
.max(est_by_len);
|
|
256
|
-
let mut rt_runner = Some(start_realtime_runner(
|
|
257
|
-
RtContext {
|
|
258
|
-
bpm,
|
|
259
|
-
entry_stmts: entry_stmts.clone(),
|
|
260
|
-
variables: variables.clone(),
|
|
261
|
-
functions: functions.clone(),
|
|
262
|
-
global_store: global_store.clone(),
|
|
263
|
-
},
|
|
264
|
-
total_secs,
|
|
265
|
-
));
|
|
266
|
-
|
|
267
|
-
loop {
|
|
268
|
-
let current_snapshot = snapshot_files(&entry_path);
|
|
269
|
-
let has_changed = files_changed(&last_snapshot, ¤t_snapshot);
|
|
270
|
-
|
|
271
|
-
if has_changed {
|
|
272
|
-
logger.log_message(
|
|
273
|
-
LogLevel::Info,
|
|
274
|
-
"Change detected, rebuilding in background...",
|
|
275
|
-
);
|
|
276
|
-
let entry_file = entry_file.clone();
|
|
277
|
-
let output_path = output_path.clone();
|
|
278
|
-
let config_clone = config.clone();
|
|
279
|
-
|
|
280
|
-
// Rebuild in a separate thread
|
|
281
|
-
std::thread::spawn(move || {
|
|
282
|
-
if let Err(e) = process_play(
|
|
283
|
-
&config_clone,
|
|
284
|
-
&entry_file,
|
|
285
|
-
&output_path,
|
|
286
|
-
final_audio_format,
|
|
287
|
-
final_sample_rate,
|
|
288
|
-
debug,
|
|
289
|
-
) {
|
|
290
|
-
eprintln!("Rebuild failed in background: {}", e);
|
|
291
|
-
}
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
last_snapshot = current_snapshot;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Wait for the audio to finish
|
|
298
|
-
audio_player.wait_until_end();
|
|
299
|
-
// Stop the current real-time runner
|
|
300
|
-
stop_realtime_runner(&mut rt_runner);
|
|
301
|
-
|
|
302
|
-
// Then replay the audio (rebuilt or not)
|
|
303
|
-
audio_player.play_file_once(&audio_file);
|
|
304
|
-
let loop_iters: usize = entry_stmts
|
|
305
|
-
.iter()
|
|
306
|
-
.map(|s| match &s.kind {
|
|
307
|
-
crate::core::parser::statement::StatementKind::Loop => {
|
|
308
|
-
use devalang_types::Value;
|
|
309
|
-
if let Value::Map(m) = &s.value {
|
|
310
|
-
if let Some(Value::Array(items)) = m.get("array") {
|
|
311
|
-
items.len()
|
|
312
|
-
} else if let Some(Value::Number(n)) = m.get("iterator") {
|
|
313
|
-
(*n).max(0.0) as usize
|
|
314
|
-
} else {
|
|
315
|
-
0
|
|
316
|
-
}
|
|
317
|
-
} else {
|
|
318
|
-
0
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
_ => 0,
|
|
322
|
-
})
|
|
323
|
-
.sum();
|
|
324
|
-
let est_beats = (entry_stmts.len() as f32) + (loop_iters as f32);
|
|
325
|
-
let est_by_len = ((60.0 / bpm).max(0.01) * est_beats).max(1.0);
|
|
326
|
-
let total_secs = wav_duration_seconds(&audio_file)
|
|
327
|
-
.unwrap_or(0.0)
|
|
328
|
-
.max(est_by_len);
|
|
329
|
-
rt_runner = Some(start_realtime_runner(
|
|
330
|
-
RtContext {
|
|
331
|
-
bpm,
|
|
332
|
-
entry_stmts: entry_stmts.clone(),
|
|
333
|
-
variables: variables.clone(),
|
|
334
|
-
functions: functions.clone(),
|
|
335
|
-
global_store: global_store.clone(),
|
|
336
|
-
},
|
|
337
|
-
total_secs,
|
|
338
|
-
));
|
|
339
|
-
}
|
|
340
|
-
} else {
|
|
341
|
-
// Single execution
|
|
342
|
-
let (bpm, entry_stmts, variables, functions, global_store) = process_play(
|
|
343
|
-
&config,
|
|
344
|
-
&entry_file,
|
|
345
|
-
&output_path,
|
|
346
|
-
final_audio_format,
|
|
347
|
-
final_sample_rate,
|
|
348
|
-
debug,
|
|
349
|
-
)?;
|
|
350
|
-
|
|
351
|
-
logger.log_message(LogLevel::Info, "🎵 Playback started (once mode)...");
|
|
352
|
-
|
|
353
|
-
audio_player.play_file_once(&audio_file);
|
|
354
|
-
|
|
355
|
-
let est_by_len = ((60.0 / bpm).max(0.01) * (entry_stmts.len() as f32)).max(1.0);
|
|
356
|
-
let total_secs = wav_duration_seconds(&audio_file)
|
|
357
|
-
.unwrap_or(0.0)
|
|
358
|
-
.max(est_by_len);
|
|
359
|
-
let mut rt_runner = Some(start_realtime_runner(
|
|
360
|
-
RtContext {
|
|
361
|
-
bpm,
|
|
362
|
-
entry_stmts,
|
|
363
|
-
variables,
|
|
364
|
-
functions,
|
|
365
|
-
global_store,
|
|
366
|
-
},
|
|
367
|
-
total_secs,
|
|
368
|
-
));
|
|
369
|
-
|
|
370
|
-
audio_player.wait_until_end();
|
|
371
|
-
// Let the runner finish naturally to execute all remaining statements (e.g., loop prints)
|
|
372
|
-
join_realtime_runner(&mut rt_runner);
|
|
373
|
-
}
|
|
374
|
-
Ok(())
|
|
375
|
-
}
|
package/rust/cli/play/io.rs
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
use hound;
|
|
2
|
-
|
|
3
|
-
pub fn wav_duration_seconds(path: &str) -> Option<f32> {
|
|
4
|
-
if let Ok(reader) = hound::WavReader::open(path) {
|
|
5
|
-
let spec = reader.spec();
|
|
6
|
-
let len = reader.len();
|
|
7
|
-
if spec.sample_rate == 0 {
|
|
8
|
-
return None;
|
|
9
|
-
}
|
|
10
|
-
let channels = spec.channels.max(1) as u32;
|
|
11
|
-
let frames = len / channels;
|
|
12
|
-
let dur = (frames as f32) / (spec.sample_rate as f32);
|
|
13
|
-
Some(dur)
|
|
14
|
-
} else {
|
|
15
|
-
None
|
|
16
|
-
}
|
|
17
|
-
}
|
package/rust/cli/play/mod.rs
DELETED
package/rust/cli/play/process.rs
DELETED
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
use crate::{
|
|
2
|
-
config::driver::ProjectConfig,
|
|
3
|
-
core::{
|
|
4
|
-
builder::Builder,
|
|
5
|
-
debugger::{
|
|
6
|
-
lexer::write_lexer_log_file,
|
|
7
|
-
logs::{write_module_function_log_file, write_module_variable_log_file},
|
|
8
|
-
preprocessor::write_preprocessor_log_file,
|
|
9
|
-
store::{write_function_log_file, write_variables_log_file},
|
|
10
|
-
},
|
|
11
|
-
preprocessor::loader::ModuleLoader,
|
|
12
|
-
store::global::GlobalStore,
|
|
13
|
-
},
|
|
14
|
-
};
|
|
15
|
-
use devalang_utils::path::normalize_path;
|
|
16
|
-
use devalang_utils::{
|
|
17
|
-
logger::{LogLevel, Logger},
|
|
18
|
-
spinner::start_spinner,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
pub fn process_play(
|
|
22
|
-
_config: &Option<ProjectConfig>,
|
|
23
|
-
entry_file: &str,
|
|
24
|
-
output: &str,
|
|
25
|
-
audio_format: crate::cli::parser::AudioFormat,
|
|
26
|
-
sample_rate: u32,
|
|
27
|
-
debug: bool,
|
|
28
|
-
) -> Result<
|
|
29
|
-
(
|
|
30
|
-
f32,
|
|
31
|
-
Vec<crate::core::parser::statement::Statement>,
|
|
32
|
-
devalang_types::VariableTable,
|
|
33
|
-
devalang_types::FunctionTable,
|
|
34
|
-
crate::core::store::global::GlobalStore,
|
|
35
|
-
),
|
|
36
|
-
String,
|
|
37
|
-
> {
|
|
38
|
-
let spinner = start_spinner("Building...");
|
|
39
|
-
|
|
40
|
-
let normalized_entry = normalize_path(entry_file);
|
|
41
|
-
let normalized_output_dir = normalize_path(output);
|
|
42
|
-
|
|
43
|
-
let duration = std::time::Instant::now();
|
|
44
|
-
let mut global_store = GlobalStore::new();
|
|
45
|
-
let loader = ModuleLoader::new(&normalized_entry, &normalized_output_dir);
|
|
46
|
-
let (modules_tokens, modules_statements) = loader.load_all_modules(&mut global_store);
|
|
47
|
-
|
|
48
|
-
// Try to detect initial BPM from statements (fallback to 120.0)
|
|
49
|
-
let mut detected_bpm: f32 = 120.0;
|
|
50
|
-
let mut entry_statements: Vec<crate::core::parser::statement::Statement> = Vec::new();
|
|
51
|
-
// Prefer the entry module if present
|
|
52
|
-
if let Some(entry_stmts) = modules_statements.get(&normalized_entry) {
|
|
53
|
-
entry_statements = entry_stmts.clone();
|
|
54
|
-
for stmt in entry_stmts {
|
|
55
|
-
if let crate::core::parser::statement::StatementKind::Tempo = &stmt.kind {
|
|
56
|
-
use devalang_types::Value;
|
|
57
|
-
if let Value::Number(n) = &stmt.value {
|
|
58
|
-
detected_bpm = *n;
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// If still default, scan other modules for a tempo directive
|
|
65
|
-
if (detected_bpm - 120.0).abs() < f32::EPSILON {
|
|
66
|
-
'outer: for (_name, stmts) in modules_statements.iter() {
|
|
67
|
-
for stmt in stmts {
|
|
68
|
-
if let crate::core::parser::statement::StatementKind::Tempo = &stmt.kind {
|
|
69
|
-
use devalang_types::Value;
|
|
70
|
-
if let Value::Number(n) = &stmt.value {
|
|
71
|
-
detected_bpm = *n;
|
|
72
|
-
break 'outer;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// SECTION Write logs
|
|
80
|
-
if debug {
|
|
81
|
-
for (module_path, module) in global_store.modules.clone() {
|
|
82
|
-
write_module_variable_log_file(
|
|
83
|
-
&normalized_output_dir,
|
|
84
|
-
&module_path,
|
|
85
|
-
&module.variable_table,
|
|
86
|
-
);
|
|
87
|
-
write_module_function_log_file(
|
|
88
|
-
&normalized_output_dir,
|
|
89
|
-
&module_path,
|
|
90
|
-
&module.function_table,
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
write_lexer_log_file(
|
|
95
|
-
&normalized_output_dir,
|
|
96
|
-
"lexer_tokens.log",
|
|
97
|
-
modules_tokens.clone(),
|
|
98
|
-
);
|
|
99
|
-
write_preprocessor_log_file(
|
|
100
|
-
&normalized_output_dir,
|
|
101
|
-
"resolved_statements.log",
|
|
102
|
-
modules_statements.clone(),
|
|
103
|
-
);
|
|
104
|
-
write_variables_log_file(
|
|
105
|
-
&normalized_output_dir,
|
|
106
|
-
"global_variables.log",
|
|
107
|
-
global_store.variables.clone(),
|
|
108
|
-
);
|
|
109
|
-
write_function_log_file(
|
|
110
|
-
&normalized_output_dir,
|
|
111
|
-
"global_functions.log",
|
|
112
|
-
global_store.functions.clone(),
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// SECTION Detect errors before building (like build.rs)
|
|
117
|
-
let all_errors = crate::core::error::collect_all_errors_with_modules(&modules_statements);
|
|
118
|
-
let (warnings, criticals) = crate::core::error::partition_errors(all_errors);
|
|
119
|
-
crate::core::error::log_errors_with_stack("Play", &warnings, &criticals);
|
|
120
|
-
if !criticals.is_empty() {
|
|
121
|
-
spinner.finish_and_clear();
|
|
122
|
-
return Err(format!(
|
|
123
|
-
"play failed with {} critical error(s): {}",
|
|
124
|
-
criticals.len(),
|
|
125
|
-
criticals[0].message
|
|
126
|
-
));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// SECTION Building AST and Audio
|
|
130
|
-
let builder = Builder::new();
|
|
131
|
-
builder.build_ast(&modules_statements, output, false);
|
|
132
|
-
let audio_format_str = format!("{:?}", audio_format);
|
|
133
|
-
builder.build_audio(
|
|
134
|
-
&modules_statements,
|
|
135
|
-
output,
|
|
136
|
-
&mut global_store,
|
|
137
|
-
Some(audio_format_str),
|
|
138
|
-
Some(sample_rate),
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
// SECTION Logging
|
|
142
|
-
let logger = Logger::new();
|
|
143
|
-
let success_message = format!(
|
|
144
|
-
"Build completed successfully in {:.2?}. Output files written to: '{}'",
|
|
145
|
-
duration.elapsed(),
|
|
146
|
-
normalized_output_dir
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
spinner.finish_and_clear();
|
|
150
|
-
logger.log_message(LogLevel::Success, &success_message);
|
|
151
|
-
|
|
152
|
-
Ok((
|
|
153
|
-
detected_bpm,
|
|
154
|
-
entry_statements,
|
|
155
|
-
global_store.variables.clone(),
|
|
156
|
-
global_store.functions.clone(),
|
|
157
|
-
global_store,
|
|
158
|
-
))
|
|
159
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
use std::sync::Arc;
|
|
2
|
-
use std::sync::atomic::{AtomicBool, Ordering};
|
|
3
|
-
use std::time::Duration;
|
|
4
|
-
|
|
5
|
-
use devalang_types::Value;
|
|
6
|
-
|
|
7
|
-
pub struct RtRunner {
|
|
8
|
-
pub stop: Arc<AtomicBool>,
|
|
9
|
-
pub handle: std::thread::JoinHandle<()>,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
pub struct RtContext {
|
|
13
|
-
pub bpm: f32,
|
|
14
|
-
pub entry_stmts: Vec<crate::core::parser::statement::Statement>,
|
|
15
|
-
pub variables: devalang_types::store::VariableTable,
|
|
16
|
-
pub functions: devalang_types::store::FunctionTable,
|
|
17
|
-
pub global_store: crate::core::store::global::GlobalStore,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
pub fn start_realtime_runner(ctx: RtContext, total_secs: f32) -> RtRunner {
|
|
21
|
-
use crate::core::audio::engine::AudioEngine;
|
|
22
|
-
use crate::core::audio::interpreter::driver::execute_audio_block;
|
|
23
|
-
use crate::core::parser::statement::StatementKind;
|
|
24
|
-
use devalang_utils::logger::Logger;
|
|
25
|
-
|
|
26
|
-
let stop = Arc::new(AtomicBool::new(false));
|
|
27
|
-
let stop_clone = stop.clone();
|
|
28
|
-
|
|
29
|
-
let handle = std::thread::spawn(move || {
|
|
30
|
-
let _logger = Logger::new();
|
|
31
|
-
let bpm = if ctx.bpm > 0.0 { ctx.bpm } else { 120.0 };
|
|
32
|
-
let beat_secs = 60.0f32 / bpm;
|
|
33
|
-
let mut elapsed = 0.0f32;
|
|
34
|
-
|
|
35
|
-
let mut variables = ctx.variables.clone();
|
|
36
|
-
variables.set("__rt".to_string(), Value::Boolean(true));
|
|
37
|
-
let functions = ctx.functions.clone();
|
|
38
|
-
let _global_store = ctx.global_store.clone();
|
|
39
|
-
let mut audio_engine = AudioEngine::new("rt".to_string());
|
|
40
|
-
|
|
41
|
-
let i: usize = 0;
|
|
42
|
-
let mut _current_loop: Option<()> = None; // simplified state
|
|
43
|
-
let mut _beat_index: u64 = 0;
|
|
44
|
-
while elapsed + 1e-3 < total_secs && i < ctx.entry_stmts.len() {
|
|
45
|
-
if stop_clone.load(Ordering::Relaxed) {
|
|
46
|
-
break;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
std::thread::sleep(Duration::from_secs_f32(beat_secs));
|
|
50
|
-
elapsed += beat_secs;
|
|
51
|
-
_beat_index += 1;
|
|
52
|
-
if stop_clone.load(Ordering::Relaxed) {
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Only fire periodic handlers when not in a loop - simplified
|
|
57
|
-
if let Some(handlers) = ctx.global_store.get_event_handlers("beat") {
|
|
58
|
-
for h in handlers {
|
|
59
|
-
if let StatementKind::On { body, .. } = &h.kind {
|
|
60
|
-
let _ = execute_audio_block(
|
|
61
|
-
&mut audio_engine,
|
|
62
|
-
&ctx.global_store,
|
|
63
|
-
variables.clone(),
|
|
64
|
-
functions.clone(),
|
|
65
|
-
body,
|
|
66
|
-
bpm,
|
|
67
|
-
60.0 / bpm,
|
|
68
|
-
0.0,
|
|
69
|
-
0.0,
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
RtRunner { stop, handle }
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
pub fn stop_realtime_runner(runner_opt: &mut Option<RtRunner>) {
|
|
81
|
-
if let Some(r) = runner_opt.take() {
|
|
82
|
-
r.stop.store(true, Ordering::Relaxed);
|
|
83
|
-
let _ = r.handle.join();
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
pub fn join_realtime_runner(runner_opt: &mut Option<RtRunner>) {
|
|
88
|
-
if let Some(r) = runner_opt.take() {
|
|
89
|
-
let _ = r.handle.join();
|
|
90
|
-
}
|
|
91
|
-
}
|
package/rust/cli/play/utils.rs
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
use std::collections::HashMap;
|
|
2
|
-
use std::fs;
|
|
3
|
-
use std::path::Path;
|
|
4
|
-
|
|
5
|
-
pub fn snapshot_files<P: AsRef<Path>>(dir: P) -> HashMap<String, u64> {
|
|
6
|
-
let mut map = HashMap::new();
|
|
7
|
-
if let Ok(entries) = fs::read_dir(dir) {
|
|
8
|
-
for entry in entries.flatten() {
|
|
9
|
-
if let Ok(meta) = entry.metadata() {
|
|
10
|
-
if let Ok(mtime) = meta.modified() {
|
|
11
|
-
if let Ok(duration) = mtime.duration_since(std::time::UNIX_EPOCH) {
|
|
12
|
-
map.insert(entry.path().display().to_string(), duration.as_secs());
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
map
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
pub fn files_changed(old: &HashMap<String, u64>, new: &HashMap<String, u64>) -> bool {
|
|
22
|
-
old != new
|
|
23
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
use crate::config::settings::set_user_config_value;
|
|
2
|
-
use devalang_utils::logger::{LogLevel, Logger};
|
|
3
|
-
|
|
4
|
-
#[cfg(feature = "cli")]
|
|
5
|
-
pub async fn handle_telemetry_enable_command() -> Result<(), String> {
|
|
6
|
-
set_user_config_value("telemetry", serde_json::Value::Bool(true));
|
|
7
|
-
|
|
8
|
-
let logger = Logger::new();
|
|
9
|
-
logger.log_message(LogLevel::Info, "Telemetry has been enabled.");
|
|
10
|
-
|
|
11
|
-
Ok(())
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
#[cfg(feature = "cli")]
|
|
15
|
-
pub async fn handle_telemetry_disable_command() -> Result<(), String> {
|
|
16
|
-
set_user_config_value("telemetry", serde_json::Value::Bool(false));
|
|
17
|
-
|
|
18
|
-
let logger = Logger::new();
|
|
19
|
-
logger.log_message(LogLevel::Info, "Telemetry has been disabled.");
|
|
20
|
-
|
|
21
|
-
Ok(())
|
|
22
|
-
}
|