Merge branch 'master' of git://github.com/erg/factor into erg

db4
Slava Pestov 2010-06-22 01:05:13 -04:00
commit 0fa1a46d35
82 changed files with 938 additions and 467 deletions

View File

@ -1,74 +0,0 @@
USING: help.markup help.syntax calendar quotations system ;
IN: alarms
HELP: alarm
{ $class-description "An alarm. Can be passed to " { $link stop-alarm } "." } ;
HELP: start-alarm
{ $values { "alarm" alarm } }
{ $description "Starts an alarm." } ;
HELP: restart-alarm
{ $values { "alarm" alarm } }
{ $description "Starts or restarts an alarm. Restarting an alarm causes the a sleep of initial delay nanoseconds before looping. An alarm's parameters may be modified and restarted with this word." } ;
HELP: stop-alarm
{ $values { "alarm" alarm } }
{ $description "Prevents an alarm from calling its quotation again. Has no effect on alarms that are not currently running." } ;
HELP: every
{ $values
{ "quot" quotation } { "interval-duration" duration }
{ "alarm" alarm } }
{ $description "Creates an alarm that calls the quotation repeatedly, using " { $snippet "duration" } " as the frequency. The first call of " { $snippet "quot" } " will happen immediately. If the quotation throws an exception, the alarm will stop." }
{ $examples
{ $unchecked-example
"USING: alarms io calendar ;"
"""[ "Hi Buddy." print flush ] 10 seconds every drop"""
""
}
} ;
HELP: later
{ $values { "quot" quotation } { "delay-duration" duration } { "alarm" alarm } }
{ $description "Sleeps for " { $snippet "duration" } " and then calls a " { $snippet "quot" } ". The user may cancel the alarm before " { $snippet "quot" } " runs. This alarm is not repeated." }
{ $examples
{ $unchecked-example
"USING: alarms io calendar ;"
"""[ "Break's over!" print flush ] 15 minutes later drop"""
""
}
} ;
HELP: delayed-every
{ $values
{ "quot" quotation } { "duration" duration }
{ "alarm" alarm } }
{ $description "Creates an alarm that calls " { $snippet "quot" } " repeatedly, waiting " { $snippet "duration" } " before calling " { $snippet "quot" } " the first time and then waiting " { $snippet "duration" } " between further calls. If the quotation throws an exception, the alarm will stop." }
{ $examples
{ $unchecked-example
"USING: alarms io calendar ;"
"""[ "Hi Buddy." print flush ] 10 seconds every drop"""
""
}
} ;
ARTICLE: "alarms" "Alarms"
"The " { $vocab-link "alarms" } " vocabulary provides a lightweight way to schedule one-time and recurring tasks. Alarms run in a single green thread per alarm and consist of a quotation, a delay duration, and an interval duration. After starting an alarm, the alarm thread sleeps for the delay duration and calls the quotation. Then it waits out the interval duration and calls the quotation again until something stops the alarm. If a recurring alarm's quotation would be scheduled to run again before the previous quotation has finished processing, the alarm will be run again immediately afterwards. This may result in the alarm falling behind indefinitely, in which case the it will run as often as possible while still allowing other green threads to run. Recurring alarms that execute 'on time' or 'catch up' will always be scheduled for an exact multiple of the interval from the original starting time to prevent the alarm from drifting over time. Alarms use " { $link nano-count } " as the timing primitive, so they will continue to work across system clock changes." $nl
"The alarm class:"
{ $subsections alarm }
"Create an alarm before starting it:"
{ $subsections <alarm> }
"Starting an alarm:"
{ $subsections start-alarm restart-alarm }
"Stopping an alarm:"
{ $subsections stop-alarm }
"A recurring alarm without an initial delay:"
{ $subsections every }
"A one-time alarm with an initial delay:"
{ $subsections later }
"A recurring alarm with an initial delay:"
{ $subsections delayed-every } ;
ABOUT: "alarms"

View File

@ -1,119 +1,5 @@
! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman. ! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs calendar combinators.short-circuit fry USING: ;
heaps init kernel math math.functions math.parser namespaces
quotations sequences system threads ;
IN: alarms IN: alarms
TUPLE: alarm
{ quot callable initial: [ ] }
start-nanos
delay-nanos
interval-nanos
iteration-start-nanos
quotation-running?
restart?
thread ;
<PRIVATE
GENERIC: >nanoseconds ( obj -- duration/f )
M: f >nanoseconds ;
M: real >nanoseconds >integer ;
M: duration >nanoseconds duration>nanoseconds >integer ;
: set-next-alarm-time ( alarm -- alarm )
! start + delay + ceiling((now - (start + delay)) / interval) * interval
nano-count
over start-nanos>> -
over delay-nanos>> [ - ] when*
over interval-nanos>> / ceiling
over interval-nanos>> *
over start-nanos>> +
over delay-nanos>> [ + ] when*
>>iteration-start-nanos ;
: stop-alarm? ( alarm -- ? )
{ [ thread>> self eq? not ] [ restart?>> ] } 1|| ;
DEFER: call-alarm-loop
: loop-alarm ( alarm -- )
nano-count over
[ iteration-start-nanos>> - ] [ interval-nanos>> ] bi <
[ set-next-alarm-time ] dip
[ dup iteration-start-nanos>> ] [ 0 ] if
0 or sleep-until call-alarm-loop ;
: maybe-loop-alarm ( alarm -- )
dup { [ stop-alarm? ] [ interval-nanos>> not ] } 1||
[ drop ] [ loop-alarm ] if ;
: call-alarm-loop ( alarm -- )
dup stop-alarm? [
drop
] [
[
[ t >>quotation-running? drop ]
[ quot>> call( -- ) ]
[ f >>quotation-running? drop ] tri
] keep
maybe-loop-alarm
] if ;
: sleep-delay ( alarm -- )
dup stop-alarm? [
drop
] [
nano-count >>start-nanos
delay-nanos>> [ sleep ] when*
] if ;
: alarm-loop ( alarm -- )
[ sleep-delay ]
[ nano-count >>iteration-start-nanos call-alarm-loop ]
[ dup restart?>> [ f >>restart? alarm-loop ] [ drop ] if ] tri ;
PRIVATE>
: <alarm> ( quot delay-duration/f interval-duration/f -- alarm )
alarm new
swap >nanoseconds >>interval-nanos
swap >nanoseconds >>delay-nanos
swap >>quot ; inline
: start-alarm ( alarm -- )
[
'[ _ alarm-loop ] "Alarm execution" spawn
] keep thread<< ;
: stop-alarm ( alarm -- )
dup quotation-running?>> [
f >>thread drop
] [
[ [ interrupt ] when* f ] change-thread drop
] if ;
: restart-alarm ( alarm -- )
t >>restart?
dup quotation-running?>> [
drop
] [
dup thread>> [ nip interrupt ] [ start-alarm ] if*
] if ;
<PRIVATE
: (start-alarm) ( quot start-duration interval-duration -- alarm )
<alarm> [ start-alarm ] keep ;
PRIVATE>
: every ( quot interval-duration -- alarm )
[ f ] dip (start-alarm) ;
: later ( quot delay-duration -- alarm )
f (start-alarm) ;
: delayed-every ( quot duration -- alarm )
dup (start-alarm) ;

0
basis/alarms/authors.txt Executable file → Normal file
View File

View File

@ -1 +0,0 @@
One-time and recurring events

View File

@ -7,6 +7,8 @@ IN: calendar
HOOK: gmt-offset os ( -- hours minutes seconds ) HOOK: gmt-offset os ( -- hours minutes seconds )
HOOK: gmt os ( -- timestamp )
TUPLE: duration TUPLE: duration
{ year real } { year real }
{ month real } { month real }
@ -371,10 +373,6 @@ M: duration time-
: timestamp>micros ( timestamp -- n ) : timestamp>micros ( timestamp -- n )
unix-1970 (time-) 1000000 * >integer ; unix-1970 (time-) 1000000 * >integer ;
: gmt ( -- timestamp )
#! GMT time, right now
unix-1970 system-micros microseconds time+ ;
: now ( -- timestamp ) gmt >local-time ; : now ( -- timestamp ) gmt >local-time ;
: hence ( duration -- timestamp ) now swap time+ ; : hence ( duration -- timestamp ) now swap time+ ;
: ago ( duration -- timestamp ) now swap time- ; : ago ( duration -- timestamp ) now swap time- ;

View File

@ -5,11 +5,11 @@ kernel math unix unix.time unix.types namespaces system
accessors classes.struct ; accessors classes.struct ;
IN: calendar.unix IN: calendar.unix
: timeval>seconds ( timeval -- seconds ) : timeval>duration ( timeval -- duration )
[ sec>> seconds ] [ usec>> microseconds ] bi time+ ; [ sec>> seconds ] [ usec>> microseconds ] bi time+ ;
: timeval>unix-time ( timeval -- timestamp ) : timeval>unix-time ( timeval -- timestamp )
timeval>seconds since-1970 ; timeval>duration since-1970 ;
: timespec>seconds ( timespec -- seconds ) : timespec>seconds ( timespec -- seconds )
[ sec>> seconds ] [ nsec>> nanoseconds ] bi time+ ; [ sec>> seconds ] [ nsec>> nanoseconds ] bi time+ ;
@ -28,3 +28,7 @@ IN: calendar.unix
M: unix gmt-offset ( -- hours minutes seconds ) M: unix gmt-offset ( -- hours minutes seconds )
get-time gmtoff>> 3600 /mod 60 /mod ; get-time gmtoff>> 3600 /mod 60 /mod ;
M: unix gmt
timeval <struct> f [ gettimeofday io-error ] 2keep drop
timeval>unix-time ;

View File

@ -1,8 +1,33 @@
USING: calendar namespaces alien.c-types system USING: calendar namespaces alien.c-types system
windows.kernel32 kernel math combinators windows.errors windows.kernel32 kernel math combinators windows.errors
accessors classes.struct ; accessors classes.struct calendar.format math.functions ;
IN: calendar.windows IN: calendar.windows
: timestamp>SYSTEMTIME ( timestamp -- SYSTEMTIME )
{
[ year>> ]
[ month>> ]
[ day-of-week ]
[ day>> ]
[ hour>> ]
[ minute>> ]
[
second>> dup floor
[ nip >integer ]
[ - 1000 * >integer ] 2bi
]
} cleave \ SYSTEMTIME <struct-boa> ;
: SYSTEMTIME>timestamp ( SYSTEMTIME -- timestamp )
{
[ wYear>> ]
[ wMonth>> ]
[ wDay>> ]
[ wHour>> ]
[ wMinute>> ]
[ [ wSecond>> ] [ wMilliseconds>> 1000 / ] bi + ]
} cleave instant <timestamp> ;
M: windows gmt-offset ( -- hours minutes seconds ) M: windows gmt-offset ( -- hours minutes seconds )
TIME_ZONE_INFORMATION <struct> TIME_ZONE_INFORMATION <struct>
dup GetTimeZoneInformation { dup GetTimeZoneInformation {
@ -11,3 +36,6 @@ M: windows gmt-offset ( -- hours minutes seconds )
{ TIME_ZONE_ID_STANDARD [ Bias>> ] } { TIME_ZONE_ID_STANDARD [ Bias>> ] }
{ TIME_ZONE_ID_DAYLIGHT [ [ Bias>> ] [ DaylightBias>> ] bi + ] } { TIME_ZONE_ID_DAYLIGHT [ [ Bias>> ] [ DaylightBias>> ] bi + ] }
} case neg 60 /mod 0 ; } case neg 60 /mod 0 ;
M: windows gmt
SYSTEMTIME <struct> [ GetSystemTime ] keep SYSTEMTIME>timestamp ;

View File

@ -474,4 +474,7 @@ CONSULT: struct-test-delegate struct-test-delegator del>> ;
7 >>a 7 >>a
8 >>b 8 >>b
] unit-test ] unit-test
<<<<<<< HEAD
=======
>>>>>>> alien.data: make binary-zero? public and move it from classes.struct.private

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008, 2010 Slava Pestov. ! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: deques threads kernel arrays sequences alarms fry ; USING: deques threads kernel arrays sequences timers fry ;
IN: concurrency.conditions IN: concurrency.conditions
: notify-1 ( deque -- ) : notify-1 ( deque -- )
@ -9,8 +9,8 @@ IN: concurrency.conditions
: notify-all ( deque -- ) : notify-all ( deque -- )
[ resume-now ] slurp-deque ; inline [ resume-now ] slurp-deque ; inline
: queue-timeout ( queue timeout -- alarm ) : queue-timeout ( queue timeout -- timer )
#! Add an alarm which removes the current thread from the #! Add an timer which removes the current thread from the
#! queue, and resumes it, passing it a value of t. #! queue, and resumes it, passing it a value of t.
[ [
[ self swap push-front* ] keep '[ [ self swap push-front* ] keep '[
@ -28,7 +28,7 @@ ERROR: wait-timeout ;
: wait ( queue timeout status -- ) : wait ( queue timeout status -- )
over [ over [
[ queue-timeout ] dip suspend [ queue-timeout ] dip suspend
[ wait-timeout ] [ stop-alarm ] if [ wait-timeout ] [ stop-timer ] if
] [ ] [
[ drop queue ] dip suspend drop [ drop queue ] dip suspend drop
] if ; inline ] if ; inline

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel sequences db.tuples alarms calendar db fry USING: kernel sequences db.tuples timers calendar db fry
furnace.db furnace.db
furnace.cache furnace.cache
furnace.asides furnace.asides

View File

@ -3,7 +3,7 @@
USING: assocs kernel math.intervals math.parser namespaces USING: assocs kernel math.intervals math.parser namespaces
strings random accessors quotations hashtables sequences strings random accessors quotations hashtables sequences
continuations fry calendar combinators combinators.short-circuit continuations fry calendar combinators combinators.short-circuit
destructors alarms io.sockets db db.tuples db.types destructors io.sockets db db.tuples db.types
http http.server http.server.dispatchers http.server.filters http http.server http.server.dispatchers http.server.filters
furnace.cache furnace.scopes furnace.utilities ; furnace.cache furnace.scopes furnace.utilities ;
IN: furnace.sessions IN: furnace.sessions

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays combinators continuations fry io io.backend USING: arrays combinators continuations fry io io.backend
io.directories io.directories.hierarchy io.files io.pathnames io.directories io.directories.hierarchy io.files io.pathnames
kernel math math.bitwise math.parser namespaces random kernel locals math math.bitwise math.parser namespaces random
sequences system vocabs.loader ; sequences system vocabs.loader ;
IN: io.files.unique IN: io.files.unique
@ -78,9 +78,10 @@ PRIVATE>
: temporary-file ( -- path ) "" unique-file ; : temporary-file ( -- path ) "" unique-file ;
: with-working-directory ( path quot -- ) :: cleanup-unique-working-directory ( quot -- )
over make-directories unique-directory :> path
dupd '[ _ _ with-temporary-directory ] with-directory ; inline path [ path quot with-temporary-directory ] with-directory
path delete-tree ; inline
{ {
{ [ os unix? ] [ "io.files.unique.unix" ] } { [ os unix? ] [ "io.files.unique.unix" ] }

View File

@ -37,17 +37,22 @@ M: callable run-pipeline-element
'[ _ call( -- result ) ] with-streams* '[ _ call( -- result ) ] with-streams*
] with-destructors ; ] with-destructors ;
: <pipes> ( n -- pipes ) GENERIC: <pipes> ( obj -- pipes )
M: integer <pipes> ( n -- pipes )
[ [
[ (pipe) |dispose ] replicate [ (pipe) |dispose ] replicate
T{ pipe } [ prefix ] [ suffix ] bi T{ pipe } [ prefix ] [ suffix ] bi
2 <clumps> 2 <clumps>
] with-destructors ; ] with-destructors ;
M: sequence <pipes>
[ { } ] [ length 1 - <pipes> ] if-empty ;
PRIVATE> PRIVATE>
: run-pipeline ( seq -- results ) : run-pipeline ( seq -- results )
[ length dup zero? [ drop { } ] [ 1 - <pipes> ] if ] keep [ <pipes> ] keep
[ [
[ [ first in>> ] [ second out>> ] bi ] dip [ [ first in>> ] [ second out>> ] bi ] dip
run-pipeline-element run-pipeline-element

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008 Slava Pestov, Doug Coleman ! Copyright (C) 2008 Slava Pestov, Doug Coleman
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel calendar alarms io io.encodings accessors USING: kernel calendar timers io io.encodings accessors
namespaces fry io.streams.null ; namespaces fry io.streams.null ;
IN: io.timeouts IN: io.timeouts
@ -13,11 +13,11 @@ M: encoder set-timeout stream>> set-timeout ;
GENERIC: cancel-operation ( obj -- ) GENERIC: cancel-operation ( obj -- )
: queue-timeout ( obj timeout -- alarm ) : queue-timeout ( obj timeout -- timer )
[ '[ _ cancel-operation ] ] dip later ; [ '[ _ cancel-operation ] ] dip later ;
: with-timeout* ( obj timeout quot -- ) : with-timeout* ( obj timeout quot -- )
3dup drop queue-timeout [ nip call ] dip stop-alarm ; 3dup drop queue-timeout [ nip call ] dip stop-timer ;
inline inline
: with-timeout ( obj quot -- ) : with-timeout ( obj quot -- )

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: logging.analysis logging.server logging smtp kernel USING: logging.analysis logging.server logging smtp kernel
io.files io.streams.string namespaces make alarms assocs io.files io.streams.string namespaces make timers assocs
io.encodings.utf8 accessors calendar sequences ; io.encodings.utf8 accessors calendar sequences ;
QUALIFIED: io.sockets QUALIFIED: io.sockets
IN: logging.insomniac IN: logging.insomniac

View File

@ -1,9 +1,9 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alarms fry kernel models ; USING: accessors timers fry kernel models ;
IN: models.delay IN: models.delay
TUPLE: delay < model model timeout alarm ; TUPLE: delay < model model timeout timer ;
: update-delay-model ( delay -- ) : update-delay-model ( delay -- )
[ model>> value>> ] keep set-model ; [ model>> value>> ] keep set-model ;
@ -15,13 +15,13 @@ TUPLE: delay < model model timeout alarm ;
[ add-dependency ] keep ; [ add-dependency ] keep ;
: stop-delay ( delay -- ) : stop-delay ( delay -- )
alarm>> [ stop-alarm ] when* ; timer>> [ stop-timer ] when* ;
: start-delay ( delay -- ) : start-delay ( delay -- )
dup dup
[ '[ _ f >>alarm update-delay-model ] ] [ timeout>> ] bi [ '[ _ f >>timer update-delay-model ] ] [ timeout>> ] bi
later later
>>alarm drop ; >>timer drop ;
M: delay model-changed nip dup stop-delay start-delay ; M: delay model-changed nip dup stop-delay start-delay ;

1
basis/timers/authors.txt Executable file
View File

@ -0,0 +1 @@
Doug Coleman

1
basis/timers/summary.txt Normal file
View File

@ -0,0 +1 @@
One-time and recurring timers for relative time offsets

View File

@ -0,0 +1,74 @@
USING: help.markup help.syntax calendar quotations system ;
IN: timers
HELP: timer
{ $class-description "A timer. Can be passed to " { $link stop-timer } "." } ;
HELP: start-timer
{ $values { "timer" timer } }
{ $description "Starts a timer." } ;
HELP: restart-timer
{ $values { "timer" timer } }
{ $description "Starts or restarts a timer. Restarting a timer causes the a sleep of initial delay nanoseconds before looping. An timer's parameters may be modified and restarted with this word." } ;
HELP: stop-timer
{ $values { "timer" timer } }
{ $description "Prevents a timer from calling its quotation again. Has no effect on timers that are not currently running." } ;
HELP: every
{ $values
{ "quot" quotation } { "interval-duration" duration }
{ "timer" timer } }
{ $description "Creates a timer that calls the quotation repeatedly, using " { $snippet "duration" } " as the frequency. The first call of " { $snippet "quot" } " will happen immediately. If the quotation throws an exception, the timer will stop." }
{ $examples
{ $unchecked-example
"USING: timers io calendar ;"
"""[ "Hi Buddy." print flush ] 10 seconds every drop"""
""
}
} ;
HELP: later
{ $values { "quot" quotation } { "delay-duration" duration } { "timer" timer } }
{ $description "Sleeps for " { $snippet "duration" } " and then calls a " { $snippet "quot" } ". The user may cancel the timer before " { $snippet "quot" } " runs. This timer is not repeated." }
{ $examples
{ $unchecked-example
"USING: timers io calendar ;"
"""[ "Break's over!" print flush ] 15 minutes later drop"""
""
}
} ;
HELP: delayed-every
{ $values
{ "quot" quotation } { "duration" duration }
{ "timer" timer } }
{ $description "Creates a timer that calls " { $snippet "quot" } " repeatedly, waiting " { $snippet "duration" } " before calling " { $snippet "quot" } " the first time and then waiting " { $snippet "duration" } " between further calls. If the quotation throws an exception, the timer will stop." }
{ $examples
{ $unchecked-example
"USING: timers io calendar ;"
"""[ "Hi Buddy." print flush ] 10 seconds every drop"""
""
}
} ;
ARTICLE: "timers" "Alarms"
"The " { $vocab-link "timers" } " vocabulary provides a lightweight way to schedule one-time and recurring tasks. Alarms run in a single green thread per timer and consist of a quotation, a delay duration, and an interval duration. After starting a timer, the timer thread sleeps for the delay duration and calls the quotation. Then it waits out the interval duration and calls the quotation again until something stops the timer. If a recurring timer's quotation would be scheduled to run again before the previous quotation has finished processing, the timer will be run again immediately afterwards. This may result in the timer falling behind indefinitely, in which case the it will run as often as possible while still allowing other green threads to run. Recurring timers that execute 'on time' or 'catch up' will always be scheduled for an exact multiple of the interval from the original starting time to prevent the timer from drifting over time. Alarms use " { $link nano-count } " as the timing primitive, so they will continue to work across system clock changes." $nl
"The timer class:"
{ $subsections timer }
"Create a timer before starting it:"
{ $subsections <timer> }
"Starting a timer:"
{ $subsections start-timer restart-timer }
"Stopping a timer:"
{ $subsections stop-timer }
"A recurring timer without an initial delay:"
{ $subsections every }
"A one-time timer with an initial delay:"
{ $subsections later }
"A recurring timer with an initial delay:"
{ $subsections delayed-every } ;
ABOUT: "timers"

View File

@ -1,12 +1,12 @@
USING: alarms alarms.private calendar concurrency.count-downs USING: timers timers.private calendar concurrency.count-downs
concurrency.promises fry kernel math math.order sequences concurrency.promises fry kernel math math.order sequences
threads tools.test tools.time ; threads tools.test tools.time ;
IN: alarms.tests IN: timers.tests
[ ] [ [ ] [
1 <count-down> 1 <count-down>
{ f } clone 2dup { f } clone 2dup
[ first stop-alarm count-down ] 2curry 1 seconds later [ first stop-timer count-down ] 2curry 1 seconds later
swap set-first swap set-first
await await
] unit-test ] unit-test
@ -28,20 +28,20 @@ IN: alarms.tests
{ 3 } dup { 3 } dup
'[ 4 _ set-first ] 2 seconds later '[ 4 _ set-first ] 2 seconds later
1/2 seconds sleep 1/2 seconds sleep
stop-alarm stop-timer
] unit-test ] unit-test
[ { 1 } ] [ [ { 1 } ] [
{ 0 } { 0 }
dup '[ 0 _ [ 1 + ] change-nth ] 3 seconds later dup '[ 0 _ [ 1 + ] change-nth ] 3 seconds later
[ stop-alarm ] [ start-alarm ] bi [ stop-timer ] [ start-timer ] bi
4 seconds sleep 4 seconds sleep
] unit-test ] unit-test
[ { 0 } ] [ [ { 0 } ] [
{ 0 } { 0 }
dup '[ 3 seconds sleep 1 _ set-first ] 1 seconds later dup '[ 3 seconds sleep 1 _ set-first ] 1 seconds later
2 seconds sleep stop-alarm 2 seconds sleep stop-timer
1/2 seconds sleep 1/2 seconds sleep
] unit-test ] unit-test
@ -49,19 +49,19 @@ IN: alarms.tests
{ 0 } { 0 }
dup '[ 1 _ set-first ] 300 milliseconds later dup '[ 1 _ set-first ] 300 milliseconds later
150 milliseconds sleep 150 milliseconds sleep
[ restart-alarm ] [ 200 milliseconds sleep stop-alarm ] bi [ restart-timer ] [ 200 milliseconds sleep stop-timer ] bi
] unit-test ] unit-test
[ { 1 } ] [ [ { 1 } ] [
{ 0 } { 0 }
dup '[ 0 _ [ 1 + ] change-nth ] 200 milliseconds later dup '[ 0 _ [ 1 + ] change-nth ] 200 milliseconds later
100 milliseconds sleep restart-alarm 300 milliseconds sleep 100 milliseconds sleep restart-timer 300 milliseconds sleep
] unit-test ] unit-test
[ { 4 } ] [ [ { 4 } ] [
{ 0 } { 0 }
dup '[ 0 _ [ 1 + ] change-nth ] 300 milliseconds 300 milliseconds dup '[ 0 _ [ 1 + ] change-nth ] 300 milliseconds 300 milliseconds
<alarm> dup start-alarm <timer> dup start-timer
700 milliseconds sleep dup restart-alarm 700 milliseconds sleep dup restart-timer
700 milliseconds sleep stop-alarm 500 milliseconds sleep 700 milliseconds sleep stop-timer 500 milliseconds sleep
] unit-test ] unit-test

122
basis/timers/timers.factor Normal file
View File

@ -0,0 +1,122 @@
! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs calendar combinators.short-circuit fry
heaps init kernel math math.functions math.parser namespaces
quotations sequences system threads ;
IN: timers
TUPLE: timer
{ quot callable initial: [ ] }
start-nanos
delay-nanos
interval-nanos
iteration-start-nanos
quotation-running?
restart?
thread ;
<PRIVATE
GENERIC: >nanoseconds ( obj -- duration/f )
M: f >nanoseconds ;
M: real >nanoseconds >integer ;
M: duration >nanoseconds duration>nanoseconds >integer ;
: set-next-timer-time ( timer -- timer )
! start + delay + ceiling((now - (start + delay)) / interval) * interval
nano-count
over start-nanos>> -
over delay-nanos>> [ - ] when*
over interval-nanos>> / ceiling
over interval-nanos>> *
over start-nanos>> +
over delay-nanos>> [ + ] when*
>>iteration-start-nanos ;
: stop-timer? ( timer -- ? )
{ [ thread>> self eq? not ] [ restart?>> ] } 1|| ;
DEFER: call-timer-loop
: loop-timer ( timer -- )
nano-count over
[ iteration-start-nanos>> - ] [ interval-nanos>> ] bi <
[ set-next-timer-time ] dip
[ dup iteration-start-nanos>> ] [ 0 ] if
0 or sleep-until call-timer-loop ;
: maybe-loop-timer ( timer -- )
dup { [ stop-timer? ] [ interval-nanos>> not ] } 1||
[ drop ] [ loop-timer ] if ;
: call-timer-loop ( timer -- )
dup stop-timer? [
drop
] [
[
[ t >>quotation-running? drop ]
[ quot>> call( -- ) ]
[ f >>quotation-running? drop ] tri
] keep
maybe-loop-timer
] if ;
: sleep-delay ( timer -- )
dup stop-timer? [
drop
] [
nano-count >>start-nanos
delay-nanos>> [ sleep ] when*
] if ;
: timer-loop ( timer -- )
[ sleep-delay ]
[ nano-count >>iteration-start-nanos call-timer-loop ]
[ dup restart?>> [ f >>restart? timer-loop ] [ drop ] if ] tri ;
PRIVATE>
: <timer> ( quot delay-duration/f interval-duration/f -- timer )
timer new
swap >nanoseconds >>interval-nanos
swap >nanoseconds >>delay-nanos
swap >>quot ; inline
: start-timer ( timer -- )
[
'[ _ timer-loop ] "Alarm execution" spawn
] keep thread<< ;
: stop-timer ( timer -- )
dup quotation-running?>> [
f >>thread drop
] [
[ [ interrupt ] when* f ] change-thread drop
] if ;
: restart-timer ( timer -- )
t >>restart?
dup quotation-running?>> [
drop
] [
dup thread>> [ nip interrupt ] [ start-timer ] if*
] if ;
<PRIVATE
: (start-timer) ( quot start-duration interval-duration -- timer )
<timer> [ start-timer ] keep ;
PRIVATE>
: every ( quot interval-duration -- timer )
[ f ] dip (start-timer) ;
: later ( quot delay-duration -- timer )
f (start-timer) ;
: delayed-every ( quot duration -- timer )
dup (start-timer) ;
: nanos-since ( nano-count -- nanos )
[ nano-count ] dip - ;

View File

@ -64,7 +64,7 @@ $nl
HELP: deploy-threads? HELP: deploy-threads?
{ $description "Deploy flag. If set, thread support will be included in the final image." { $description "Deploy flag. If set, thread support will be included in the final image."
$nl $nl
"On by default. Most programs depend on libraries which use threads even if they don't use threads directly; for example, alarms, non-blocking I/O, and the UI are built on top of threads. If after testing your program still works without threads, you can disable this feature to save some space." } ; "On by default. Most programs depend on libraries which use threads even if they don't use threads directly; for example, timers, non-blocking I/O, and the UI are built on top of threads. If after testing your program still works without threads, you can disable this feature to save some space." } ;
HELP: deploy-ui? HELP: deploy-ui?
{ $description "Deploy flag. If set, the Factor UI will be included in the deployed image." { $description "Deploy flag. If set, the Factor UI will be included in the deployed image."

View File

@ -317,7 +317,7 @@ IN: tools.deploy.shaker
strip-io? [ io-backend , ] when strip-io? [ io-backend , ] when
{ } { { } {
"alarms" "timers"
"tools" "tools"
"io.launcher" "io.launcher"
"random" "random"

View File

@ -5,7 +5,7 @@ io.encodings.utf8 hashtables kernel namespaces sequences
vocabs.loader vocabs.metadata io combinators calendar accessors vocabs.loader vocabs.metadata io combinators calendar accessors
math.parser io.streams.string ui.tools.operations quotations math.parser io.streams.string ui.tools.operations quotations
strings arrays prettyprint words vocabs sorting sets classes strings arrays prettyprint words vocabs sorting sets classes
math alien urls splitting ascii combinators.short-circuit alarms math alien urls splitting ascii combinators.short-circuit timers
words.symbol system summary ; words.symbol system summary ;
IN: tools.scaffold IN: tools.scaffold
@ -22,7 +22,9 @@ M: bad-developer-name summary
<PRIVATE <PRIVATE
: vocab-root? ( string -- ? ) vocab-roots get member? ; : vocab-root? ( string -- ? )
trim-tail-separators
vocab-roots get member? ;
: contains-dot? ( string -- ? ) ".." swap subseq? ; : contains-dot? ( string -- ? ) ".." swap subseq? ;
@ -128,7 +130,7 @@ M: bad-developer-name summary
{ "ch" "a character" } { "ch" "a character" }
{ "word" word } { "word" word }
{ "array" array } { "array" array }
{ "alarm" alarm } { "timers" timer }
{ "duration" duration } { "duration" duration }
{ "path" "a pathname string" } { "path" "a pathname string" }
{ "vocab" "a vocabulary specifier" } { "vocab" "a vocabulary specifier" }

View File

@ -569,6 +569,9 @@ H{ } clone wm-handlers set-global
[ [ execute( -- wm ) add-wm-handler ] with each ] [ [ execute( -- wm ) add-wm-handler ] with each ]
[ wm-handlers get-global set-at ] if ; [ wm-handlers get-global set-at ] if ;
: remove-wm-handler ( wm -- )
wm-handlers get-global delete-at ;
[ handle-wm-close 0 ] WM_CLOSE add-wm-handler [ handle-wm-close 0 ] WM_CLOSE add-wm-handler
[ 4dup handle-wm-paint DefWindowProc ] WM_PAINT add-wm-handler [ 4dup handle-wm-paint DefWindowProc ] WM_PAINT add-wm-handler

View File

@ -1,6 +1,6 @@
! Copyright (C) 2006, 2009 Slava Pestov ! Copyright (C) 2006, 2009 Slava Pestov
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alarms arrays assocs calendar colors.constants USING: accessors timers arrays assocs calendar colors.constants
combinators combinators.short-circuit documents combinators combinators.short-circuit documents
documents.elements fry grouping kernel locals make math documents.elements fry grouping kernel locals make math
math.functions math.order math.ranges math.rectangles math.functions math.order math.ranges math.rectangles
@ -15,7 +15,7 @@ IN: ui.gadgets.editors
TUPLE: editor < line-gadget TUPLE: editor < line-gadget
caret-color caret-color
caret mark caret mark
focused? blink blink-alarm ; focused? blink blink-timer ;
<PRIVATE <PRIVATE
@ -60,11 +60,11 @@ SYMBOL: blink-interval
750 milliseconds blink-interval set-global 750 milliseconds blink-interval set-global
: stop-blinking ( editor -- ) : stop-blinking ( editor -- )
blink-alarm>> [ stop-alarm ] when* ; blink-timer>> [ stop-timer ] when* ;
: start-blinking ( editor -- ) : start-blinking ( editor -- )
t >>blink t >>blink
blink-alarm>> [ restart-alarm ] when* ; blink-timer>> [ restart-timer ] when* ;
: restart-blinking ( editor -- ) : restart-blinking ( editor -- )
dup focused?>> [ dup focused?>> [
@ -80,12 +80,12 @@ M: editor graft*
[ dup mark>> activate-editor-model ] [ dup mark>> activate-editor-model ]
[ [
[ [
'[ _ blink-caret ] blink-interval get dup <alarm> '[ _ blink-caret ] blink-interval get dup <timer>
] keep blink-alarm<< ] keep blink-timer<<
] tri ; ] tri ;
M: editor ungraft* M: editor ungraft*
[ [ stop-blinking ] [ f >>blink-alarm drop ] bi ] [ [ stop-blinking ] [ f >>blink-timer drop ] bi ]
[ dup caret>> deactivate-editor-model ] [ dup caret>> deactivate-editor-model ]
[ dup mark>> deactivate-editor-model ] tri ; [ dup mark>> deactivate-editor-model ] tri ;

View File

@ -1,10 +1,11 @@
! Copyright (C) 2005, 2009 Slava Pestov. ! Copyright (C) 2005, 2009 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs continuations kernel math models USING: accessors arrays assocs cache colors combinators
namespaces opengl opengl.textures sequences io colors combinators combinators.short-circuit concurrency.promises continuations
combinators.short-circuit fry math.vectors math.rectangles cache destructors fry io kernel literals math math.rectangles
ui.gadgets ui.gestures ui.render ui.backend ui.gadgets.tracks math.vectors models namespaces opengl opengl.textures sequences
ui.pixel-formats destructors literals strings ; strings ui.backend ui.gadgets ui.gadgets.tracks ui.gestures
ui.pixel-formats ui.render ;
IN: ui.gadgets.worlds IN: ui.gadgets.worlds
SYMBOLS: SYMBOLS:
@ -40,6 +41,7 @@ TUPLE: world < track
window-loc window-loc
pixel-format-attributes pixel-format-attributes
background-color background-color
promise
window-controls window-controls
window-resources ; window-resources ;
@ -118,7 +120,8 @@ M: world request-focus-on ( child gadget -- )
f >>active? f >>active?
{ 0 0 } >>window-loc { 0 0 } >>window-loc
f >>grab-input? f >>grab-input?
V{ } clone >>window-resources ; V{ } clone >>window-resources
<promise> >>promise ;
: initial-background-color ( attributes -- color ) : initial-background-color ( attributes -- color )
window-controls>> textured-background swap member-eq? window-controls>> textured-background swap member-eq?

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs kernel math math.order models USING: accessors arrays assocs kernel math math.order models
namespaces make sequences words strings system hashtables math.parser namespaces make sequences words strings system hashtables math.parser
math.vectors classes.tuple classes boxes calendar alarms combinators math.vectors classes.tuple classes boxes calendar timers combinators
sets columns fry deques ui.gadgets ui.gadgets.private ascii sets columns fry deques ui.gadgets ui.gadgets.private ascii
combinators.short-circuit ; combinators.short-circuit ;
FROM: namespaces => set ; FROM: namespaces => set ;
@ -188,15 +188,15 @@ SYMBOL: drag-timer
[ drag-gesture ] [ drag-gesture ]
300 milliseconds 300 milliseconds
100 milliseconds 100 milliseconds
<alarm> <timer>
[ drag-timer get-global >box ] [ drag-timer get-global >box ]
[ start-alarm ] bi [ start-timer ] bi
] when ; ] when ;
: stop-drag-timer ( -- ) : stop-drag-timer ( -- )
hand-buttons get-global empty? [ hand-buttons get-global empty? [
drag-timer get-global ?box drag-timer get-global ?box
[ stop-alarm ] [ drop ] if [ stop-timer ] [ drop ] if
] when ; ] when ;
: fire-motion ( -- ) : fire-motion ( -- )

View File

@ -1,12 +1,12 @@
! Copyright (C) 2006, 2010 Slava Pestov. ! Copyright (C) 2006, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays assocs boxes io kernel math models namespaces make USING: accessors arrays assocs boxes classes.tuple
dlists deques sequences threads words continuations init classes.tuple.parser combinators combinators.short-circuit
combinators combinators.short-circuit hashtables concurrency.flags concurrency.promises continuations deques
concurrency.flags sets accessors calendar fry destructors destructors dlists fry init kernel lexer make math namespaces
ui.gadgets ui.gadgets.private ui.gadgets.worlds parser sequences sets strings threads ui.backend ui.gadgets
ui.gadgets.tracks ui.gestures ui.backend ui.render strings ui.gadgets.private ui.gadgets.worlds ui.gestures vocabs.parser
classes.tuple classes.tuple.parser lexer vocabs.parser parser ; words ;
IN: ui IN: ui
<PRIVATE <PRIVATE
@ -94,6 +94,7 @@ M: world ungraft*
[ [ <reversed> [ [ dispose ] when* ] each V{ } clone ] change-window-resources drop ] [ [ <reversed> [ [ dispose ] when* ] each V{ } clone ] change-window-resources drop ]
[ [ (close-window) f ] change-handle drop ] [ [ (close-window) f ] change-handle drop ]
[ unfocus-world ] [ unfocus-world ]
[ promise>> t swap fulfill ]
} cleave ; } cleave ;
: init-ui ( -- ) : init-ui ( -- )

View File

@ -94,6 +94,7 @@ FUNCTION: int getpriority ( int which, id_t who ) ;
FUNCTION: int setpriority ( int which, id_t who, int prio ) ; FUNCTION: int setpriority ( int which, id_t who, int prio ) ;
FUNCTION: int getrusage ( int who, rusage* r_usage ) ; FUNCTION: int getrusage ( int who, rusage* r_usage ) ;
FUNCTION: group* getgrent ; FUNCTION: group* getgrent ;
FUNCTION: void endgrent ( ) ;
FUNCTION: int gethostname ( c-string name, int len ) ; FUNCTION: int gethostname ( c-string name, int len ) ;
FUNCTION: int getsockname ( int socket, sockaddr* address, socklen_t* address_len ) ; FUNCTION: int getsockname ( int socket, sockaddr* address, socklen_t* address_len ) ;
FUNCTION: int getpeername ( int socket, sockaddr* address, socklen_t* address_len ) ; FUNCTION: int getpeername ( int socket, sockaddr* address, socklen_t* address_len ) ;

View File

@ -65,8 +65,8 @@ HELP: user-groups
HELP: with-effective-group HELP: with-effective-group
{ $values { $values
{ "string/id" "a string or a group id" } { "quot" quotation } } { "string/id/f" "a string, a group id, or f" } { "quot" quotation } }
{ $description "Sets the effective group name and calls the quotation. Restors the effective group name on success or on error after the call." } ; { $description "Sets the effective group name and calls the quotation. Restors the effective group name on success or on error after the call. If the first parameter is " { $link f } ", the quotation is called as the current user." } ;
HELP: with-group-cache HELP: with-group-cache
{ $values { $values
@ -75,26 +75,55 @@ HELP: with-group-cache
HELP: with-real-group HELP: with-real-group
{ $values { $values
{ "string/id" "a string or a group id" } { "quot" quotation } } { "string/id/f" "a string or a group id" } { "quot" quotation } }
{ $description "Sets the real group name and calls the quotation. Restores the current group name on success or on error after the call." } ; { $description "Sets the real group name and calls the quotation. Restores the current group name on success or on error after the call. If the first parameter is " { $link f } ", the quotation is called as the current user." } ;
HELP: ?group-id
{ $values
{ "string" string }
{ "id" "a group id" }
}
{ $description "Returns a group id or throws an exception." } ;
HELP: all-group-names
{ $values
{ "seq" sequence }
}
{ $description "Returns a sequence of group names as strings." } ;
HELP: group-exists?
{ $values
{ "name/id" "a name or a group id" }
{ "?" boolean }
}
{ $description "Returns a boolean representing the group's existence." } ;
ARTICLE: "unix.groups" "Unix groups" ARTICLE: "unix.groups" "Unix groups"
"The " { $vocab-link "unix.groups" } " vocabulary contains words that return information about Unix groups." "The " { $vocab-link "unix.groups" } " vocabulary contains words that return information about Unix groups."
$nl $nl
"Listing all groups:" "Listing all group structures:"
{ $subsections all-groups } { $subsections all-groups }
"Real groups:" "Listing all group names:"
{ $subsections all-group-names }
"Checking if a group exists:"
{ $subsections group-exists? }
"Querying/setting the current real group:"
{ $subsections { $subsections
real-group-name real-group-name
real-group-id real-group-id
set-real-group set-real-group
} }
"Effective groups:" "Querying/setting the current effective group:"
{ $subsections { $subsections
effective-group-name effective-group-name
effective-group-id effective-group-id
set-effective-group set-effective-group
} }
"Getting a group id from a group name or id:"
{ $subsections
?group-id
}
"Combinators to change groups:" "Combinators to change groups:"
{ $subsections { $subsections
with-real-group with-real-group

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: tools.test unix.groups kernel strings math ; USING: kernel math sequences strings tools.test unix.groups ;
IN: unix.groups.tests IN: unix.groups.tests
[ ] [ all-groups drop ] unit-test [ ] [ all-groups drop ] unit-test
@ -25,5 +25,15 @@ IN: unix.groups.tests
[ ] [ real-group-id group-name drop ] unit-test [ ] [ real-group-id group-name drop ] unit-test
[ "888888888888888" ] [ 888888888888888 group-name ] unit-test [ "888888888888888" ] [ 888888888888888 group-name ] unit-test
[ f ] [ "please-oh-please-don't-have-a-group-named-this123lalala" group-struct ] unit-test
[ f ] [ "please-oh-please-don't-have-a-group-named-this123lalala" group-exists? ] unit-test
[ "please-oh-please-don't-have-a-group-named-this123lalala" ?group-id ] must-fail
[ 3 ] [ f [ 3 ] with-effective-group ] unit-test
[ 3 ] [ f [ 3 ] with-real-group ] unit-test
[ f ] [ f ]
[ "please-oh-please-don't-have-a-group-named-this123lalala" group-struct ] unit-test [ all-groups drop all-groups empty? ] unit-test
[ f ]
[ all-group-names drop all-group-names empty? ] unit-test

View File

@ -1,15 +1,13 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.c-types alien.strings io.encodings.utf8 USING: accessors alien alien.c-types alien.strings assocs
io.backend.unix kernel math sequences splitting strings byte-arrays classes.struct combinators
combinators.short-circuit byte-arrays combinators combinators.short-circuit continuations fry io.backend.unix
accessors math.parser fry assocs namespaces continuations io.encodings.utf8 kernel math math.parser namespaces sequences
unix.users unix.utilities classes.struct unix ; splitting strings unix unix.ffi unix.users unix.utilities ;
IN: unix.groups
QUALIFIED: unix.ffi QUALIFIED: unix.ffi
QUALIFIED: grouping QUALIFIED: grouping
IN: unix.groups
TUPLE: group id name passwd members ; TUPLE: group id name passwd members ;
@ -61,6 +59,11 @@ PRIVATE>
: group-id ( string -- id/f ) : group-id ( string -- id/f )
group-struct dup [ gr_gid>> ] when ; group-struct dup [ gr_gid>> ] when ;
ERROR: no-group string ;
: ?group-id ( string -- id )
dup group-struct [ nip gr_gid>> ] [ no-group ] if* ;
<PRIVATE <PRIVATE
: >groups ( byte-array n -- groups ) : >groups ( byte-array n -- groups )
@ -83,7 +86,11 @@ M: integer user-groups ( id -- seq )
user-name (user-groups) ; user-name (user-groups) ;
: all-groups ( -- seq ) : all-groups ( -- seq )
[ unix.ffi:getgrent dup ] [ group-struct>group ] produce nip ; [ unix.ffi:getgrent dup ] [ group-struct>group ] produce nip
endgrent ;
: all-group-names ( -- seq )
all-groups [ name>> ] map ;
: <group-cache> ( -- assoc ) : <group-cache> ( -- assoc )
all-groups [ [ id>> ] keep ] H{ } map>assoc ; all-groups [ [ id>> ] keep ] H{ } map>assoc ;
@ -100,18 +107,26 @@ M: integer user-groups ( id -- seq )
: effective-group-name ( -- string ) : effective-group-name ( -- string )
effective-group-id group-name ; inline effective-group-id group-name ; inline
: group-exists? ( name/id -- ? ) group-id >boolean ;
GENERIC: set-real-group ( obj -- ) GENERIC: set-real-group ( obj -- )
GENERIC: set-effective-group ( obj -- ) GENERIC: set-effective-group ( obj -- )
: with-real-group ( string/id quot -- ) : (with-real-group) ( string/id quot -- )
'[ _ set-real-group @ ] '[ _ set-real-group @ ]
real-group-id '[ _ set-real-group ] [ ] cleanup ; inline real-group-id '[ _ set-real-group ] [ ] cleanup ; inline
: with-effective-group ( string/id quot -- ) : with-real-group ( string/id/f quot -- )
over [ (with-real-group) ] [ nip call ] if ; inline
: (with-effective-group) ( string/id quot -- )
'[ _ set-effective-group @ ] '[ _ set-effective-group @ ]
effective-group-id '[ _ set-effective-group ] [ ] cleanup ; inline effective-group-id '[ _ set-effective-group ] [ ] cleanup ; inline
: with-effective-group ( string/id/f quot -- )
over [ (with-effective-group) ] [ nip call ] if ; inline
<PRIVATE <PRIVATE
: (set-real-group) ( id -- ) : (set-real-group) ( id -- )
@ -122,14 +137,14 @@ GENERIC: set-effective-group ( obj -- )
PRIVATE> PRIVATE>
M: string set-real-group ( string -- )
group-id (set-real-group) ;
M: integer set-real-group ( id -- ) M: integer set-real-group ( id -- )
(set-real-group) ; (set-real-group) ;
M: string set-real-group ( string -- )
?group-id (set-real-group) ;
M: integer set-effective-group ( id -- ) M: integer set-effective-group ( id -- )
(set-effective-group) ; (set-effective-group) ;
M: string set-effective-group ( string -- ) M: string set-effective-group ( string -- )
group-id (set-effective-group) ; ?group-id (set-effective-group) ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel alien.syntax alien.c-types math unix.types USING: accessors alien.c-types alien.syntax calendar
classes.struct accessors ; classes.struct kernel math unix.types ;
IN: unix.time IN: unix.time
STRUCT: timeval STRUCT: timeval
@ -24,6 +24,15 @@ STRUCT: timespec
swap >>nsec swap >>nsec
swap >>sec ; swap >>sec ;
STRUCT: timezone
{ tz_minuteswest int }
{ tz_dsttime int } ;
: timestamp>timezone ( timestamp -- timezone )
gmt-offset>> duration>minutes
1
\ timezone <struct-boa> ; inline
STRUCT: tm STRUCT: tm
{ sec int } { sec int }
{ min int } { min int }
@ -40,3 +49,5 @@ STRUCT: tm
FUNCTION: time_t time ( time_t* t ) ; FUNCTION: time_t time ( time_t* t ) ;
FUNCTION: tm* localtime ( time_t* clock ) ; FUNCTION: tm* localtime ( time_t* clock ) ;
FUNCTION: int gettimeofday ( timespec* TP, void* TZP ) ; FUNCTION: int gettimeofday ( timespec* TP, void* TZP ) ;
FUNCTION: int settimeofday ( timeval* TP, timezone* TZP ) ;
FUNCTION: int adjtime ( timeval* delta, timeval* olddelta ) ;

View File

@ -67,8 +67,8 @@ HELP: user-id
HELP: with-effective-user HELP: with-effective-user
{ $values { $values
{ "string/id" "a string or a uid" } { "quot" quotation } } { "string/id/f" "a string, a uid, or f" } { "quot" quotation } }
{ $description "Sets the effective user-name and calls the quotation. Restores the current user-name on success or on error after the call." } ; { $description "Sets the effective user-name and calls the quotation. Restores the current user-name on success or on error after the call. If the first parameter is " { $link f } ", the quotation is called as the current user." } ;
HELP: with-user-cache HELP: with-user-cache
{ $values { $values
@ -77,8 +77,8 @@ HELP: with-user-cache
HELP: with-real-user HELP: with-real-user
{ $values { $values
{ "string/id" "a string or a uid" } { "quot" quotation } } { "string/id/f" "a string, a uid, or f" } { "quot" quotation } }
{ $description "Sets the real user-name and calls the quotation. Restores the current user-name on success or on error after the call." } ; { $description "Sets the real user-name and calls the quotation. Restores the current user-name on success or on error after the call. If the first parameter is " { $link f } ", the quotation is called as the current user." } ;
{ {
real-user-name real-user-id set-real-user real-user-name real-user-id set-real-user
@ -86,18 +86,43 @@ HELP: with-real-user
set-effective-user set-effective-user
} related-words } related-words
HELP: ?user-id
{ $values
{ "string" string }
{ "id/f" "an integer or " { $link f } }
}
{ $description "Returns a group id or throws an exception." } ;
HELP: all-user-names
{ $values
{ "seq" sequence }
}
{ $description "Returns a sequence of group names as strings." } ;
HELP: user-exists?
{ $values
{ "name/id" "a string or an integer" }
{ "?" boolean }
}
{ $description "Returns a boolean representing the user's existence." } ;
ARTICLE: "unix.users" "Unix users" ARTICLE: "unix.users" "Unix users"
"The " { $vocab-link "unix.users" } " vocabulary contains words that return information about Unix users." "The " { $vocab-link "unix.users" } " vocabulary contains words that return information about Unix users."
$nl $nl
"Listing all users:" "Listing all users:"
{ $subsections all-users } { $subsections all-users }
"Real user:" "Listing all user names:"
{ $subsections all-user-names }
"Checking if a user exists:"
{ $subsections user-exists? }
"Querying/setting the current real user:"
{ $subsections { $subsections
real-user-name real-user-name
real-user-id real-user-id
set-real-user set-real-user
} }
"Effective user:" "Querying/setting the current effective user:"
{ $subsections { $subsections
effective-user-name effective-user-name
effective-user-id effective-user-id

View File

@ -1,6 +1,6 @@
! Copyright (C) 2008 Doug Coleman. ! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: tools.test unix.users kernel strings math ; USING: tools.test unix.users kernel strings math sequences ;
IN: unix.users.tests IN: unix.users.tests
[ ] [ all-users drop ] unit-test [ ] [ all-users drop ] unit-test
@ -27,3 +27,14 @@ IN: unix.users.tests
[ f ] [ 89898989898989898989898989898 user-passwd ] unit-test [ f ] [ 89898989898989898989898989898 user-passwd ] unit-test
[ f ] [ "thisusershouldnotexistabcdefg12345asdfasdfasdfasdfasdfasdfasdf" user-id ] unit-test [ f ] [ "thisusershouldnotexistabcdefg12345asdfasdfasdfasdfasdfasdfasdf" user-id ] unit-test
[ f ] [ "thisusershouldnotexistabcdefg12345asdfasdfasdfasdfasdfasdfasdf" user-exists? ] unit-test
[ "thisusershouldnotexistabcdefg12345asdfasdfasdfasdfasdfasdfasdf" ?user-id ] must-fail
[ 3 ] [ f [ 3 ] with-effective-user ] unit-test
[ 3 ] [ f [ 3 ] with-real-user ] unit-test
[ f ]
[ all-users drop all-users empty? ] unit-test
[ f ]
[ all-user-names drop all-user-names empty? ] unit-test

View File

@ -40,6 +40,9 @@ PRIVATE>
[ unix.ffi:getpwent dup ] [ passwd>new-passwd ] produce nip [ unix.ffi:getpwent dup ] [ passwd>new-passwd ] produce nip
] with-pwent ; ] with-pwent ;
: all-user-names ( -- seq )
all-users [ user-name>> ] map ;
SYMBOL: user-cache SYMBOL: user-cache
: <user-cache> ( -- assoc ) : <user-cache> ( -- assoc )
@ -64,6 +67,11 @@ M: string user-passwd ( string -- passwd/f )
: user-id ( string -- id/f ) : user-id ( string -- id/f )
user-passwd dup [ uid>> ] when ; user-passwd dup [ uid>> ] when ;
ERROR: no-user string ;
: ?user-id ( string -- id/f )
dup user-passwd [ nip uid>> ] [ no-user ] if* ;
: real-user-id ( -- id ) : real-user-id ( -- id )
unix.ffi:getuid ; inline unix.ffi:getuid ; inline
@ -76,20 +84,28 @@ M: string user-passwd ( string -- passwd/f )
: effective-user-name ( -- string ) : effective-user-name ( -- string )
effective-user-id user-name ; inline effective-user-id user-name ; inline
: user-exists? ( name/id -- ? ) user-id >boolean ;
GENERIC: set-real-user ( string/id -- ) GENERIC: set-real-user ( string/id -- )
GENERIC: set-effective-user ( string/id -- ) GENERIC: set-effective-user ( string/id -- )
: with-real-user ( string/id quot -- ) : (with-real-user) ( string/id quot -- )
'[ _ set-real-user @ ] '[ _ set-real-user @ ]
real-user-id '[ _ set-real-user ] real-user-id '[ _ set-real-user ]
[ ] cleanup ; inline [ ] cleanup ; inline
: with-effective-user ( string/id quot -- ) : with-real-user ( string/id/f quot -- )
over [ (with-real-user) ] [ nip call ] if ; inline
: (with-effective-user) ( string/id quot -- )
'[ _ set-effective-user @ ] '[ _ set-effective-user @ ]
effective-user-id '[ _ set-effective-user ] effective-user-id '[ _ set-effective-user ]
[ ] cleanup ; inline [ ] cleanup ; inline
: with-effective-user ( string/id/f quot -- )
over [ (with-effective-user) ] [ nip call ] if ; inline
<PRIVATE <PRIVATE
: (set-real-user) ( id -- ) : (set-real-user) ( id -- )
@ -100,17 +116,17 @@ GENERIC: set-effective-user ( string/id -- )
PRIVATE> PRIVATE>
M: string set-real-user ( string -- )
user-id (set-real-user) ;
M: integer set-real-user ( id -- ) M: integer set-real-user ( id -- )
(set-real-user) ; (set-real-user) ;
M: string set-real-user ( string -- )
?user-id (set-real-user) ;
M: integer set-effective-user ( id -- ) M: integer set-effective-user ( id -- )
(set-effective-user) ; (set-effective-user) ;
M: string set-effective-user ( string -- ) M: string set-effective-user ( string -- )
user-id (set-effective-user) ; ?user-id (set-effective-user) ;
os { os {
{ [ dup bsd? ] [ drop "unix.users.bsd" require ] } { [ dup bsd? ] [ drop "unix.users.bsd" require ] }

View File

@ -1800,7 +1800,7 @@ FUNCTION: BOOL SetProcessPriorityBoost ( HANDLE hProcess, BOOL disablePriorityBo
! FUNCTION: SetProcessWorkingSetSize ! FUNCTION: SetProcessWorkingSetSize
! FUNCTION: SetStdHandle ! FUNCTION: SetStdHandle
! FUNCTION: SetSystemPowerState ! FUNCTION: SetSystemPowerState
! FUNCTION: SetSystemTime FUNCTION: BOOL SetSystemTime ( SYSTEMTIME* lpSystemTime ) ;
! FUNCTION: SetSystemTimeAdjustment ! FUNCTION: SetSystemTimeAdjustment
! FUNCTION: SetTapeParameters ! FUNCTION: SetTapeParameters
! FUNCTION: SetTapePosition ! FUNCTION: SetTapePosition

View File

@ -536,7 +536,6 @@ tuple
{ "set-string-nth-fast" "strings.private" "primitive_set_string_nth_fast" (( ch n string -- )) } { "set-string-nth-fast" "strings.private" "primitive_set_string_nth_fast" (( ch n string -- )) }
{ "(exit)" "system" "primitive_exit" (( n -- * )) } { "(exit)" "system" "primitive_exit" (( n -- * )) }
{ "nano-count" "system" "primitive_nano_count" (( -- ns )) } { "nano-count" "system" "primitive_nano_count" (( -- ns )) }
{ "system-micros" "system" "primitive_system_micros" (( -- us )) }
{ "(sleep)" "threads.private" "primitive_sleep" (( nanos -- )) } { "(sleep)" "threads.private" "primitive_sleep" (( nanos -- )) }
{ "callstack-for" "threads.private" "primitive_callstack_for" (( context -- array )) } { "callstack-for" "threads.private" "primitive_callstack_for" (( context -- array )) }
{ "context-object-for" "threads.private" "primitive_context_object_for" (( n context -- obj )) } { "context-object-for" "threads.private" "primitive_context_object_for" (( n context -- obj )) }

View File

@ -22,6 +22,7 @@ SYMBOL: add-vocab-root-hook
] "vocabs.loader" add-startup-hook ] "vocabs.loader" add-startup-hook
: add-vocab-root ( root -- ) : add-vocab-root ( root -- )
trim-tail-separators
[ vocab-roots get adjoin ] [ vocab-roots get adjoin ]
[ add-vocab-root-hook get-global call( root -- ) ] bi ; [ add-vocab-root-hook get-global call( root -- ) ] bi ;

View File

@ -1,5 +1,5 @@
! (c)2009 Joe Groff bsd license ! (c)2009 Joe Groff bsd license
USING: accessors alien audio classes.struct fry calendar alarms USING: accessors alien audio classes.struct fry calendar timers
combinators combinators.short-circuit destructors generalizations combinators combinators.short-circuit destructors generalizations
kernel literals locals math openal sequences kernel literals locals math openal sequences
sequences.generalizations specialized-arrays strings ; sequences.generalizations specialized-arrays strings ;
@ -70,7 +70,7 @@ TUPLE: audio-engine < disposable
listener listener
{ next-source integer } { next-source integer }
clips clips
update-alarm ; update-timer ;
TUPLE: audio-clip < disposable TUPLE: audio-clip < disposable
{ audio-engine audio-engine } { audio-engine audio-engine }
@ -226,20 +226,20 @@ DEFER: update-audio
: start-audio ( audio-engine -- ) : start-audio ( audio-engine -- )
dup start-audio* dup start-audio*
dup '[ _ update-audio ] 20 milliseconds every >>update-alarm dup '[ _ update-audio ] 20 milliseconds every >>update-timer
drop ; drop ;
: stop-audio ( audio-engine -- ) : stop-audio ( audio-engine -- )
dup al-sources>> [ dup al-sources>> [
{ {
[ make-engine-current ] [ make-engine-current ]
[ update-alarm>> [ stop-alarm ] when* ] [ update-timer>> [ stop-timer ] when* ]
[ clips>> clone [ dispose ] each ] [ clips>> clone [ dispose ] each ]
[ al-sources>> free-sources ] [ al-sources>> free-sources ]
[ [
f >>al-sources f >>al-sources
f >>clips f >>clips
f >>update-alarm f >>update-timer
drop drop
] ]
[ al-context>> alcSuspendContext ] [ al-context>> alcSuspendContext ]

View File

@ -1,5 +1,5 @@
! (c)2009 Joe Groff bsd license ! (c)2009 Joe Groff bsd license
USING: accessors alarms audio audio.engine audio.loader calendar USING: accessors timers audio audio.engine audio.loader calendar
destructors io kernel locals math math.functions math.ranges specialized-arrays destructors io kernel locals math math.functions math.ranges specialized-arrays
sequences random math.vectors ; sequences random math.vectors ;
FROM: alien.c-types => short ; FROM: alien.c-types => short ;
@ -41,10 +41,10 @@ M: noise-generator dispose
] when ] when
engine update-audio engine update-audio
] 20 milliseconds every :> alarm ] 20 milliseconds every :> timer
"Press Enter to stop the test." print "Press Enter to stop the test." print
readln drop readln drop
alarm stop-alarm timer stop-timer
engine dispose ; engine dispose ;
MAIN: audio-engine-test MAIN: audio-engine-test

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1,31 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.c-types classes.struct kernel memory
system vm ;
IN: benchmark.struct
STRUCT: benchmark-data
{ time ulonglong }
{ data-room data-heap-room }
{ code-room mark-sweep-sizes } ;
STRUCT: benchmark-data-pair
{ start benchmark-data }
{ stop benchmark-data } ;
: <benchmark-data> ( -- benchmark-data )
\ benchmark-data <struct>
nano-count >>time
code-room >>code-room
data-room >>data-room ; inline
: <benchmark-data-pair> ( start stop -- benchmark-data-pair )
\ benchmark-data-pair <struct>
swap >>stop
swap >>start ; inline
: with-benchmarking ( ... quot -- ... benchmark-data-pair )
<benchmark-data>
[ call ] dip
<benchmark-data> <benchmark-data-pair> ; inline

View File

@ -0,0 +1,2 @@
Joe Groff
Doug Coleman

View File

@ -0,0 +1,245 @@
! (c)2010 Joe Groff bsd license
USING: accessors arrays assocs calendar calendar.format
combinators combinators.short-circuit fry io io.backend
io.directories io.encodings.binary io.encodings.detect
io.encodings.utf8 io.files io.files.info io.files.types
io.files.unique io.launcher io.pathnames kernel locals math
math.parser namespaces sequences sorting strings system
unicode.categories xml.syntax xml.writer xmode.catalog
xmode.marker xmode.tokens ;
IN: codebook
! Usage: "my/source/tree" codebook
! Writes tree.opf, tree.ncx, and tree.html to a temporary directory
! Writes tree.mobi to resource:codebooks
! Requires kindlegen to compile tree.mobi for Kindle
CONSTANT: codebook-style
{
{ COMMENT1 [ [XML <i><font color="#555555"><-></font></i> XML] ] }
{ COMMENT2 [ [XML <i><font color="#555555"><-></font></i> XML] ] }
{ COMMENT3 [ [XML <i><font color="#555555"><-></font></i> XML] ] }
{ COMMENT4 [ [XML <i><font color="#555555"><-></font></i> XML] ] }
{ DIGIT [ [XML <font color="#333333"><-></font> XML] ] }
{ FUNCTION [ [XML <b><font color="#111111"><-></font></b> XML] ] }
{ KEYWORD1 [ [XML <b><font color="#111111"><-></font></b> XML] ] }
{ KEYWORD2 [ [XML <b><font color="#111111"><-></font></b> XML] ] }
{ KEYWORD3 [ [XML <b><font color="#111111"><-></font></b> XML] ] }
{ KEYWORD4 [ [XML <b><font color="#111111"><-></font></b> XML] ] }
{ LABEL [ [XML <b><font color="#333333"><-></font></b> XML] ] }
{ LITERAL1 [ [XML <font color="#333333"><-></font> XML] ] }
{ LITERAL2 [ [XML <font color="#333333"><-></font> XML] ] }
{ LITERAL3 [ [XML <font color="#333333"><-></font> XML] ] }
{ LITERAL4 [ [XML <font color="#333333"><-></font> XML] ] }
{ MARKUP [ [XML <b><font color="#333333"><-></font></b> XML] ] }
{ OPERATOR [ [XML <b><font color="#111111"><-></font></b> XML] ] }
[ drop ]
}
: first-line ( filename encoding -- line )
[ readln ] with-file-reader ;
TUPLE: code-file
name encoding mode ;
: include-file-name? ( name -- ? )
{
[ path-components [ "." head? ] any? not ]
[ link-info type>> +regular-file+ = ]
} 1&& ;
: code-files ( dir -- files )
'[
[ include-file-name? ] filter [
dup detect-file dup binary?
[ f ] [ 2dup dupd first-line find-mode ] if
code-file boa
] map [ mode>> ] filter [ name>> ] sort-with
] with-directory-tree-files ;
: html-name-char ( char -- str )
{
{ [ dup alpha? ] [ 1string ] }
{ [ dup digit? ] [ 1string ] }
[ >hex 6 CHAR: 0 pad-head "_" "_" surround ]
} cond ;
: file-html-name ( name -- name )
[ html-name-char ] { } map-as concat ".html" append ;
: toc-list ( files -- list )
[ name>> ] map natural-sort [
[ file-html-name ] keep
[XML <li><a href=<->><-></a></li> XML]
] map ;
! insert zero-width non-joiner between all characters so words can wrap anywhere
: zwnj ( string -- s|t|r|i|n|g )
[ CHAR: \u00200c "" 2sequence ] { } map-as concat ;
! We wrap every line in <tt> because Kindle tends to forget the font when
! moving back pages
: htmlize-tokens ( tokens line# -- html-tokens )
swap [
[ str>> zwnj ] [ id>> ] bi codebook-style case
] map [XML <tt><font size="-2" color="#666666"><-></font> <-></tt> XML]
"\n" 2array ;
: line#>string ( i line#len -- i-string )
[ number>string ] [ CHAR: \s pad-head ] bi* ;
:: code>html ( dir file -- page )
file name>> :> name
"Generating HTML for " write name write "..." print flush
dir [ file [ name>> ] [ encoding>> ] bi file-lines ] with-directory :> lines
lines length 1 + number>string length :> line#len
file mode>> load-mode :> rules
f lines [| l i | l rules tokenize-line i 1 + line#len line#>string htmlize-tokens ]
map-index concat nip :> html-lines
<XML <html>
<head>
<title><-name-></title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<h2><-name-></h2>
<pre><-html-lines-></pre>
<mbp:pagebreak xmlns:mbp="http://www.mobipocket.com/mbp" />
</body>
</html> XML> ;
:: code>toc-html ( dir name files -- html )
"Generating HTML table of contents" print flush
now timestamp>rfc822 :> timestamp
dir absolute-path :> source
dir [
files toc-list :> toc
<XML <html>
<head>
<title><-name-></title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<h1><-name-></h1>
<font size="-2">Generated from<br/>
<b><tt><-source-></tt></b><br/>
at <-timestamp-></font><br/>
<br/>
<ul><-toc-></ul>
<mbp:pagebreak xmlns:mbp="http://www.mobipocket.com/mbp" />
</body>
</html> XML>
] with-directory ;
:: code>ncx ( dir name files -- xml )
"Generating NCX table of contents" print flush
files [| file i |
file name>> :> name
name file-html-name :> filename
i 2 + number>string :> istr
[XML <navPoint class="book" id=<-filename-> playOrder=<-istr->>
<navLabel><text><-name-></text></navLabel>
<content src=<-filename-> />
</navPoint> XML]
] map-index :> file-nav-points
<XML <?xml version="1.0" encoding="UTF-8" ?>
<ncx version="2005-1" xmlns="http://www.daisy.org/z3986/2005/ncx/">
<navMap>
<navPoint class="book" id="toc" playOrder="1">
<navLabel><text>Table of Contents</text></navLabel>
<content src="_toc.html" />
</navPoint>
<-file-nav-points->
</navMap>
</ncx> XML> ;
:: code>opf ( dir name files -- xml )
"Generating OPF manifest" print flush
name ".ncx" append :> ncx-name
files [
name>> file-html-name dup
[XML <item id=<-> href=<-> media-type="text/html" /> XML]
] map :> html-manifest
files [ name>> file-html-name [XML <itemref idref=<-> /> XML] ] map :> html-spine
<XML <?xml version="1.0" encoding="UTF-8" ?>
<package
version="2.0"
xmlns="http://www.idpf.org/2007/opf"
unique-identifier=<-name->>
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
<dc:title><-name-></dc:title>
<dc:language>en</dc:language>
<meta name="cover" content="my-cover-image" />
</metadata>
<manifest>
<item href="cover.jpg" id="my-cover-image" media-type="image/jpeg" />
<item id="html-toc" href="_toc.html" media-type="text/html" />
<-html-manifest->
<item id="toc" href=<-ncx-name-> media-type="application/x-dtbncx+xml" />
</manifest>
<spine toc="toc">
<itemref idref="html-toc" />
<-html-spine->
</spine>
<guide>
<reference type="toc" title="Table of Contents" href="_toc.html" />
</guide>
</package> XML> ;
: write-dest-file ( xml dest-dir name ext -- )
append append-path utf8 [ write-xml ] with-file-writer ;
SYMBOL: kindlegen-path
kindlegen-path [ "kindlegen" ] initialize
SYMBOL: codebook-output-path
codebook-output-path [ "resource:codebooks" ] initialize
: kindlegen ( path -- )
[ kindlegen-path get "-unicode" ] dip 3array try-process ;
: kindle-path ( directory name extension -- path )
[ append-path ] dip append ;
:: codebook ( src-dir -- )
codebook-output-path get normalize-path :> dest-dir
"Generating ebook for " write src-dir write " in " write dest-dir print flush
dest-dir make-directories
[
current-temporary-directory get :> temp-dir
src-dir file-name :> name
src-dir code-files :> files
src-dir name files code>opf
temp-dir name ".opf" write-dest-file
"vocab:codebook/cover.jpg" temp-dir copy-file-into
src-dir name files code>ncx
temp-dir name ".ncx" write-dest-file
src-dir name files code>toc-html
temp-dir "_toc.html" "" write-dest-file
files [| file |
src-dir file code>html
temp-dir file name>> file-html-name "" write-dest-file
] each
temp-dir name ".opf" kindle-path kindlegen
temp-dir name ".mobi" kindle-path dest-dir copy-file-into
dest-dir name ".mobi" kindle-path :> mobi-path
"Job's finished: " write mobi-path print flush
] cleanup-unique-working-directory ;

BIN
extra/codebook/cover.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

View File

@ -1,7 +1,7 @@
USING: ui ui.gadgets sequences kernel arrays math colors USING: ui ui.gadgets sequences kernel arrays math colors
colors.constants ui.render ui.pens.polygon ui.pens.solid math.vectors colors.constants ui.render ui.pens.polygon ui.pens.solid math.vectors
accessors fry ui.gadgets.packs game.input ui.gadgets.labels accessors fry ui.gadgets.packs game.input ui.gadgets.labels
ui.gadgets.borders alarms calendar locals strings ui.gadgets.buttons ui.gadgets.borders timers calendar locals strings ui.gadgets.buttons
combinators math.parser assocs threads ; combinators math.parser assocs threads ;
IN: game.input.demos.joysticks IN: game.input.demos.joysticks
@ -73,7 +73,7 @@ CONSTANT: pov-polygons
COLOR: red <indicator-gadget> [ >>indicator ] [ add-gadget ] bi COLOR: red <indicator-gadget> [ >>indicator ] [ add-gadget ] bi
dup [ 0.0 0.0 0.0 move-axis ] [ f move-pov ] bi ; dup [ 0.0 0.0 0.0 move-axis ] [ f move-pov ] bi ;
TUPLE: joystick-demo-gadget < pack axis raxis controller buttons alarm ; TUPLE: joystick-demo-gadget < pack axis raxis controller buttons timer ;
: add-gadget-with-border ( parent child -- parent ) : add-gadget-with-border ( parent child -- parent )
{ 2 2 } <border> COLOR: gray <solid> >>boundary add-gadget ; { 2 2 } <border> COLOR: gray <solid> >>boundary add-gadget ;
@ -108,7 +108,7 @@ TUPLE: joystick-demo-gadget < pack axis raxis controller buttons alarm ;
: kill-update-axes ( gadget -- ) : kill-update-axes ( gadget -- )
COLOR: gray <solid> >>interior COLOR: gray <solid> >>interior
[ [ stop-alarm ] when* f ] change-alarm [ [ stop-timer ] when* f ] change-timer
relayout-1 ; relayout-1 ;
: (update-axes) ( gadget controller-state -- ) : (update-axes) ( gadget controller-state -- )
@ -125,11 +125,11 @@ TUPLE: joystick-demo-gadget < pack axis raxis controller buttons alarm ;
[ (update-axes) ] [ kill-update-axes ] if* ; [ (update-axes) ] [ kill-update-axes ] if* ;
M: joystick-demo-gadget graft* M: joystick-demo-gadget graft*
dup '[ _ update-axes ] FREQUENCY every >>alarm dup '[ _ update-axes ] FREQUENCY every >>timer
drop ; drop ;
M: joystick-demo-gadget ungraft* M: joystick-demo-gadget ungraft*
alarm>> [ stop-alarm ] when* ; timer>> [ stop-timer ] when* ;
: joystick-window ( controller -- ) : joystick-window ( controller -- )
[ <joystick-demo-gadget> ] [ product-string ] bi [ <joystick-demo-gadget> ] [ product-string ] bi

View File

@ -1,6 +1,6 @@
USING: game.input game.input.scancodes USING: game.input game.input.scancodes
kernel ui.gadgets ui.gadgets.buttons sequences accessors kernel ui.gadgets ui.gadgets.buttons sequences accessors
words arrays assocs math calendar fry alarms ui words arrays assocs math calendar fry timers ui
ui.gadgets.borders ui.gestures literals ; ui.gadgets.borders ui.gestures literals ;
IN: game.input.demos.key-caps IN: game.input.demos.key-caps
@ -134,7 +134,7 @@ CONSTANT: key-locations H{
CONSTANT: KEYBOARD-SIZE { 230 65 } CONSTANT: KEYBOARD-SIZE { 230 65 }
CONSTANT: FREQUENCY $[ 1/30 seconds ] CONSTANT: FREQUENCY $[ 1/30 seconds ]
TUPLE: key-caps-gadget < gadget keys alarm ; TUPLE: key-caps-gadget < gadget keys timer ;
: make-key-gadget ( scancode dim array -- ) : make-key-gadget ( scancode dim array -- )
[ [
@ -163,11 +163,11 @@ M: key-caps-gadget pref-dim* drop KEYBOARD-SIZE ;
M: key-caps-gadget graft* M: key-caps-gadget graft*
open-game-input open-game-input
dup '[ _ update-key-caps-state ] FREQUENCY every >>alarm dup '[ _ update-key-caps-state ] FREQUENCY every >>timer
drop ; drop ;
M: key-caps-gadget ungraft* M: key-caps-gadget ungraft*
alarm>> [ stop-alarm ] when* timer>> [ stop-timer ] when*
close-game-input ; close-game-input ;
M: key-caps-gadget handle-gesture M: key-caps-gadget handle-gesture

View File

@ -26,22 +26,6 @@ $nl
{ <game-loop> <game-loop*> } related-words { <game-loop> <game-loop*> } related-words
HELP: benchmark-frames-per-second
{ $values
{ "loop" game-loop }
{ "n" float }
}
{ $description "Returns the average number of times per second the game loop has called " { $link draw* } " on its delegate since the game loop was started with " { $link start-loop } " or since the benchmark counters have been reset with " { $link reset-loop-benchmark } "." } ;
HELP: benchmark-ticks-per-second
{ $values
{ "loop" game-loop }
{ "n" float }
}
{ $description "Returns the average number of times per second the game loop has called " { $link tick* } " on its tick delegate since the game loop was started with " { $link start-loop } " or since the benchmark counters have been reset with " { $link reset-loop-benchmark } "." } ;
{ reset-loop-benchmark benchmark-frames-per-second benchmark-ticks-per-second } related-words
HELP: draw* HELP: draw*
{ $values { $values
{ "tick-slice" float } { "delegate" "a " { $link "game.loop-delegates" } } { "tick-slice" float } { "delegate" "a " { $link "game.loop-delegates" } }
@ -59,12 +43,6 @@ HELP: game-loop-error
} }
{ $description "If an uncaught error is thrown from inside a game loop delegate's " { $link tick* } " or " { $link draw* } ", the game loop will catch the error, stop the game loop, and rethrow an error of this class." } ; { $description "If an uncaught error is thrown from inside a game loop delegate's " { $link tick* } " or " { $link draw* } ", the game loop will catch the error, stop the game loop, and rethrow an error of this class." } ;
HELP: reset-loop-benchmark
{ $values
{ "loop" game-loop }
}
{ $description "Resets the benchmark counters on a " { $link game-loop } ". Subsequent calls to " { $link benchmark-frames-per-second } " and " { $link benchmark-ticks-per-second } " will measure their values from the point " { $snippet "reset-loop-benchmark" } " was called." } ;
HELP: start-loop HELP: start-loop
{ $values { $values
{ "loop" game-loop } { "loop" game-loop }
@ -109,12 +87,6 @@ ARTICLE: "game.loop" "Game loops"
start-loop start-loop
stop-loop stop-loop
} }
"The game loop maintains performance counters:"
{ $subsections
reset-loop-benchmark
benchmark-frames-per-second
benchmark-ticks-per-second
}
"The game loop catches errors that occur in the delegate's methods during the course of the game loop:" "The game loop catches errors that occur in the delegate's methods during the course of the game loop:"
{ $subsections { $subsections
game-loop-error game-loop-error

View File

@ -1,34 +1,38 @@
! (c)2009 Joe Groff bsd license ! (c)2009 Joe Groff bsd license
USING: accessors alarms calendar continuations destructors fry USING: accessors timers alien.c-types calendar classes.struct
kernel math math.order namespaces system ui ui.gadgets.worlds ; continuations destructors fry kernel math math.order memory
namespaces sequences specialized-vectors system
tools.memory ui ui.gadgets.worlds vm vocabs.loader arrays
benchmark.struct locals ;
IN: game.loop IN: game.loop
TUPLE: game-loop TUPLE: game-loop
{ tick-interval-nanos integer read-only } { tick-interval-nanos integer read-only }
tick-delegate tick-delegate
draw-delegate draw-delegate
{ last-tick integer }
{ running? boolean } { running? boolean }
{ tick-number integer } { tick# integer }
{ frame-number integer } { frame# integer }
{ benchmark-time integer } tick-timer
{ benchmark-tick-number integer } draw-timer
{ benchmark-frame-number integer } benchmark-data ;
alarm ;
STRUCT: game-loop-benchmark
{ benchmark-data-pair benchmark-data-pair }
{ tick# ulonglong }
{ frame# ulonglong } ;
SPECIALIZED-VECTOR: game-loop-benchmark
: <game-loop-benchmark> ( benchmark-data-pair tick frame -- obj )
\ game-loop-benchmark <struct>
swap >>frame#
swap >>tick#
swap >>benchmark-data-pair ; inline
GENERIC: tick* ( delegate -- ) GENERIC: tick* ( delegate -- )
GENERIC: draw* ( tick-slice delegate -- ) GENERIC: draw* ( tick-slice delegate -- )
SYMBOL: game-loop
: since-last-tick ( loop -- nanos )
last-tick>> nano-count swap - ;
: tick-slice ( loop -- slice )
[ since-last-tick ] [ tick-interval-nanos>> ] bi /f 1.0 min ;
CONSTANT: MAX-FRAMES-TO-SKIP 5
DEFER: stop-loop DEFER: stop-loop
TUPLE: game-loop-error game-loop error ; TUPLE: game-loop-error game-loop error ;
@ -40,70 +44,69 @@ TUPLE: game-loop-error game-loop error ;
[ drop stop-loop ] [ \ game-loop-error boa ?ui-error ] 2bi ; [ drop stop-loop ] [ \ game-loop-error boa ?ui-error ] 2bi ;
: fps ( fps -- nanos ) : fps ( fps -- nanos )
1,000,000,000 swap /i ; inline [ 1,000,000,000 ] dip /i ; inline
<PRIVATE <PRIVATE
: record-benchmarking ( benchark-data-pair loop -- )
[ tick#>> ]
[ frame#>> <game-loop-benchmark> ]
[ benchmark-data>> ] tri push ;
: last-tick-percent-offset ( loop -- float )
[ draw-timer>> iteration-start-nanos>> nano-count swap - ]
[ tick-interval-nanos>> ] bi /f 1.0 min ;
: redraw ( loop -- ) : redraw ( loop -- )
[ 1 + ] change-frame-number [ 1 + ] change-frame#
[ tick-slice ] [ draw-delegate>> ] bi draw* ; [
[ last-tick-percent-offset ] [ draw-delegate>> ] bi
[ draw* ] with-benchmarking
] keep record-benchmarking ;
: tick ( loop -- ) : tick ( loop -- )
tick-delegate>> tick* ; [
[ tick-delegate>> tick* ] with-benchmarking
] keep record-benchmarking ;
: increment-tick ( loop -- ) : increment-tick ( loop -- )
[ 1 + ] change-tick-number [ 1 + ] change-tick#
dup tick-interval-nanos>> [ + ] curry change-last-tick
drop ; drop ;
: ?tick ( loop count -- )
[ nano-count >>last-tick drop ] [
over [ since-last-tick ] [ tick-interval-nanos>> ] bi >=
[ [ drop increment-tick ] [ drop tick ] [ 1 - ?tick ] 2tri ]
[ 2drop ] if
] if-zero ;
: benchmark-nanos ( loop -- nanos )
nano-count swap benchmark-time>> - ;
PRIVATE> PRIVATE>
: reset-loop-benchmark ( loop -- loop ) :: when-running ( loop quot -- )
nano-count >>benchmark-time [
dup tick-number>> >>benchmark-tick-number loop
dup frame-number>> >>benchmark-frame-number ; dup running?>> quot [ drop ] if
] [
loop game-loop-error
] recover ; inline
: benchmark-ticks-per-second ( loop -- n ) : tick-iteration ( loop -- )
[ tick-number>> ] [ benchmark-tick-number>> - ] [ benchmark-nanos ] tri /f ; [ [ tick ] [ increment-tick ] bi ] when-running ;
: benchmark-frames-per-second ( loop -- n )
[ frame-number>> ] [ benchmark-frame-number>> - ] [ benchmark-nanos ] tri /f ;
: (game-tick) ( loop -- ) : frame-iteration ( loop -- )
dup running?>> [ redraw ] when-running ;
[ [ MAX-FRAMES-TO-SKIP ?tick ] [ redraw ] bi ]
[ drop ] if ;
: game-tick ( loop -- )
dup game-loop [
[ (game-tick) ] [ game-loop-error ] recover
] with-variable ;
: start-loop ( loop -- ) : start-loop ( loop -- )
nano-count >>last-tick
t >>running? t >>running?
reset-loop-benchmark
[ dup
[ '[ _ game-tick ] f ] [ '[ _ tick-iteration ] f ]
[ tick-interval-nanos>> nanoseconds ] bi [ tick-interval-nanos>> nanoseconds ] bi <timer> >>tick-timer
<alarm>
] keep [ alarm<< ] [ drop start-alarm ] 2bi ; dup '[ _ frame-iteration ] f 1 milliseconds <timer> >>draw-timer
[ tick-timer>> ] [ draw-timer>> ] bi [ start-timer ] bi@ ;
: stop-loop ( loop -- ) : stop-loop ( loop -- )
f >>running? f >>running?
alarm>> stop-alarm ; [ tick-timer>> ] [ draw-timer>> ] bi [ stop-timer ] bi@ ;
: <game-loop*> ( tick-interval-nanos tick-delegate draw-delegate -- loop ) : <game-loop*> ( tick-interval-nanos tick-delegate draw-delegate -- loop )
nano-count f 0 0 nano-count 0 0 f f 0 0 f f
game-loop-benchmark-vector{ } clone
game-loop boa ; game-loop boa ;
: <game-loop> ( tick-interval-nanos delegate -- loop ) : <game-loop> ( tick-interval-nanos delegate -- loop )
@ -112,6 +115,4 @@ PRIVATE>
M: game-loop dispose M: game-loop dispose
stop-loop ; stop-loop ;
USE: vocabs.loader
{ "game.loop" "prettyprint" } "game.loop.prettyprint" require-when { "game.loop" "prettyprint" } "game.loop.prettyprint" require-when

View File

@ -1,7 +1,8 @@
! (c)2009 Joe Groff bsd license ! (c)2009 Joe Groff bsd license
USING: accessors combinators fry game.input game.loop generic kernel math USING: accessors audio.engine combinators concurrency.promises
parser sequences ui ui.gadgets ui.gadgets.worlds ui.gestures threads destructors fry game.input game.loop generic kernel math parser
words audio.engine destructors ; sequences threads ui ui.gadgets ui.gadgets.worlds ui.gestures
words words.constant ;
IN: game.worlds IN: game.worlds
TUPLE: game-world < world TUPLE: game-world < world
@ -48,7 +49,7 @@ M: game-world begin-world
[ >>game-loop begin-game-world ] keep start-loop ; [ >>game-loop begin-game-world ] keep start-loop ;
M: game-world end-world M: game-world end-world
[ [ stop-loop ] when* f ] change-game-loop dup game-loop>> [ stop-loop ] when*
[ end-game-world ] [ end-game-world ]
[ audio-engine>> [ dispose ] when* ] [ audio-engine>> [ dispose ] when* ]
[ use-game-input?>> [ close-game-input ] when ] tri ; [ use-game-input?>> [ close-game-input ] when ] tri ;
@ -70,8 +71,18 @@ M: game-world apply-world-attributes
[ call-next-method ] [ call-next-method ]
} cleave ; } cleave ;
: start-game ( attributes -- game-world )
f swap open-window* ;
: wait-game ( attributes -- game-world )
f swap open-window* dup promise>> ?promise drop ;
: define-attributes-word ( word tuple -- )
[ name>> "-attributes" append create-in ] dip define-constant ;
SYNTAX: GAME: SYNTAX: GAME:
CREATE CREATE
game-attributes parse-main-window-attributes game-attributes parse-main-window-attributes
2dup define-attributes-word
parse-definition parse-definition
define-main-window ; define-main-window ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: fry irc.client irc.client.chats kernel namespaces USING: fry irc.client irc.client.chats kernel namespaces
sequences threads io.launcher io splitting sequences threads io.launcher io splitting
make mason.common mason.updates calendar math alarms make mason.common mason.updates calendar math timers
io.encodings.8-bit.latin1 debugger ; io.encodings.8-bit.latin1 debugger ;
IN: irc.gitbot IN: irc.gitbot

View File

@ -1,6 +1,6 @@
! Copyright (C) 2010 Doug Coleman. ! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alarms bit-arrays calendar game.input io USING: accessors timers bit-arrays calendar game.input io
io.binary io.encodings.binary io.files kernel literals math io.binary io.encodings.binary io.files kernel literals math
namespaces system threads ; namespaces system threads ;
IN: key-logger IN: key-logger
@ -28,7 +28,7 @@ SYMBOL: key-logger
] unless ; ] unless ;
: stop-key-logger ( -- ) : stop-key-logger ( -- )
key-logger get-global [ stop-alarm ] when* key-logger get-global [ stop-timer ] when*
f key-logger set-global f key-logger set-global
close-game-input ; close-game-input ;

View File

@ -1,6 +1,7 @@
IN: mason.common.tests IN: mason.common.tests
USING: prettyprint mason.common mason.config USING: prettyprint mason.common mason.config
namespaces calendar tools.test io.files io.files.temp io.encodings.utf8 ; namespaces calendar tools.test io.files
io.files.temp io.encodings.utf8 sequences ;
[ "00:01:02" ] [ 62,000,000,000 nanos>time ] unit-test [ "00:01:02" ] [ 62,000,000,000 nanos>time ] unit-test
@ -11,7 +12,7 @@ namespaces calendar tools.test io.files io.files.temp io.encodings.utf8 ;
] with-scope ] with-scope
] unit-test ] unit-test
[ "/home/bobby/builds/2008-09-11-12-23" ] [ [ t ] [
[ [
"/home/bobby/builds" builds-dir set "/home/bobby/builds" builds-dir set
T{ timestamp T{ timestamp
@ -23,6 +24,7 @@ namespaces calendar tools.test io.files io.files.temp io.encodings.utf8 ;
} datestamp stamp set } datestamp stamp set
build-dir build-dir
] with-scope ] with-scope
"/home/bobby/builds/2008-09-11-12-23" head?
] unit-test ] unit-test
[ ] [ "empty-test" temp-file utf8 [ ] with-file-writer ] unit-test [ ] [ "empty-test" temp-file utf8 [ ] with-file-writer ] unit-test

View File

@ -57,6 +57,7 @@ M: unix really-delete-tree delete-tree ;
[ day>> , ] [ day>> , ]
[ hour>> , ] [ hour>> , ]
[ minute>> , ] [ minute>> , ]
[ drop nano-count , ]
} cleave } cleave
] { } make [ pad-00 ] map "-" join ; ] { } make [ pad-00 ] map "-" join ;

View File

@ -1,9 +1,17 @@
! Copyright (C) 2008, 2010 Eduardo Cavazos, Slava Pestov. ! Copyright (C) 2008, 2010 Eduardo Cavazos, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel io.launcher bootstrap.image.download USING: bootstrap.image.download combinators.short-circuit
mason.common mason.platform ; io.directories io.launcher kernel mason.common mason.platform ;
IN: mason.updates IN: mason.updates
: git-reset-cmd ( -- cmd )
{
"git"
"reset"
"--hard"
"HEAD"
} ;
: git-pull-cmd ( -- cmd ) : git-pull-cmd ( -- cmd )
{ {
"git" "git"
@ -14,6 +22,8 @@ IN: mason.updates
} ; } ;
: updates-available? ( -- ? ) : updates-available? ( -- ? )
".git/index" delete-file
git-reset-cmd short-running-process
git-id git-id
git-pull-cmd short-running-process git-pull-cmd short-running-process
git-id git-id
@ -23,6 +33,4 @@ IN: mason.updates
boot-image-name maybe-download-image ; boot-image-name maybe-download-image ;
: new-code-available? ( -- ? ) : new-code-available? ( -- ? )
updates-available? { [ updates-available? ] [ new-image-available? ] } 0|| ;
new-image-available?
or ;

View File

@ -1,6 +1,6 @@
! Copyright (C) 2009 Doug Coleman. ! Copyright (C) 2009 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alarms arrays calendar combinators USING: accessors timers arrays calendar combinators
combinators.smart continuations debugger http.client fry combinators.smart continuations debugger http.client fry
init io.streams.string kernel locals math math.parser db init io.streams.string kernel locals math math.parser db
namespaces sequences site-watcher.db site-watcher.email ; namespaces sequences site-watcher.db site-watcher.email ;
@ -48,4 +48,4 @@ PRIVATE>
] unless ; ] unless ;
: stop-site-watcher ( -- ) : stop-site-watcher ( -- )
running-site-watcher get [ stop-alarm ] when* ; running-site-watcher get [ stop-timer ] when* ;

View File

@ -229,9 +229,9 @@ M: terrain-world tick-game-world
GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_CLAMP_TO_EDGE glTexParameteri ; GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_CLAMP_TO_EDGE glTexParameteri ;
: sky-gradient ( world -- t ) : sky-gradient ( world -- t )
game-loop>> tick-number>> SKY-PERIOD mod SKY-PERIOD /f ; game-loop>> tick#>> SKY-PERIOD mod SKY-PERIOD /f ;
: sky-theta ( world -- theta ) : sky-theta ( world -- theta )
game-loop>> tick-number>> SKY-SPEED * ; game-loop>> tick#>> SKY-SPEED * ;
M: terrain-world begin-game-world M: terrain-world begin-game-world
"2.0" { "GL_ARB_vertex_buffer_object" "GL_ARB_shader_objects" } "2.0" { "GL_ARB_vertex_buffer_object" "GL_ARB_shader_objects" }

View File

@ -1,10 +1,13 @@
! Copyright (C) 2006, 2007, 2008 Alex Chapman ! Copyright (C) 2006, 2007, 2008 Alex Chapman
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors alarms arrays calendar kernel make math math.rectangles math.parser namespaces sequences system tetris.game tetris.gl ui.gadgets ui.gadgets.labels ui.gadgets.worlds ui.gadgets.status-bar ui.gestures ui.render ui ; USING: accessors timers arrays calendar kernel make math math.rectangles
math.parser namespaces sequences system tetris.game tetris.gl ui.gadgets
ui.gadgets.labels ui.gadgets.worlds ui.gadgets.status-bar ui.gestures
ui.render ui ;
FROM: tetris.game => level>> ; FROM: tetris.game => level>> ;
IN: tetris IN: tetris
TUPLE: tetris-gadget < gadget { tetris tetris } { alarm } ; TUPLE: tetris-gadget < gadget { tetris tetris } { timer } ;
: <tetris-gadget> ( tetris -- gadget ) : <tetris-gadget> ( tetris -- gadget )
tetris-gadget new swap >>tetris ; tetris-gadget new swap >>tetris ;
@ -52,10 +55,10 @@ tetris-gadget H{
[ tetris>> ?update ] [ relayout-1 ] bi ; [ tetris>> ?update ] [ relayout-1 ] bi ;
M: tetris-gadget graft* ( gadget -- ) M: tetris-gadget graft* ( gadget -- )
[ [ tick ] curry 100 milliseconds every ] keep alarm<< ; [ [ tick ] curry 100 milliseconds every ] keep timer<< ;
M: tetris-gadget ungraft* ( gadget -- ) M: tetris-gadget ungraft* ( gadget -- )
[ stop-alarm f ] change-alarm drop ; [ stop-timer f ] change-timer drop ;
: tetris-window ( -- ) : tetris-window ( -- )
[ [

1
extra/time/authors.txt Normal file
View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1,15 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: alien.data calendar calendar.unix classes.struct
io.files.info.unix.private kernel system time unix unix.time ;
IN: time.macosx
M: macosx adjust-time-monotonic
timestamp>timeval
\ timeval <struct>
[ adjtime io-error ] keep dup binary-zero? [
drop instant
] [
timeval>duration since-1970 now time-
] if ;

View File

@ -0,0 +1 @@
macosx

14
extra/time/time.factor Normal file
View File

@ -0,0 +1,14 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: combinators kernel system vocabs.loader ;
IN: time
HOOK: set-time os ( timestamp -- )
HOOK: adjust-time-monotonic os ( timestamp -- seconds )
os {
{ [ dup macosx? ] [ drop "time.macosx" require ] }
{ [ dup windows? ] [ drop "time.windows" require ] }
{ [ dup unix? ] [ drop "time.unix" require ] }
[ drop ]
} cond

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1 @@
unix

View File

@ -0,0 +1,9 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: calendar kernel math system time unix unix.time ;
IN: time.unix
M: unix set-time
[ unix-1970 time- duration>microseconds >integer make-timeval ]
[ timestamp>timezone ] bi
settimeofday io-error ;

View File

@ -0,0 +1 @@
Doug Coleman

View File

@ -0,0 +1 @@
windows

View File

@ -0,0 +1,9 @@
! Copyright (C) 2010 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: calendar.windows system time windows.errors
windows.kernel32 kernel classes.struct calendar ;
IN: time.windows
M: windows set-time
>gmt
timestamp>SYSTEMTIME SetSystemTime win32-error=0/f ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2008, 2010 Slava Pestov. ! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors sequences sorting math math.order USING: kernel accessors sequences sorting math math.order
calendar alarms logging concurrency.combinators namespaces calendar timers logging concurrency.combinators namespaces
db.types db.tuples db fry locals hashtables db.types db.tuples db fry locals hashtables
syndication urls xml.writer validators syndication urls xml.writer validators
html.forms html.forms

View File

@ -123,7 +123,7 @@ void factor_vm::init_factor(vm_parameters *p)
if(p->image_path == NULL) if(p->image_path == NULL)
p->image_path = default_image_path(); p->image_path = default_image_path();
srand((unsigned int)system_micros()); srand((unsigned int)nano_count());
init_ffi(); init_ffi();
init_contexts(p->datastack_size,p->retainstack_size,p->callstack_size); init_contexts(p->datastack_size,p->retainstack_size,p->callstack_size);
init_callbacks(p->callback_size); init_callbacks(p->callback_size);

View File

@ -19,13 +19,6 @@ THREADHANDLE start_thread(void *(*start_routine)(void *),void *args)
static void *null_dll; static void *null_dll;
u64 system_micros()
{
struct timeval t;
gettimeofday(&t,NULL);
return (u64)t.tv_sec * 1000000 + t.tv_usec;
}
void sleep_nanos(u64 nsec) void sleep_nanos(u64 nsec)
{ {
timespec ts; timespec ts;

View File

@ -42,7 +42,6 @@ inline static THREADHANDLE thread_id() { return pthread_self(); }
void signal_handler(int signal, siginfo_t* siginfo, void* uap); void signal_handler(int signal, siginfo_t* siginfo, void* uap);
void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap); void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap);
u64 system_micros();
u64 nano_count(); u64 nano_count();
void sleep_nanos(u64 nsec); void sleep_nanos(u64 nsec);
void open_console(); void open_console();

View File

@ -3,16 +3,6 @@
namespace factor namespace factor
{ {
u64 system_micros()
{
SYSTEMTIME st;
FILETIME ft;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &ft);
return (((s64)ft.dwLowDateTime
| (s64)ft.dwHighDateTime<<32) - EPOCH_OFFSET) / 10;
}
char *strerror(int err) char *strerror(int err)
{ {
/* strerror() is not defined on WinCE */ /* strerror() is not defined on WinCE */

View File

@ -21,7 +21,6 @@ char *getenv(char *name);
#define snprintf _snprintf #define snprintf _snprintf
#define snwprintf _snwprintf #define snwprintf _snwprintf
u64 system_micros();
void c_to_factor_toplevel(cell quot); void c_to_factor_toplevel(cell quot);
void open_console(); void open_console();

View File

@ -8,14 +8,6 @@ THREADHANDLE start_thread(void *(*start_routine)(void *), void *args)
return (void *)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0); return (void *)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, 0);
} }
u64 system_micros()
{
FILETIME t;
GetSystemTimeAsFileTime(&t);
return (((u64)t.dwLowDateTime | (u64)t.dwHighDateTime<<32)
- EPOCH_OFFSET) / 10;
}
u64 nano_count() u64 nano_count()
{ {
static double scale_factor; static double scale_factor;

View File

@ -45,7 +45,6 @@ typedef wchar_t vm_char;
inline static void early_init() {} inline static void early_init() {}
u64 system_micros();
u64 nano_count(); u64 nano_count();
void sleep_nanos(u64 nsec); void sleep_nanos(u64 nsec);
long getpagesize(); long getpagesize();

View File

@ -125,7 +125,6 @@ namespace factor
_(special_object) \ _(special_object) \
_(string) \ _(string) \
_(strip_stack_traces) \ _(strip_stack_traces) \
_(system_micros) \
_(tuple) \ _(tuple) \
_(tuple_boa) \ _(tuple_boa) \
_(unimplemented) \ _(unimplemented) \

View File

@ -8,11 +8,6 @@ void factor_vm::primitive_exit()
exit((int)to_fixnum(ctx->pop())); exit((int)to_fixnum(ctx->pop()));
} }
void factor_vm::primitive_system_micros()
{
ctx->push(from_unsigned_8(system_micros()));
}
void factor_vm::primitive_nano_count() void factor_vm::primitive_nano_count()
{ {
u64 nanos = nano_count(); u64 nanos = nano_count();

View File

@ -146,7 +146,6 @@ struct factor_vm
// run // run
void primitive_exit(); void primitive_exit();
void primitive_system_micros();
void primitive_nano_count(); void primitive_nano_count();
void primitive_sleep(); void primitive_sleep();
void primitive_set_slot(); void primitive_set_slot();