This commit is contained in:
Ingy döt Net 2013-06-05 21:47:54 +00:00
parent 1f1ad49427
commit 6f050a029e
2496 changed files with 37609 additions and 3031 deletions

View file

@ -0,0 +1,62 @@
-module( active_object ).
-export( [delete/1, input/2, new/0, output/1, task/1] ).
-compile({no_auto_import,[time/0]}).
delete( Object ) ->
Object ! stop.
input( Object, Fun ) ->
Object ! {input, Fun}.
new( ) ->
K = fun zero/1,
S = 0,
T0 = seconds_with_decimals(),
erlang:spawn( fun() -> loop(K, S, T0) end ).
output( Object ) ->
Object ! {output, erlang:self()},
receive
{output, Object, Output} -> Output
end.
task( Integrate_millisec ) ->
Object = new(),
{ok, _Ref} = timer:send_interval( Integrate_millisec, Object, integrate ),
io:fwrite( "New ~p~n", [output(Object)] ),
input( Object, fun sine/1 ),
timer:sleep( 2000 ),
io:fwrite( "Sine ~p~n", [output(Object)] ),
input( Object, fun zero/1 ),
timer:sleep( 500 ),
io:fwrite( "Approx ~p~n", [output(Object)] ),
delete( Object ).
loop( Fun, Sum, T0 ) ->
receive
integrate ->
T1 = seconds_with_decimals(),
New_sum = trapeze( Sum, Fun, T0, T1 ),
loop( Fun, New_sum, T1 );
stop ->
ok;
{input, New_fun} ->
loop( New_fun, Sum, T0 );
{output, Pid} ->
Pid ! {output, erlang:self(), Sum},
loop( Fun, Sum, T0 )
end.
sine( T ) ->
math:sin( 2 * math:pi() * 0.5 * T ).
seconds_with_decimals() ->
{Megaseconds, Seconds, Microseconds} = os:timestamp(),
(Megaseconds * 1000000) + Seconds + (Microseconds / 1000000).
trapeze( Sum, Fun, T0, T1 ) ->
Sum + (Fun(T1) + Fun(T0)) * (T1 - T0) / 2.
zero( _ ) -> 0.

View file

@ -0,0 +1,94 @@
#APPTYPE CONSOLE
#INCLUDE <Include\Windows.inc>
DIM Entity AS NEW Integrator(): Sleep(2000) ' respawn and do the job
Entity.Relax(): Sleep(500) ' get some rest
PRINT ">>> ", Entity.Yield(): DELETE Entity ' report and die
PAUSE
' ------------- End Program Code -------------
#DEFINE SpawnMutex CreateMutex(NULL, FALSE, "mutex")
#DEFINE LockMutex WaitForSingleObject(mutex, INFINITE)
#DEFINE UnlockMutex ReleaseMutex(mutex)
#DEFINE KillMutex CloseHandle(mutex)
CLASS Integrator
PRIVATE:
TYPE LARGE_INTEGER
lowPart AS INTEGER
highPart AS INTEGER
END TYPE
DIM dfreq AS DOUBLE, dlast AS DOUBLE, dnow AS DOUBLE, llint AS LARGE_INTEGER
DIM dret0 AS DOUBLE, dret1 AS DOUBLE, mutex AS INTEGER, sum AS DOUBLE, thread AS INTEGER
' --------------------------------------------
SUB INITIALIZE()
mutex = SpawnMutex
QueryPerformanceFrequency(@llint)
dfreq = LargeInt2Double(llint)
QueryPerformanceCounter(@llint)
dlast = LargeInt2Double(llint) / dfreq
thread = FBSLTHREAD(ADDRESSOF Sampler)
FBSLTHREADRESUME(thread)
END SUB
SUB TERMINATE()
' nothing special
END SUB
' --------------------------------------------
SUB Sampler()
DO
LockMutex
Sleep(5)
QueryPerformanceCounter(@llint)
dnow = LargeInt2Double(llint) / dfreq
dret0 = Task(dlast): dret1 = Task(dnow)
sum = sum + (dret1 + dret0) * (dnow - dlast) / 2
dlast = dnow
UnlockMutex
LOOP
END SUB
FUNCTION LargeInt2Double(obj AS VARIANT) AS DOUBLE
STATIC ret
ret = obj.highPart
IF obj.highPart < 0 THEN ret = ret + (2 ^ 32)
ret = ret * 2 ^ 32
ret = ret + obj.lowPart
IF obj.lowPart < 0 THEN ret = ret + (2 ^ 32)
RETURN ret
END FUNCTION
PUBLIC:
METHOD Relax()
LockMutex
ADDRESSOF Task = ADDRESSOF Idle
UnlockMutex
END METHOD
METHOD Yield() AS DOUBLE
LockMutex
Yield = sum
FBSLTHREADKILL(thread)
UnlockMutex
KillMutex
END METHOD
END CLASS
FUNCTION Idle(BYVAL t AS DOUBLE) AS DOUBLE
RETURN 0.0
END FUNCTION
FUNCTION Task(BYVAL t AS DOUBLE) AS DOUBLE
RETURN SIN(2 * PI * 0.5 * t)
END FUNCTION