Active object: Difference between revisions

add crystal solution
m (→‎{{header|Phix}}: added to Phix/Class)
(add crystal solution)
Line 414:
1.414065859052494E-5
</lang>
 
=={{header|Crystal}}==
{{trans|Python}}
<lang ruby>require "math"
require "time"
 
class Integrator
property interval : Float64
getter s : Float64 = 0f64
 
# initialize our k function as a proc that takes a float
# and just returns 0 (as a 64-bit float)
property k : Proc(Float64, Float64) = ->(t : Float64) { 0f64 }
 
def initialize(@k, @interval = 1e-4)
# use a monotonic clock for accuracy
start = Time.monotonic.total_seconds
t0, k0 = 0f64, @k.call(0f64)
 
# spawn creates a new fiber.
# since the fiber immediately sleeps, control is returned to the main code.
# the main code then sleeps for two seconds, returning control to our state_clock fiber.
# when two seconds is up, this state_clock fiber will return control
# to the main code on the next `sleep interval.seconds`
spawn name: "state_clock" do
loop do
sleep interval.seconds
t1 = Time.monotonic.total_seconds - start
k1 = @k.call(t1)
@s += (k1 + k0) * (t1 - t0) / 2.0
t0, k0 = t1, k1
end
end
end
end
 
ai = Integrator.new ->(t : Float64) { Math.sin(Math::PI * t) }
sleep 2.seconds
ai.k = ->(t : Float64) { 0f64 }
sleep 0.5.seconds
puts ai.s
</lang>
 
Note: when <code>put</code>ting <code>ai.s</code> twice (once after the first sleep, another after the second) like in the Python solution, two slightly different values will be printed since Crystal's fibers work differently than Python's threads
 
Output:
<pre>
2.1379517395755217e-6
</pre>
 
=={{header|D}}==
Anonymous user