How to resolve the algorithm Active object step by step in the OxygenBasic programming language
How to resolve the algorithm Active object step by step in the OxygenBasic programming language
Table of Contents
Problem Statement
In object-oriented programming an object is active when its state depends on clock. Usually an active object encapsulates a task that updates the object's state. To the outer world the object looks like a normal object with methods that can be called from outside. Implementation of such methods must have a certain synchronization mechanism with the encapsulated task in order to prevent object's state corruption. A typical instance of an active object is an animation widget. The widget state changes with the time, while as an object it has all properties of a normal widget. The task Implement an active integrator object. The object has an input and output. The input can be set using the method Input. The input is a function of time. The output can be queried using the method Output. The object integrates its input over the time and the result becomes the object's output. So if the input is K(t) and the output is S, the object state S is changed to S + (K(t1) + K(t0)) * (t1 - t0) / 2, i.e. it integrates K using the trapeze method. Initially K is constant 0 and S is 0. In order to test the object: Verify that now the object's output is approximately 0 (the sine has the period of 2s). The accuracy of the result will depend on the OS scheduler time slicing and the accuracy of the clock.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Active object step by step in the OxygenBasic programming language
Source code in the oxygenbasic programming language
double MainTime
'===============
class RingMaster
'===============
'
indexbase 1
sys List[512] 'limit of 512 objects per ringmaster
sys max,acts
'
method Register(sys meth,obj) as sys
sys i
for i=1 to max step 2
if list[i]=0 then exit for 'vacant slot
next
if i>=max then max+=2
List[i]<=meth,obj
return i 'token for deregistration etc
end method
'
method Deregister(sys *i)
if i then List[i]<=0,0 : i=0
end method
'
method Clear()
max=0
end method
'
method Act() 'called by the timer
sys i,q
for i=1 to max step 2
q=List[i]
if q then
call q List[i+1] 'anon object
end if
next
acts++
end method
'
end class
'=================
class ActiveObject
'=================
'
double s,freq,t1,t2,v1,v2
sys nfun,acts,RingToken
RingMaster *Master
'
method fun0() as double
end method
'
method fun1() as double
return sin(2*pi()*freq*MainTime)
end method
'
method func() as double
select case nfun
case 0 : return fun0()
case 1 : return fun1()
end select
'error?
end method
'
method TimeBasedDuties()
t1=t2
v1=v2
t2=MainTime
v2=func
s=s+(v2+v1)*(t2-t1)*0.5 'add slice to integral
acts++
end method
'
method RegisterWith(RingMaster*r)
@Master=@r
if @Master then
RingToken=Master.register @TimeBasedDuties,@this
end if
end method
'
method Deregister()
if @Master then
Master.Deregister RingToken 'this is set to null
end if
end method
'
method Output() as double
return s
end method
'
method Input(double fr=0,fun=0)
if fr then freq=fr
nfun=fun
end method
method ClearIntegral()
s=0
end method
'
end class
'SETUP TIMING SYSTEM
'===================
extern library "kernel32.dll"
declare QueryPerformanceCounter (quad*c)
declare QueryPerformanceFrequency(quad*f)
declare Sleep(sys milliseconds)
end extern
'
quad scount,tcount,freq
QueryPerformanceFrequency freq
double tscale=1/freq
double t1,t2
QueryPerformanceCounter scount
macro PrecisionTime(time)
QueryPerformanceCounter tcount
time=(tcount-scount)*tscale
end macro
'====
'TEST
'====
double integral
double tevent1,tevent2
RingMaster Rudolpho
ActiveObject A
'
A.RegisterWith Rudolpho
A.input (fr=0.5, fun=1) 'start with the freqency function (1)
'
'SET EVENT TIMES
'===============
tEvent1=2.0 'seconds
tEvent2=2.5 'seconds
'
PrecisionTime t1 'mark initial time
MainTime=t1
'
'
'EVENT LOOP
'==========
'
do
PrecisionTime t2
MainTime=t2
if t2-t1>=0.020 'seconds interval
Rudolpho.Act 'service all active objects
t1=t2
end if
'
if tEvent1>=0 and MainTime>=tEvent1
A.input (fun=0) 'switch to null function (0)
tEvent1=-1 'disable this event from happening again
end if
if MainTime>=tEvent2
integral=A.output()
exit do 'end of session
end if
'
sleep 5 'hand control to OS for a while
end do
print str(integral,4)
Rudolpho.clear
You may also check:How to resolve the algorithm Abundant, deficient and perfect number classifications step by step in the Racket programming language
You may also check:How to resolve the algorithm Arrays step by step in the ChucK programming language
You may also check:How to resolve the algorithm Semiprime step by step in the Tcl programming language
You may also check:How to resolve the algorithm Idiomatically determine all the characters that can be used for symbols step by step in the Phix programming language
You may also check:How to resolve the algorithm Random number generator (included) step by step in the PureBasic programming language