Skip to main content

Dynamic Scoping(动态作用域)

Dynamic Scoping(动态作用域)

大多数 ProtoGraph 使用静态作用域(也称为词法作用域)。这使得构建模块化程序更容易,但某些编程模式(如隐式参数和异常处理)使用动态作用域来表达会更自然。

动态变量和脉冲在 Resonite 代码中非常常见,ProtoGraph 提供了一套特殊的统一语法来简化它们的使用。有一组以 ~(波浪号)开头的关键字节点,表示该节点与动态相关内容相关。

在适用的情况下,动态节点的第一个参数是一个槽位(比如目标或源)。这允许使用流畅的调用风格,看起来像是在槽位上调用方法。

警告:某些动态节点的参数顺序与它们生成的 ProtoFlux 节点不同。请注意,Resonite ProtoFlux 文档可能不反映相同的参数顺序。请使用 ProtoGraph 文档和示例来了解如何使用动态节点。

Dynamic Variables(动态变量)

这些节点允许你读取和写入动态变量。

节点 (Node) 描述 (Description)
~input<T> 提供动态变量值(Source)
~read<T> 读取动态变量值
~write<T> 写入动态变量
// 使用变量名提供动态变量。
// 变量名必须是 'global'。
// 字符串字面量会自动转换为全局变量。
// 类型参数是必需的。
SourceDynVar = ~input<bool>("VariableName");
display(SourceDynVar.Value);
display(SourceDynVar.HasValue);

// 从源槽位读取动态变量。
// 类型参数是必需的。
DynVar = SourceSlot->~read<int>("VariableTag");
display(DynVar.Value);
display(DynVar.HasValue);

// 写入动态变量。
// 类型参数可以从 'Value' 参数推断
// 注意这是一个脉冲节点,但不是 'dynamic impulse' 节点
switch S->~write("VariablePath", Value="Value to write...")
| OnSuccess  |> impulse {}
| OnFailed   |> impulse {}
| OnNotFound |> impulse {};

Dynamic Impulses(动态脉冲)

这些节点允许你触发和接收动态脉冲。Resonite 中动态脉冲的正常规则适用:触发器和接收器必须兼容(相同的数据类型和相同的同步/异步颜色),才能发送/捕获彼此的脉冲。这就是为什么有多种类型的 ~trigger~receive 的原因。

节点 (Node) 描述 (Description)
~trigger 触发一个动态脉冲
~trigger<T> 触发一个带数据的动态脉冲
~receive 接收一个动态脉冲
~receive<T> 接收一个带数据的动态脉冲
~triggerAsync ~trigger 的异步版本
~triggerAsync<T> ~trigger<T> 的异步版本
~receiveAsync ~receive 的异步版本
~receiveAsync<T> ~receive<T> 的异步版本
// 发送一个带有数据载荷 1.6 的动态脉冲 // 类型参数可以被推断 TargetSlot->~trigger("SubRoutine1", 1.6); // 发送一个如上但无数据的动态脉冲 // 因此,即使它们具有相同的标签,它们也不会触发相同的动态脉冲 TargetSlot->~trigger("SubRoutine1"); // 要捕获动态脉冲,使用 switch switch ~receive<float>("SubRoutine1") | OnTriggered Receiver |> impulse { // 使用 Receiver.Value 获取值 _value: float = Receiver.Value; // 对 _value 执行某些操作... }; 

// 发送一个带有数据载荷 1.6 的动态脉冲。
// 类型参数可以被推断。
TargetSlot->~trigger("SubRoutine1", 1.6);

// 发送一个如上但无数据的动态脉冲。
// 因此,即使它们具有相同的标签,它们也不会触发相同的动态脉冲。
TargetSlot->~trigger("SubRoutine1");

// 要捕获动态脉冲,使用 switch。
switch ~receive<float>("SubRoutine1")
| OnTriggered Receiver |> 
    impulse {
        // 使用 Receiver.Value 获取值
        _value: float = Receiver.Value;
        // 对 _value 执行某些操作...
    };