75 lines
1.8 KiB
Rexx
75 lines
1.8 KiB
Rexx
|
|
integrater = .integrater~new(.routines~sine) -- start the integrater function
|
||
|
|
call syssleep 2
|
||
|
|
integrater~input = .routines~zero -- update the integrater function
|
||
|
|
call syssleep .5
|
||
|
|
|
||
|
|
say integrater~output
|
||
|
|
integrater~stop -- terminate the updater thread
|
||
|
|
|
||
|
|
::class integrater
|
||
|
|
::method init
|
||
|
|
expose stopped start v last_v last_t k
|
||
|
|
use strict arg k
|
||
|
|
stopped = .false
|
||
|
|
start = .datetime~new -- initial time stamp
|
||
|
|
v = 0
|
||
|
|
last_v = 0
|
||
|
|
last_t = 0
|
||
|
|
self~input = k
|
||
|
|
self~start
|
||
|
|
|
||
|
|
-- spin off a new thread and start updating. Note, this method is unguarded
|
||
|
|
-- to allow other threads to make calls
|
||
|
|
::method start unguarded
|
||
|
|
expose stopped
|
||
|
|
|
||
|
|
reply -- this spins this method invocation off onto a new thread
|
||
|
|
|
||
|
|
do while \stopped
|
||
|
|
call sysSleep .1
|
||
|
|
self~update -- perform the update operation
|
||
|
|
end
|
||
|
|
|
||
|
|
-- turn off the thread. Since this is unguarded,
|
||
|
|
-- it can be called any time, any where
|
||
|
|
::method stop unguarded
|
||
|
|
expose stopped
|
||
|
|
stopped = .true
|
||
|
|
|
||
|
|
-- perform the update. Since this is a guarded method, the object
|
||
|
|
-- start is protected.
|
||
|
|
::method update
|
||
|
|
expose start v last_v t last_t k
|
||
|
|
|
||
|
|
numeric digits 20 -- give a lot of precision
|
||
|
|
|
||
|
|
current = .datetime~new
|
||
|
|
t = (current - start)~microseconds
|
||
|
|
new_v = k~call(t) -- call the input function
|
||
|
|
v += (last_v + new_v) * (t - last_t) / 2
|
||
|
|
last_t = t
|
||
|
|
last_v = new_v
|
||
|
|
say new value is v
|
||
|
|
|
||
|
|
-- a write-only attribute setter (this is GUARDED)
|
||
|
|
::attribute input SET
|
||
|
|
expose k last_t last_v
|
||
|
|
self~update -- update current values
|
||
|
|
use strict arg k -- update the call function to the provided value
|
||
|
|
last_t = 0
|
||
|
|
last_v = k~call(0) -- and update to the zero value
|
||
|
|
|
||
|
|
-- the output function...returns current calculated value
|
||
|
|
::attribute output GET
|
||
|
|
expose v
|
||
|
|
return v
|
||
|
|
|
||
|
|
::routine zero
|
||
|
|
return 0
|
||
|
|
|
||
|
|
::routine sine
|
||
|
|
use arg t
|
||
|
|
return rxcalcsin(rxcalcpi() * t)
|
||
|
|
|
||
|
|
::requires rxmath library
|