Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
113
Task/Active-object/Nim/active-object.nim
Normal file
113
Task/Active-object/Nim/active-object.nim
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# Active object.
|
||||
# Compile with "nim c --threads:on".
|
||||
|
||||
import locks
|
||||
import os
|
||||
import std/monotimes
|
||||
|
||||
type
|
||||
|
||||
# Function to use for integration.
|
||||
TimeFunction = proc (t: float): float {.gcsafe.}
|
||||
|
||||
# Integrator object.
|
||||
Integrator = ptr TIntegrator
|
||||
TIntegrator = object
|
||||
k: TimeFunction # The function to integrate.
|
||||
dt: int # Time interval in milliseconds.
|
||||
thread: Thread[Integrator] # Thread which does the computation.
|
||||
s: float # Computed value.
|
||||
lock: Lock # Lock to manage concurrent accesses.
|
||||
isRunning: bool # True if integrator is running.
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc newIntegrator(f: TimeFunction; dt: int): Integrator =
|
||||
## Create an integrator.
|
||||
|
||||
result = cast[Integrator](allocShared(sizeof(TIntegrator)))
|
||||
result.k = f
|
||||
result.dt = dt
|
||||
result.s = 0
|
||||
result.lock.initLock()
|
||||
result.isRunning = false
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc process(integrator: Integrator) {.thread, gcsafe.} =
|
||||
## Do the integration.
|
||||
|
||||
integrator.isRunning = true
|
||||
let start = getMonotime().ticks
|
||||
var t0: float = 0
|
||||
var k0 = integrator.k(0)
|
||||
while true:
|
||||
sleep(integrator.dt)
|
||||
withLock integrator.lock:
|
||||
if not integrator.isRunning:
|
||||
break
|
||||
let t1 = float(getMonoTime().ticks - start) / 1e9
|
||||
let k1 = integrator.k(t1)
|
||||
integrator.s += (k1 + k0) * (t1 - t0) / 2
|
||||
t0 = t1
|
||||
k0 = k1
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc start(integrator: Integrator) =
|
||||
## Start the integrator by launching a thread to do the computation.
|
||||
integrator.thread.createThread(process, integrator)
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc stop(integrator: Integrator) =
|
||||
## Stop the integrator.
|
||||
|
||||
withLock integrator.lock:
|
||||
integrator.isRunning = false
|
||||
integrator.thread.joinThread()
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc setInput(integrator: Integrator; f: TimeFunction) =
|
||||
## Set the function.
|
||||
withLock integrator.lock:
|
||||
integrator.k = f
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc output(integrator: Integrator): float =
|
||||
## Return the current output.
|
||||
withLock integrator.lock:
|
||||
result = integrator.s
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
proc destroy(integrator: Integrator) =
|
||||
## Destroy an integrator, freing the resources.
|
||||
|
||||
if integrator.isRunning:
|
||||
integrator.stop()
|
||||
integrator.lock.deinitLock()
|
||||
integrator.deallocShared()
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
from math import PI, sin
|
||||
|
||||
# Create the integrator and start it.
|
||||
let integrator = newIntegrator(proc (t: float): float {.gcsafe.} = sin(PI * t), 1)
|
||||
integrator.start()
|
||||
echo "Integrator started."
|
||||
sleep(2000)
|
||||
echo "Value after 2 seconds: ", integrator.output()
|
||||
|
||||
# Change the function to use.
|
||||
integrator.setInput(proc (t: float): float {.gcsafe.} = 0)
|
||||
echo "K function changed."
|
||||
sleep(500)
|
||||
|
||||
# Stop the integrator and display the computed value.
|
||||
integrator.stop()
|
||||
echo "Value after 0.5 more second: ", integrator.output()
|
||||
integrator.destroy()
|
||||
Loading…
Add table
Add a link
Reference in a new issue