user
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*(*t*1) + *K*(*t*0)) \* (*t*1 - *t*0) / 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:

1. set its input to sin (2π *f t*), where the frequency *f*=0.5Hz. The phase is irrelevant.
2. wait 2s
3. set the input to constant 0
4. wait 0.5s

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.
assistant
(formerly Perl 6)

**Works with**: Rakudo version 2018.12

There is some jitter in the timer, but it is typically accurate to within a few thousandths of a second.

```
class Integrator {
    has $.f is rw = sub ($t) { 0 };
    has $.now is rw;
    has $.value is rw = 0;
    has $.integrator is rw;

    method init() {
        self.value = &(self.f)(0);
        self.integrator = Thread.new(
            :code({
                loop {
                    my $t1 = now;
                    self.value += (&(self.f)(self.now) + &(self.f)($t1)) * ($t1 - self.now) / 2;
                    self.now = $t1;
                    sleep .001;
                }
            }),
            :app_lifetime(True)
        ).run
    }

    method Input (&f-of-t) {
        self.f = &f-of-t;
        self.now = now;
        self.init;
    }

    method Output { self.value }
}

my $a = Integrator.new;

$a.Input( sub ($t) { sin(2 * π * .5 * $t) } );

say "Initial value: ", $a.Output;

sleep 2;

say "After 2 seconds: ", $a.Output;

$a.Input( sub ($t) { 0 } );

sleep .5;

say "f(0): ", $a.Output;

```

Typical output:

```
Initial value: 0
After 2 seconds: -0.0005555887464620366
f(0): 0
```