126 lines
4.1 KiB
Tcl
126 lines
4.1 KiB
Tcl
# TODO Maybe add ::event::onstart and ::event::onfinish commands to execute some
|
|
# code when an object starts or finishes
|
|
# eg
|
|
# onstart hmm { do something }
|
|
|
|
namespace eval event {
|
|
variable sobjBusy
|
|
variable END_EVENT
|
|
|
|
set sobjBusy 0
|
|
array set END_EVENT {Motor MOTEND HistMem COUNTEND SingleCounter COUNTEND}
|
|
namespace export waitfor
|
|
}
|
|
|
|
proc ::event::waitCB {args} {
|
|
variable sobjBusy
|
|
set sobjBusy 0
|
|
}
|
|
publish ::event::waitCB user
|
|
|
|
##
|
|
# @brief Wait for a sics object to finish what it's doing.
|
|
# waitfor hmm {histmem start}
|
|
# waitfor {samx samz} {run samx 3 samz 4}
|
|
proc ::event::waitfor {sobj args} {
|
|
variable END_EVENT
|
|
variable sobjBusy
|
|
|
|
if [ catch {
|
|
set valid_sobjType [array names END_EVENT]
|
|
set sobjType [SplitReply [sicslist $sobj type] ]
|
|
if {[lsearch $valid_sobjType $sobjType ] == -1} {
|
|
error "ERROR: You can only wait for the following types of objects $valid_sobjType"
|
|
}
|
|
set CBID [SplitReply [scriptcallback connect $sobj $END_EVENT($sobjType) ::event::waitCB ] ]
|
|
set sobjBusy 1
|
|
set oldStatus [lindex [SplitReply [status]] 0]
|
|
eval $args
|
|
while {$sobjBusy == 1} {
|
|
wait 1
|
|
}
|
|
scriptcallback remove $sobj $CBID
|
|
SetStatus $oldStatus
|
|
} message ] {
|
|
scriptcallback remove $sobj $CBID
|
|
SetStatus $oldStatus
|
|
if {$::errorCode=="NONE"} {return "Return: $message"}
|
|
return -code error "Caught $message"
|
|
}
|
|
}
|
|
|
|
namespace import ::event::waitfor
|
|
|
|
publish waitfor user
|
|
|
|
namespace eval ::batch::call_cleanup { }
|
|
proc ::batch::cleanup {} {}
|
|
##
|
|
# @brief Calls a user defined cleanup script when a batch file ends or is aborted
|
|
# The cleanup script must be called ::batch::call_cleanup
|
|
proc ::batch::call_cleanup {} {
|
|
::batch::cleanup
|
|
proc ::batch::cleanup {} {}
|
|
}
|
|
publish ::batch::call_cleanup user
|
|
scriptcallback connect exe BATCHEND ::batch::call_cleanup
|
|
|
|
##
|
|
# @brief Call a command assigned to an hdb property when the given event occurs.
|
|
# This is meant to be called from the read command on an hdb node. It must be
|
|
# called everytime the node is polled so that the oneshot callback can be
|
|
# removed if the given event fails to occur within the allowed time.
|
|
# @param hpath hdb path to a node which regularly calls this procedure.
|
|
# @param event an event which may trigger a callback.
|
|
# @param args is a list of arguments which will be passed to the callback.
|
|
# @return state: -2 = fatal error, -1 = timer expired, 0 = callback triggered, 1 = waiting for event
|
|
# remaining before expiry.
|
|
proc call_oneshot {hpath event args} {
|
|
if [hpropexists $hpath oneshot_cb] {
|
|
set start_time [hgetpropval $hpath oneshot_start_time]
|
|
set timeout [hgetpropval $hpath oneshot_timeout]
|
|
set useby [expr {$start_time + $timeout}]
|
|
set currtime [hgetpropval $hpath read_time]
|
|
set trigger [hgetpropval $hpath oneshot_trigger]
|
|
|
|
if {$event == $trigger} {
|
|
set oneshot_cmd [hgetpropval $hpath oneshot_cb]
|
|
hdelprop $hpath oneshot_cb
|
|
hsetprop $hpath oneshot_state 0
|
|
eval "$oneshot_cmd $hpath $args"
|
|
return 0
|
|
} elseif {$event == "fatal_error"} {
|
|
hdelprop $hpath oneshot_cb
|
|
hsetprop $hpath oneshot_state -2
|
|
return -2
|
|
} elseif {$timeout >= 0} {
|
|
if {$currtime > $useby} {
|
|
hdelprop $hpath oneshot_cb
|
|
hsetprop $hpath oneshot_state -1
|
|
return -1
|
|
} else {
|
|
hsetprop $hpath oneshot_state 1
|
|
return 1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
##
|
|
# @brief Assign a oneshot callback to which is triggered by the given event.
|
|
#
|
|
# @param hpath hdb path to a node which regularly calls "call_oneshot"
|
|
# @param cb_proc name of the callback procedure
|
|
# @param trigger event for callback
|
|
# @param timeout the callback is removed when the timeout expires.
|
|
# If timeout = 0 the callback will only be called if the trigger event occurs
|
|
# the first time the node is polled. If timeout < 0 then the callback will be
|
|
# called if the trigger event occurs and then it is removed.
|
|
proc set_oneshot {hpath cb_proc event {timeout 60}} {
|
|
hsetprop $hpath oneshot_cb $cb_proc
|
|
hsetprop $hpath oneshot_timeout $timeout
|
|
hsetprop $hpath oneshot_start_time [hgetpropval $hpath read_time]
|
|
hsetprop $hpath oneshot_trigger $event
|
|
}
|
|
publish set_oneshot user
|