local env = {
nextEvent = function ()
return 'dt', 5
end
}
local gvt = require 'Module:luagravity'
local expr = require 'Module:luagravity/expr'
local meta = require 'Module:luagravity/meta'
--local env = require 'luagravity.env.simple'
local p = {}
function p.multi (frame)
local a = 0
local A = gvt.loop(env.nextEvent,
function ()
a = a + 1
gvt.await(0)
a = a + 1
end)
assert(a == 2)
local B = gvt.loop(env.nextEvent,
function ()
a = a + 1
gvt.await(0)
a = a + 1
end)
assert(a == 4)
local b, c = 0, 0
local B = gvt.start(
function ()
b = b + 1
gvt.await('x')
b = b + 1
end)
local C = gvt.start(
function ()
c = c + 1
gvt.await('x')
c = c + 1
end)
assert(b == 1)
assert(c == 1)
gvt.step(B, 'x')
assert(b == 2)
assert(c == 1)
gvt.step(C, 'x')
assert(b == 2)
assert(c == 2)
return '===> OK'
end
local type, assert = type, assert
function p.meta (frame)
gvt.loop(env.nextEvent, meta.apply(
function ()
-- REACTORS
local tot = 1
function f1 (v) end
function _f2 (v) tot=tot+1 end
function __f3 (v) await(_f4) tot=tot*2 end
function _f4 (v) tot=tot+1 end
assert(type(f1) == 'function')
assert(_f2.zero == true)
assert(__f3.zero == false)
link(_f2, __f3)
_f2()
assert(tot == 2)
_f4()
assert(tot == 6)
spawn(__f3)
await(0)
_f4()
assert(tot == 14, tot)
unlink(_f2, __f3)
_f2()
assert(tot == 15)
-- meta.new
do
local t = meta.new{1,2,3,_a=1}
assert(t._a() == 1)
assert(meta.len(t) == 3)
local len = 0
for k,v in meta.pairs(t) do len
= len+1 end
assert(len == 4)
local t2 = meta.new(nil, t, false)
assert(t2[2] == 2)
t._a = 1
assert(t2._a() == 1)
t._a = 2
assert(t2._a() == 2)
end
-- BEHAVIORS
_a = 1
_b = 2
_c = _a + _b
assert(_c() == 3)
_a = 3
_b = 4
assert(_c() == 7)
_v1 = 1
_v2 = 2
_v2 = _v1
_v1 = 3
assert((_v1() == 3) and (_v2() == 3))
-- LIFT
local fadd = function (a, b) return a+b end
local ladd = L(fadd)
_v3 = ladd(_v1, _v2)
_v4 = ladd(_v1, 2)
_v1 = 5
assert((_v1() == 5) and (_v2() == 5) and
(_v3() == 10) and (_v4() ==7))
local fnear = function (cur, exp)
return assert((cur >= exp*0.90) and (cur <= exp*1.10),
exp..' vs '..cur)
end
local lnear = L(fnear)
local fequal = function (v1, v2)
return assert(v1 == v2)
end
local lequal = L(fequal)
local flt = function (v1, v2)
return assert(v1 < v2)
end
local llt = L(flt)
--[[
-- IDX
do
_k1 = 1
local t1 = { 1, 2 }
local _v1 = IDX(t1, _k1)
assert(_v1() == 1)
_k1 = 2
assert(_v1() == 2)
_k2 = 1
local t2 = { 1, _v1 }
local _v2 = IDX(t2, _k2)
assert(_v2() == 1)
_k2 = 2
assert(_v2()() == 2)
_k1 = 1
assert(_v2()() == 1)
end
]]
-- GLITCHES
_x = 1
local xx
local x1 = _x
for i=1, 50 do
local x2 = x1 + 1
llt(x1, x2)
x1 = x2
xx = x2
end
for i=1, 50 do
_x = i
end
assert(xx() == 100, xx())
-- VAR
_v5 = 1
_v6 = 2
_v6 = _v5
assert(_v6() == _v5())
_v5 = _v4
assert(_v5() == _v4() and _v6() == 7)
_v1 = 10
assert(_v5() == _v4() and _v6() == 12)
local fadd = function (a, b) return a+b end
local ladd = L(fadd)
_v3 = ladd(_v1, _v2)
local _v4 = ladd(_v1, 2)
_v1 = 5
assert((_v1() == 5) and (_v2() == 5) and
(_v3() == 10) and (_v4() ==7))
--[[local]] _v5 = expr.var(1)
--[[local]] _v6 = expr.var(2)
_v6:attr(_v5)
assert(_v6() == _v5())
_v5:attr(_v4)
assert(_v5() == _v4() and _v6() == 7)
_v1 = 10
assert(_v5() == _v4() and _v6() == 12)
-- INTEGRAL / DERIVATIVE
local s = gvt.S(3) -- corrected for Traditio
local ss = gvt.S(3) -- corrected for Traditio
lequal(s, ss)
await(500)
fnear(s(), 1500)
local s1 = s + 1
llt(s, s1)
local d1 = D(s1)
local d2 = D(10000)
await(100) -- para ter derivada
await(100) -- para ter derivada
await(100) -- para ter derivada
lnear(d1, 3)
lequal(d2, 0)
await(1200)
fnear(s(), 6000)
-- OO
local t = meta.new({}, nil, true)
t.v = 3
function t:_inc (v)
self.v = self.v + (v or 1)
end
function t:_double ()
self.v = self.v * 2
end
link(t._inc, t._double)
t:_inc()
assert(t.v == 8)
t._inc(2)
assert(t.v == 20)
local _s = gvt.S(10) -- corrected for Traditio
local _d = D(_s)
await(5000)
await(0)
assert(_s() >= 50000 and _s() <= 51000)
assert(_d() == 10)
-- COND
local lt = expr.lift(function(a,b) return a < b end)
local x = false
local s = gvt.S(1) -- corrected for Traditio
gvt.spawn(function()
gvt.await(500)
x = true
end)
gvt.await(cond(lt(1000,s)))
assert(x)
-- ACCUM
_a = 1
_b = 2
_c = 3
local t = { _a, _b, _c }
_all = 0
for i, _v in ipairs(t) do
_all = _all.src + _v
end
assert(_all() == 6)
_a = 2
_b = 4
assert(_all() == 9)
end))
return '===> OK'
end
function p.test1 (frame)
local _start, _stop = 0, 0
local f_start = function(v)
v = v or 0
_start = _start + 1
return v + 1
end
start = gvt.create(f_start, {name='start',zero=true})
local f_stop = function(v)
v = v or 0
_stop = _stop + 1
return v + 1
end
stop = gvt.create(f_stop, {name='stop',zero=true})
gvt.loop(env.nextEvent,
function ()
-- Reacoes
gvt.call(start)
gvt.call(stop)
gvt.call(start)
gvt.call(stop)
assert((_start==2) and (_stop==2))
local rm = gvt.link(start, stop)
gvt.call(start)
assert((_start==3) and (_stop==3), _stop)
-- Quebra de elo "explicita"
gvt.unlink(start, stop)
gvt.call(start)
assert((_start==4) and (_stop==3))
gvt.link(start, stop)
gvt.link(stop, function (v)
assert(v == 3, v)
end)
gvt.call(start, 1)
assert((_start==5) and (_stop==4))
-- STRINGS
gvt.link('start', f_start)
gvt.link('stop', f_stop)
gvt.post('start', 1)
gvt.post('stop', 1)
gvt.post('start', 1)
gvt.post('stop', 1)
assert((_start==7) and (_stop==6))
end)
return '===> OK'
end
function p.test2 (frame)
-- testing if `s_f1()` call is synchronous
local _ret
f1 = gvt.create(function()
gvt.await(10)
_ret = true
end)
f = gvt.create(function()end)
gvt.loop(env.nextEvent,
function ()
gvt.spawn(function()
gvt.call(f1)
assert(_ret == true)
end)
-- testing if one call to `f` awakes exactly one `gvt.await(f)`
local _fs = 0
gvt.spawn(function()
gvt.await(f)
_fs = _fs + 1
gvt.await(f)
_fs = _fs + 1
gvt.await(f)
_fs = _fs + 1
end)
gvt.await(0)
gvt.call(f)
gvt.call(f)
assert(_fs == 2, _fs)
-- testing reaction nesting
local _ret = {}
gvt.spawn(function()
-- it is finished before `_ret[1]=true`
local r = gvt.spawn(function()
gvt.await(10)
_ret[1] = true
end)
-- it is not finished
gvt.spawn(function()
gvt.await(10)
_ret[2] = true
end)
gvt.await(0)
gvt.kill(r)
end)
gvt.await(20)
assert(not _ret[1])
assert(_ret[2])
end)
-- testing inner reaction terminating outer reaction
--[[
g = function () end
gvt.spawn(function()
gvt.spawn(function()
gvt.await(0)
g()
gvt.await(0)
error'oi'
end)
gvt.await(g)
end)
gvt.await(0.1)
]]
return '===> OK'
end
function p.activate (frame)
local state
local app = gvt.start(function()
state = 0
gvt.await(10)
state = 1
gvt.await(10)
state = 2
end)
assert(state == 0)
gvt.step(app, 'dt', 10)
gvt.step(app, 'dt', 0)
assert(state == 1)
gvt.deactivate(app)
gvt.step(app, 'dt', 10)
gvt.step(app, 'dt', 0)
assert(state == 1)
gvt.step(app, 'dt', 10)
gvt.step(app, 'dt', 0)
assert(state == 1)
gvt.reactivate(app)
gvt.step(app, 'dt', 10)
gvt.step(app, 'dt', 0)
assert(state == 2, state)
return '===> OK'
end
function p.call (frame)
gvt.loop(env.nextEvent,
function ()
local tot = 0
local r = gvt.create(function() gvt.await(0.2) end)
local a = gvt.create(function() tot=tot+1 gvt.await(0) end)
local b = gvt.create(function() tot=tot+1 gvt.await(0) end)
local c = gvt.create(function() tot=tot+1 gvt.await(0) end)
local d = gvt.create(function() tot=tot+1 gvt.await(0) end)
local e = gvt.create(function() tot=tot+1 gvt.await(0) end)
local f = gvt.create(function() tot=tot+1 gvt.await(0) end)
local g = gvt.create(function() tot=tot+1 gvt.await(0) end)
local h = gvt.create(function() tot=tot+1 gvt.await(0) end)
local i = gvt.create(function() tot=tot+1 gvt.await(0) end)
gvt.link(r, a)
gvt.link(r, b)
gvt.link(r, c)
gvt.link(r, d)
gvt.link(r, e)
gvt.link(r, f)
gvt.link(r, g)
gvt.link(r, h)
gvt.link(r, i)
gvt.call(r)
assert(tot == 9, tot)
end)
return '===> OK'
end
function p.cycle (frame)
gvt.loop(env.nextEvent,
function ()
-- Testing timer accuracy
local tot = 0
local f = gvt.create(
function ()
tot = tot + 1
gvt.await(30)
end)
gvt.link(f, f)
gvt.spawn(f)
gvt.await(100)
assert(tot == 4, tot)
-- tight cycle
local a = gvt.create(function()end, {zero=true})
local b = gvt.create(function()end, {zero=true})
gvt.link(a, b)
local ret, msg = pcall(gvt.link, b, a)
assert((not ret) and string.match(msg, 'tight cycle detected'))
end)
return '===> OK'
end
function p.expr (frame)
local fnear = function (cur, exp)
return assert((cur >= exp*0.90) and (cur <= exp*1.10), cur)
end
local lnear = expr.lift(fnear)
local fequal = function (v1, v2)
return assert(v1 == v2)
end
local lequal = expr.lift(fequal)
local flt = function (v1, v2)
return assert(v1 < v2)
end
local llt = expr.lift(flt)
local app = function ()
local v1 = expr.new(1)
local v2 = expr.new(2)
gvt.link(v1._set, v2._set)
gvt.call(v1._set, 3)
assert((v1.value == 3) and (v2.value == 3))
local tot = 0
local a = expr.new(1)
gvt.link(a._set, function () tot = tot+1 end)
assert((tot == 0) and (a.value == 1), tot)
gvt.call(a._set, 2)
gvt.call(a._set, 2) -- CANCEL
assert(a.value == 2)
assert(tot == 1, tot)
local b = expr.new(0)
gvt.link(b._set, function () tot = tot+1 end)
assert(tot == 1)
gvt.link(a._set, b._set)
gvt.call(a._set, 3)
gvt.call(a._set, 3) -- CANCEL
assert(tot == 3, tot)
assert((a.value==3) and (b.value==3))
gvt.unlink(a._set, b._set)
gvt.call(a._set, 4)
assert(tot == 4)
assert((a.value==4) and (b.value==3))
-- LIFT
local fadd = function (a, b) return a+b end
local ladd = expr.lift(fadd)
local v3 = ladd(v1, v2)
local v4 = ladd(v1, 2)
gvt.call(v1._set, 5)
assert((v1.value == 5) and (v2.value == 5) and
(v3.value == 10) and (v4.value ==7))
-- GLITCHES
local x = expr.var(1)
local xx
local x1 = x
for i=1, 50 do
local x2 = ladd(x1, 1)
llt(x1, x2)
x1 = x2
xx = x2
end
for i=1, 50 do
gvt.call(x._set, i)
end
assert(xx.value == 100, xx.value)
-- VAR
local v5 = expr.var(1)
local v6 = expr.var(2)
v6:attr(v5)
assert(v6.value == v5.value)
v5:attr(v4)
assert(v5.value == v4.value and v6.value == 7)
gvt.call(v1._set, 10)
assert(v5.value == v4.value and v6.value == 12)
local fadd = function (a, b) return a+b end
local ladd = expr.lift(fadd)
local v3 = ladd(v1, v2)
local v4 = ladd(v1, 2)
gvt.call(v1._set, 5)
assert((v1.value == 5) and (v2.value == 5) and
(v3.value == 10) and (v4.value ==7))
local v5 = expr.var(1)
local v6 = expr.var(2)
v6:attr(v5)
assert(v6.value == v5.value)
v5:attr(v4)
assert(v5.value == v4.value and v6.value == 7)
gvt.call(v1._set, 10)
assert(v5.value == v4.value and v6.value == 12)
v6:attr(10)
gvt.call(v5._set, 1)
assert(v5.value==1 and v6.value==10)
-- INTEGRAL / DERIVATIVE
local s = expr.integral(3)
local ss = expr.integral(3)
lequal(s, ss)
gvt.await(500)
fnear(s.value, 1500)
local s1 = ladd(s, 1)
llt(s, s1)
local d1 = expr.derivative(s1)
local d2 = expr.derivative(10000)
gvt.await(0) -- para ter derivada
gvt.await(0) -- para ter derivada
gvt.await(0) -- para ter derivada
lnear(d1, 3)
lequal(d2, 0)
gvt.await(1500)
fnear(s.value, 6000)
-- DELAY
local a = expr.new(0)
local d = expr.delay(a, 250)
local b = expr.var()
b:attr(d)
gvt.await(100)
gvt.call(a._set, 1)
gvt.call(a._set, 2)
assert(d.value == nil)
assert(b.value == nil)
gvt.await(200)
assert(d.value == 0, d.value)
assert(b.value == 0)
gvt.await(100)
assert(d.value == 2, d.value)
assert(b.value == 2)
-- COND
local lt = expr.lift(function(a,b) return a < b end)
local x = false
local s = expr.integral(1)
gvt.spawn(function()
gvt.await(500)
x = true
end)
gvt.await(expr.condition(lt(1000,s))._true)
assert(x)
end
gvt.loop(env.nextEvent, app)
return '===> OK'
end
function p.height (frame)
gvt.loop(env.nextEvent,
function ()
local zero = gvt.create(function()end, {zero=true})
local ret, msg = pcall(gvt.link, zero, zero)
assert((not ret) and string.match(msg, 'tight cycle detected'))
local tot = 0
local a = gvt.create(function() return 'o' end, {zero=true})
local b = gvt.create(function() return 22 end, {zero=true})
local c = gvt.create(
function (p1)
-- TODO: se der erro, testar o inverso (OU)
assert(p1 == 22)
tot = tot + 1
end, {zero=true})
gvt.link(a, b)
gvt.link(a, c)
gvt.link(b, c)
gvt.call(a)
assert(tot == 1)
local x = gvt.create(function () return nil end, {zero=true})
local y = gvt.create(function () return false end, {zero=true})
gvt.link(a, x)
gvt.link(a, y)
local d = gvt.create(
function ()
local ret = gvt.await(x, y)
assert(ret==nil or ret==false)
end)
gvt.spawn(d)
gvt.await(0)
gvt.call(a)
--[[
-- a1 --> s_a2 ==> a1
local a1 = gvt.create('a1',nil,true,function()end)
local a2 = gvt.create('a2',nil,false,function() gvt.await(a1) end)
gvt.spawn(a2)
gvt.await(0)
local ret, msg = pcall(gvt.link,a2, a1)
assert((not ret) and string.match(msg, 'tight cycle detected'))
]]
-- b2 --> s_b1 ==> s_b1
local b2 = gvt.create(function()end, {zero=true})
local b1 = gvt.create(function() gvt.await(b2) end)
gvt.spawn(b1)
gvt.link(b1, b1)
gvt.await(0)
gvt.call(b2)
-- bb2 --> s_bb1 ==> s_bb1
local bb2 = gvt.create(function()end, {zero=true})
local bb1 = gvt.create(function() gvt.await(bb2) end)
gvt.link(bb1, bb1) -- diferenca em relacao ao anterior
gvt.spawn(bb1) -- diferenca em relacao ao anterior
gvt.await(0)
gvt.call(bb2)
--[[
local f1 = gvt.create('f1',nil,false,function() gvt.await(x) end)
local f2 = gvt.create('f2',nil,true,function()end)
gvt.link(f1, f2)
assert(f1.heightOut < f2.heightIn)
gvt.link(f2, f1)
assert(f1.heightIn > f2.heightOut)
]]
-- s_1 <-- x1
-- s_2 <-- x2
-- s_1 ==> s_2
-- s_2 ==> x1
local t1, t2 = 0, 0
local x1 = gvt.create(function()end, {zero=true})
local x2 = gvt.create(function()end, {zero=true})
local z1 = gvt.create(function() gvt.await(x1) t1=t1+1 end)
local z2 = gvt.create(function() gvt.await(x2) t2=t2+1 end)
gvt.link(z1, z2)
gvt.link(z2, x1)
for i=0, 10 do
gvt.spawn(z1)
gvt.await(0)
assert(t1 == i)
assert(t2 == i)
gvt.call(x1)
assert(t1 == i+1)
assert(t2 == i)
gvt.call(x2)
assert(t1 == i+1)
assert(t2 == i+1)
end
end)
return '===> OK'
end
return p