ColdFrame: Scripting Callbacks

ColdFrame.Callbacks.Scripting provides the generic

generic
   Callback_Type_Name : String;
   with function Value (S : String) return T is <>;
package ColdFrame.Callbacks.Scripting

which creates a Tcl command callback-<callback_type_name> (lowercased) which takes one argument: the value to be provided.

The callback is made at execution time.

As an example,

with ColdFrame.Callbacks.Scripting;
with Digital_IO.Input_Signal_State_Callback;
package body Digital_IO.Scripting is

   function Input_Signal_State_Value (S : String) return Input_Signal_State;

   package Input_Signal_State_Callback
     is new Digital_IO.Input_Signal_State_Callback.Scripting
       (Callback_Type_Name => "digital_io.input_signal_state",
        Value              => Input_Signal_State_Value);

allows you to write

callback-digital_io.input_signal_state {0 true}

The function Input_Signal_State_Value is interesting because Input_Signal_State is a 2-component record,

type Input_Signal_State is record
   S : Input_Signal;
   State : Boolean;
end record;

The Tcl list {0 true} above is presented by the instantiation of ColdFrame.Callbacks.Scripting as the string "0 true", which can be parsed as in

function Input_Signal_State_Value (S : String) return Input_Signal_State
is
   Tokens : GNAT.String_Split.Slice_Set;
begin
   GNAT.String_Split.Create (S          => Tokens,
                             From       => S,
                             Separators => " " & ASCII.HT,
                             Mode       => GNAT.String_Split.Multiple);
   if Natural (GNAT.String_Split.Slice_Count (Tokens)) /= 2 then
      raise Constraint_Error
        with "digital_io.input_signal_state requires 2 components";
   end if;
   return Result : Input_Signal_State do
      Result.S :=
        Input_Signal'Value (GNAT.String_Split.Slice
                              (Tokens,
                               GNAT.String_Split.Slice_Number (1)));
      Result.State :=
        Boolean'Value (GNAT.String_Split.Slice
                         (Tokens,
                          GNAT.String_Split.Slice_Number (2)));
   end return;
end Input_Signal_State_Value;