How to resolve the algorithm Active object step by step in the OxygenBasic programming language

Published on 12 May 2024 09:40 PM

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