Merge remote-tracking branch 'origin/master' into modern-harvey2

modern-harvey2
Doug Coleman 2018-01-27 09:43:21 -06:00
commit 5d8b912216
132 changed files with 1809 additions and 546 deletions

View File

@ -44,12 +44,5 @@ before_install:
wget https://github.com/vmt/udis86/archive/v1.7.2.tar.gz && tar xzvf v1.7.2.tar.gz &&
( cd udis86-1.7.2/ && ./autogen.sh && ./configure --enable-shared=yes && make && sudo make install ) &&
( [[ "$TRAVIS_OS_NAME" != "osx" ]] && sudo ldconfig || true )
script: >
( echo "=== Bootstrap ===" ; ./build.sh net-bootstrap < /dev/null ; ret=$? ; echo "=== $ret ==="; [ $ret == 0 ] ) &&
( echo "=== Factor Configure Postgresql ===" ; ./factor -e='USING: db.postgresql namespaces memory ; T{ postgresql-db f "localhost" f f f f "postgres" "" } \ postgresql-db set-global save' ; ret=$? ; echo "=== $ret ==="; [ $ret == 0 ] ) &&
( echo "=== Factor Configure Imap ===" ; ./factor -e='USING: imap namespaces memory environment accessors ; T{ imap-settings { host "imap.gmail.com" } } "FACTOR_IMAP_USER" os-env >>email "FACTOR_IMAP_PASSWORD" os-env >>password \ imap-settings set-global save' ; ret=$? ; echo "=== $ret ==="; [ $ret == 0 ] ) &&
( echo "=== Mkdir ===" ; mkdir -p mason/builds ; ret=$? ; echo "=== $ret ==="; [ $ret == 0 ] ) &&
( echo "=== Factor tests ===" ; cd mason/builds && ../../factor -e='USING: namespaces tools.test mason.test benchmark ; f long-unit-tests-enabled? set-global t benchmarks-disabled? set-global do-all' < /dev/null | awk 'NR<1000 || /^Loading resource|Unit Test/' ; ret=${PIPESTATUS[0]} ; echo "=== $ret ==="; [ $ret == 0 ]) &&
( echo "=== Factor report === " ; cd mason && ../factor -e='USING: mason.config mason.report namespaces ; "." builds-dir [ successful-report ] with-variable' ; ret=$? ; echo "=== $ret ==="; [ $ret == 0 ]) &&
( echo "=== Dump report === " ;[[ "$TRAVIS_OS_NAME" != "osx" ]] && links -dump mason/report || cat mason/report ; ret=$? ; echo "=== $ret ==="; [ $ret == 0 ]) &&
[ ! -s mason/test-all-errors ]
script:
- ./build.sh net-bootstrap < /dev/null

View File

@ -1,4 +1,4 @@
Copyright (c) 2017, Slava Pestov, et al.
Copyright (c) 2018, Slava Pestov, et al.
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -75,7 +75,7 @@ Some other simple things you can try in the listener:
1000 [1,b] sum .
4 iota [
4 <iota> [
"Happy Birthday " write
2 = "dear NAME" "to You" ? print
] each

View File

@ -12,7 +12,7 @@ HELP: <bihash>
{ $values { "biassoc" biassoc } }
{ $description "Creates a new biassoc using a pair of hashtables for underlying storage." } ;
HELP: once-at
HELP: set-at-once
{ $values { "value" object } { "key" object } { "assoc" assoc } }
{ $description "If the assoc does not contain the given key, adds the key/value pair to the assoc, otherwise does nothing." } ;

View File

@ -17,11 +17,11 @@ M: biassoc at* from>> at* ; inline
M: biassoc value-at* to>> at* ; inline
: once-at ( value key assoc -- )
: set-at-once ( value key assoc -- )
2dup key? [ 3drop ] [ set-at ] if ;
M: biassoc set-at
[ from>> set-at ] [ swapd to>> once-at ] 3bi ;
[ from>> set-at ] [ swapd to>> set-at-once ] 3bi ;
ERROR: no-biassoc-deletion ;

View File

@ -31,5 +31,5 @@ PRIVATE>
: ?box ( box -- value/f ? )
dup occupied>> [ box-unsafe> t ] [ drop f f ] if ; inline
: if-box? ( box quot -- )
: if-box? ( box quot: ( value -- ) -- )
[ ?box ] dip [ drop ] if ; inline

View File

@ -169,5 +169,4 @@ MACRO: attempt-all-quots ( quots -- quot )
[ instant read-00 >>hour read-00 >>minute ] with-string-reader ;
: hms>duration ( str -- duration )
[ read-hms ] with-string-reader
instant swap >>second swap >>minute swap >>hour ;
[ 0 0 0 read-hms <duration> ] with-string-reader ;

View File

@ -7,17 +7,17 @@ IN: cocoa.touchbar
: make-touchbar ( seq self -- touchbar )
[ NSTouchBar -> alloc -> init dup ] dip -> setDelegate: {
[ swap <CFStringArray> { void { id SEL id } } ?-> setDefaultItemIdentifiers: ]
[ swap <CFStringArray> { void { id SEL id } } ?-> setCustomizationAllowedItemIdentifiers: ]
[ swap <CFStringArray> -> setDefaultItemIdentifiers: ]
[ swap <CFStringArray> -> setCustomizationAllowedItemIdentifiers: ]
[ nip ]
} 2cleave ;
:: make-NSTouchBar-button ( self identifier label-string action-string -- button )
NSCustomTouchBarItem send: alloc
identifier <CFString> { id { id SEL id } } ?send: \initWithIdentifier: :> item
NSCustomTouchBarItem -> alloc
identifier <CFString> -> initWithIdentifier: :> item
NSButton
label-string <CFString>
self
action-string lookup-selector { id { id SEL id id SEL } } ?send: \buttonWithTitle:target:action: :> button
item button send: \setView:
action-string lookup-selector -> buttonWithTitle:target:action: :> button
item button -> setView:
item ;

View File

@ -142,7 +142,7 @@ MACRO: map-reduce-outputs ( quot mapper reducer -- quot )
MACRO: smart-reduce ( reduce-quots -- quot )
unzip [ [ ] like ] bi@ dup length dup '[
[ @ ] dip [ @ _ cleave-curry _ spread* ] each
_ dip [ @ _ cleave-curry _ spread* ] each
] ;
MACRO: smart-map-reduce ( map-reduce-quots -- quot )
@ -154,7 +154,7 @@ MACRO: smart-map-reduce ( map-reduce-quots -- quot )
MACRO: smart-2reduce ( 2reduce-quots -- quot )
unzip [ [ ] like ] bi@ dup length dup '[
[ @ ] 2dip
_ 2dip
[ @ _ [ cleave-curry ] [ cleave-curry ] bi _ spread* ] 2each
] ;

View File

@ -70,7 +70,7 @@ M: ##horizontal-shl-vector-imm insn-available? rep>> %horizontal-shl-vector-imm-
M: ##horizontal-shr-vector-imm insn-available? rep>> %horizontal-shr-vector-imm-reps member? ;
: [vector-op-checked] ( #dup quot -- quot )
'[ _ ndup [ @ ] { } make dup [ insn-available? ] all? ] ;
'[ _ ndup _ { } make dup [ insn-available? ] all? ] ;
GENERIC#: >vector-op-cond 2 ( quot #pick #dup -- quotpair )
M:: callable >vector-op-cond ( quot #pick #dup -- quotpair )

View File

@ -107,7 +107,7 @@ RENAMING: assign "[ vreg>reg ]" "[ vreg>reg ]" "[ vreg>reg ]"
: change-insn-gc-roots ( gc-map-insn quot: ( x -- x ) -- )
[ gc-map>> ] dip [ swap gc-roots>> swap map! drop ]
[ '[ [ [ @ ] bi@ ] assoc-map ] change-derived-roots drop ] 2bi ; inline
[ '[ [ _ bi@ ] assoc-map ] change-derived-roots drop ] 2bi ; inline
: spill-required? ( live-interval root-leaders n -- ? )
[ [ vreg>> ] dip sets::in? ] [ swap covers? ] bi-curry* bi or ;

View File

@ -300,7 +300,7 @@ CONSTANT: lookup-table-at-max 256
\ at* [ at-quot ] 1 define-partial-eval
: diff-quot ( seq -- quot: ( seq' -- seq'' ) )
[ tester ] keep '[ members [ @ ] reject _ set-like ] ;
[ tester ] keep '[ members _ reject _ set-like ] ;
M\\ sets::set diff [ diff-quot ] 1 define-partial-eval

View File

@ -1,5 +1,5 @@
USING: concurrency.count-downs threads kernel tools.test ;
IN: concurrency.count-downs.tests`
IN: concurrency.count-downs.tests
{ } [ 0 <count-down> await ] unit-test

View File

@ -1 +1,2 @@
Chris Double
Alexander Ilin

View File

@ -1,9 +1,11 @@
! Copyright (C) 2005 Chris Double. All Rights Reserved.
! Copyright (C) 2018 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: serialize sequences concurrency.messaging threads io
io.servers io.encodings.binary assocs init
arrays namespaces kernel accessors ;
FROM: io.sockets => host-name <inet> with-client ;
USING: accessors arrays assocs concurrency.messaging
continuations destructors fry init io io.encodings.binary
io.servers io.sockets io.streams.duplex kernel namespaces
sequences serialize threads ;
FROM: concurrency.messaging => send ;
IN: concurrency.distributed
<PRIVATE
@ -11,6 +13,9 @@ IN: concurrency.distributed
: registered-remote-threads ( -- hash )
\ registered-remote-threads get-global ;
: thread-connections ( -- hash )
\ thread-connections get-global ;
PRIVATE>
: register-remote-thread ( thread name -- )
@ -25,8 +30,9 @@ PRIVATE>
SYMBOL: local-node
: handle-node-client ( -- )
deserialize
[ first2 get-remote-thread send ] [ stop-this-server ] if* ;
deserialize [
first2 get-remote-thread send handle-node-client
] [ stop-this-server ] if* ;
: <node-server> ( addrspec -- threaded-server )
binary <threaded-server>
@ -41,19 +47,38 @@ TUPLE: remote-thread node id ;
C: <remote-thread> remote-thread
TUPLE: connection remote stream local ;
C: <connection> connection
: connect ( remote-thread -- )
[ node>> dup binary <client> <connection> ]
[ thread-connections set-at ] bi ;
: disconnect ( remote-thread -- )
thread-connections delete-at*
[ stream>> dispose ] [ drop ] if ;
: with-connection ( remote-thread quot -- )
'[ connect @ ] over [ disconnect ] curry [ ] cleanup ; inline
: send-remote-message ( message node -- )
binary [ serialize ] with-client ;
: send-to-connection ( message connection -- )
stream>> [ serialize flush ] with-stream* ;
M: remote-thread send ( message thread -- )
[ id>> 2array ] [ node>> ] bi
send-remote-message ;
[ id>> 2array ] [ node>> ] [ thread-connections at ] tri
[ nip send-to-connection ] [ send-remote-message ] if* ;
M: thread (serialize) ( obj -- )
id>> [ local-node get insecure>> ] dip <remote-thread> (serialize) ;
: stop-node ( -- )
local-node get insecure>> f swap send-remote-message ;
f local-node get insecure>> send-remote-message ;
[
H{ } clone \ registered-remote-threads set-global
H{ } clone \ thread-connections set-global
] "remote-thread-registry" add-startup-hook

View File

@ -1,4 +1,4 @@
USING: help.markup help.syntax kernel arrays calendar ;
USING: help.markup help.syntax kernel calendar sequences ;
IN: concurrency.mailboxes
HELP: <mailbox>
@ -29,15 +29,19 @@ HELP: block-if-empty
{ $values { "mailbox" mailbox }
{ "timeout" { $maybe duration } }
}
{ $description "Block the thread if the mailbox is empty." } ;
{ $description "Block the thread for " { $snippet "timeout" } " if the mailbox is empty." } ;
HELP: mailbox-get
{ $values { "mailbox" mailbox } { "obj" object } }
{ $description "Get the first item put into the mailbox. If it is empty, the thread blocks until an item is put into it. The thread then resumes, leaving the item on the stack." } ;
HELP: mailbox-get-all-timeout
{ $values { "mailbox" mailbox } { "timeout" { $maybe duration } } { "seq" sequence } }
{ $description "Blocks the thread for " { $snippet "timeout" } " if the mailbox is empty, then removes all objects in the mailbox and returns a sequence containing the objects." } ;
HELP: mailbox-get-all
{ $values { "mailbox" mailbox } { "array" array } }
{ $description "Blocks the thread if the mailbox is empty, otherwise removes all objects in the mailbox and returns an array containing the objects." } ;
{ $values { "mailbox" mailbox } { "seq" sequence } }
{ $description "Blocks the thread if the mailbox is empty, then removes all objects in the mailbox and returns a sequence containing the objects." } ;
HELP: while-mailbox-empty
{ $values { "mailbox" mailbox }
@ -69,7 +73,10 @@ ARTICLE: "concurrency.mailboxes" "Mailboxes"
mailbox-get-timeout?
}
"Emptying out a mailbox:"
{ $subsections mailbox-get-all }
{ $subsections
mailbox-get-all
mailbox-get-all-timeout
}
"Adding an element:"
{ $subsections mailbox-put }
"Testing if a mailbox is empty:"

View File

@ -42,7 +42,7 @@ IN: concurrency.mailboxes.tests
mailbox-get
] unit-test
{ { "foo" "bar" } } [
{ V{ "foo" "bar" } } [
<mailbox>
"foo" over mailbox-put
"bar" over mailbox-put

View File

@ -1,8 +1,8 @@
! Copyright (C) 2005, 2010 Chris Double, Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: dlists deques threads sequences continuations namespaces
math quotations words kernel arrays assocs init system
concurrency.conditions accessors locals fry vocabs.loader ;
USING: accessors concurrency.conditions continuations deques
destructors dlists fry kernel locals sequences threads
vocabs.loader ;
IN: concurrency.mailboxes
TUPLE: mailbox { threads dlist } { data dlist } ;
@ -47,13 +47,10 @@ M: mailbox mailbox-get-timeout block-if-empty data>> pop-back ;
: mailbox-get ( mailbox -- obj )
f mailbox-get-timeout ; inline
: mailbox-get-all-timeout ( mailbox timeout -- array )
block-if-empty
[ dup mailbox-empty? not ]
[ dup data>> pop-back ]
produce nip ;
: mailbox-get-all-timeout ( mailbox timeout -- seq )
block-if-empty data>> [ ] collector [ slurp-deque ] dip ;
: mailbox-get-all ( mailbox -- array )
: mailbox-get-all ( mailbox -- seq )
f mailbox-get-all-timeout ;
: while-mailbox-empty ( mailbox quot -- )
@ -68,8 +65,9 @@ M: mailbox mailbox-get-timeout block-if-empty data>> pop-back ;
f swap mailbox-get-timeout? ; inline
: wait-for-close-timeout ( mailbox timeout -- )
over disposed>>
[ 2drop ] [ 2dup wait-for-mailbox wait-for-close-timeout ] if ;
'[
_ 2dup wait-for-mailbox wait-for-close-timeout
] unless-disposed ;
: wait-for-close ( mailbox -- )
f wait-for-close-timeout ;

View File

@ -49,7 +49,7 @@ HELP: zero-extendable?
{ $values { "imm" integer } { "?" boolean } }
{ $description "All positive 32-bit numbers are zero extendable except for 0 which is the value used for relocations." } ;
ARTICLE: "cpu.x86.assembler" "X86 assembler"
ARTICLE: "cpu.x86.assembler" "CPU x86 assembler"
"This vocab implements an assembler for x86 architectures."
$nl
"General instructions:"

View File

@ -0,0 +1,16 @@
! Copyright (C) 2017 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: help.markup help.syntax kernel math quotations strings ;
IN: cpu.x86.features
HELP: instruction-count
{ $values
{ "n" number }
}
{ $description "The word returns the CPU's Timestamp Counter: " { $url "http://en.wikipedia.org/wiki/Time_Stamp_Counter" } "." } ;
ARTICLE: "cpu.x86.features" "CPU x86 features"
{ $vocab-link "cpu.x86.features" }
;
ABOUT: "cpu.x86.features"

View File

@ -9,6 +9,8 @@ math.functions.integer-logs splitting multiline ;
FROM: math.parser.private => format-float ;
IN: formatting
ERROR: unknown-format-directive value ;
<PRIVATE
: compose-all ( seq -- quot )
@ -91,8 +93,6 @@ IN: formatting
[ [ ".0" ?tail drop ] [ drop ] if-zero ] bi
] [ format-decimal-simple ] if ;
ERROR: unknown-printf-directive ;
EBNF: parse-printf [=[
zero = "0" => [[ char: 0 ]]
@ -126,7 +126,7 @@ fmt-E = digits "E" => [[ first '[ _ format-scientific >upper ] ]]
fmt-f = digits "f" => [[ first '[ _ format-decimal ] ]]
fmt-x = "x" => [[ [ >integer >hex ] ]]
fmt-X = "X" => [[ [ >integer >hex >upper ] ]]
unknown = (.)* => [[ unknown-printf-directive ]]
unknown = (.)* => [[ "" like unknown-format-directive ]]
strings_ = fmt-c|fmt-C|fmt-s|fmt-S|fmt-u
strings = pad width strings_ => [[ <reversed> compose-all ]]
@ -235,7 +235,7 @@ fmt-X = "X" => [[ [ >time ] ]]
fmt-y = "y" => [[ [ year>> 100 mod pad-00 ] ]]
fmt-Y = "Y" => [[ [ year>> number>string ] ]]
fmt-Z = "Z" => [[ [ "Not yet implemented" throw ] ]]
unknown = (.)* => [[ "Unknown directive" throw ]]
unknown = (.)* => [[ "" like unknown-format-directive ]]
formats_ = fmt-%|fmt-a|fmt-A|fmt-b|fmt-B|fmt-c|fmt-d|fmt-H|fmt-I|
fmt-j|fmt-m|fmt-M|fmt-p|fmt-S|fmt-U|fmt-w|fmt-W|fmt-x|

View File

@ -78,7 +78,7 @@ M: linux x>hid-bit-order
} ; inline
: x-bits>hid-bits ( bit-array -- bit-array )
256 <iota> [ 2array ] { } 2map-as [ first ] filter values
256 <iota> { } zip-as [ first ] filter values
x>hid-bit-order [ nth ] curry map
256 <bit-array> swap [ t swap pick set-nth ] each ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2010 Anton Gorenko.
! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.libraries alien.syntax combinators
gobject-introspection kernel system vocabs vocabs.loader ;
gobject-introspection kernel system vocabs ;
IN: gdk.gl.ffi
<<

View File

@ -2,8 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: alien alien.c-types alien.destructors alien.libraries
alien.syntax combinators gobject-introspection
gobject-introspection.standard-types kernel pango.ffi system
vocabs ;
gobject-introspection.standard-types kernel pango.ffi system vocabs ;
IN: gtk.ffi
<<

View File

@ -1,5 +1,5 @@
USING: kernel namespaces interval-maps tools.test ;
IN: interval-maps.test
IN: interval-maps.tests
SYMBOL: test

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: inverse tools.test arrays math kernel sequences
math.functions math.constants continuations combinators.smart ;
IN: inverse-tests
IN: inverse.tests
{ 2 } [ { 3 2 } [ 3 swap 2array ] undo ] unit-test
[ { 3 4 } [ dup 2array ] undo ] must-fail

View File

@ -1,6 +1,6 @@
USING: io.encodings.strict io.encodings.ascii tools.test
arrays io.encodings.string ;
IN: io.encodings.strict.test
IN: io.encodings.strict.tests
{ { 0xfffd } } [ { 128 } ascii decode >array ] unit-test
[ { 128 } ascii strict decode ] must-fail

View File

@ -1,7 +1,7 @@
! Copyright (C) 2007, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.c-types alien.data assocs combinators
continuations environment io.backend io.backend.unix
continuations environment fry io.backend io.backend.unix
io.files.private io.files.unix io.launcher io.launcher.private
io.pathnames io.ports kernel libc math namespaces sequences
simple-tokenizer strings system unix unix.ffi unix.process ;
@ -92,7 +92,7 @@ IN: io.launcher.unix
M: unix (current-process) ( -- handle ) getpid ;
M: unix (run-process) ( process -- pid )
[ spawn-process ] curry [ ] with-fork ;
'[ _ spawn-process ] [ ] with-fork ;
M: unix (kill-process) ( process -- )
[ handle>> SIGTERM ] [ group>> ] bi {
@ -102,8 +102,7 @@ M: unix (kill-process) ( process -- )
} case io-error ;
: find-process ( handle -- process )
processes get swap [ nip swap handle>> = ] curry
assoc-find 2drop ;
processes get keys [ handle>> = ] with find nip ;
TUPLE: signal n ;

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs kernel linked-assocs math sequences
tools.test ;
IN: linked-assocs.test
IN: linked-assocs.tests
{ { 1 2 3 } } [
<linked-hash> 1 "b" pick set-at

View File

@ -470,10 +470,11 @@ $nl
W-
W*
}
"Converting a number to the nearest even/odd:"
"Converting a number to the nearest even/odd/signed:"
{ $subsections
>even
>odd
>signed
}
"Bitfields:"
{ $subsections

View File

@ -214,7 +214,7 @@ CONSTANT: log10-2 0x1.34413509f79ffp-2
: (bignum-log) ( n log-quot: ( x -- y ) log-2 -- log )
[ dup ] dip '[
dup representable-as-float?
[ >float @ ] [ frexp [ @ ] [ _ * ] bi* + ] if
[ >float @ ] [ frexp _ [ _ * ] bi* + ] if
] call ; inline
PRIVATE>

View File

@ -237,7 +237,7 @@ M: sequence square-cols
[ length ] keep [ <array> ] with { } map-as ;
: make-matrix-with-indices ( m n quot -- matrix )
[ [ <iota> ] bi@ ] dip '[ @ ] cartesian-map ; inline
[ [ <iota> ] bi@ ] dip cartesian-map ; inline
: null-matrix? ( matrix -- ? ) empty? ; inline

View File

@ -8,7 +8,11 @@ USING:
tools.test ;
IN: openssl.libcrypto.tests
{ t } [ "factorcode.org:80" BIO_new_connect bio_st? ] unit-test
{ t 1 } [
"factorcode.org:80" BIO_new_connect [
bio_st?
] keep BIO_free
] unit-test
{ 1 1 } [
"factorcode.org:80" BIO_new_connect [

View File

@ -123,7 +123,7 @@ PRIVATE>
MACRO: unpack ( str -- quot )
expand-pack-format
[ [ ch>packed-length ] { } map-as start/end ]
[ [ unpack-table at '[ @ ] ] { } map-as ] bi
[ [ unpack-table at ] { } map-as ] bi
[ '[ [ _ _ ] dip <slice> @ ] ] 3map
'[ [ _ cleave ] output>array ] ;

View File

@ -1,6 +1,6 @@
IN: porter-stemmer.tests
USING: arrays io kernel porter-stemmer sequences tools.test
io.files io.encodings.utf8 ;
USING: arrays assocs io kernel porter-stemmer sequences
tools.test io.files io.encodings.utf8 ;
{ 0 } [ "xa" consonant-seq ] unit-test
{ 0 } [ "xxaa" consonant-seq ] unit-test
@ -60,5 +60,5 @@ io.files io.encodings.utf8 ;
"vocab:porter-stemmer/test/voc.txt" utf8 file-lines
[ stem ] map
"vocab:porter-stemmer/test/output.txt" utf8 file-lines
[ 2array ] 2map [ first2 = ] reject
zip [ = ] assoc-reject
] unit-test

View File

@ -46,7 +46,7 @@ ERROR: acquire-crypto-context-failed provider type error ;
initialize-crypto-context ; inline
M: windows-crypto-context random-bytes* ( n windows-crypto-context -- bytes )
handle>> swap [ ] [ <byte-array> ] bi
handle>> swap dup <byte-array>
[ CryptGenRandom win32-error=0/f ] keep ;
! Some Windows installations still don't work, so just set

View File

@ -1,6 +1,6 @@
USING: arrays regexp tools.test kernel sequences regexp.parser
regexp.private eval strings multiline accessors ;
IN: regexp-tests
IN: regexp.tests
{ f } [ "b" "a*" <regexp> matches? ] unit-test
{ t } [ "" "a*" <regexp> matches? ] unit-test

View File

@ -1,5 +1,4 @@
USING: assocs kernel sequences tools.test ;
IN: tools.completion
USING: assocs kernel sequences tools.completion tools.test ;
{ f } [ "abc" "def" fuzzy ] unit-test
{ V{ 4 5 6 } } [ "set-nth" "nth" fuzzy ] unit-test
@ -30,3 +29,8 @@ IN: tools.completion
{ f } [ { "char:" } complete-char? ] unit-test
{ t } [ { "char:" "" } complete-char? ] unit-test
{ t } [ { "char:" "a" } complete-char? ] unit-test
{ f } [ { "FROM:" } complete-vocab-words? ] unit-test
{ f } [ { "FROM:" "math" } complete-vocab-words? ] unit-test
{ t } [ { "FROM:" "math" "=>" } complete-vocab-words? ] unit-test
{ f } [ { "FROM:" "math" "=>" "+" ";" } complete-vocab-words? ] unit-test
{ f } [ { "BOOM:" "math" "=>" "+" } complete-vocab-words? ] unit-test

View File

@ -84,6 +84,9 @@ PRIVATE>
: vocabs-matching ( str -- seq )
all-disk-vocabs-recursive filter-vocabs name-completions ;
: vocab-words-matching ( str vocab -- seq )
vocab-words name-completions ;
: chars-matching ( str -- seq )
name-map keys dup zip completions ;
@ -114,8 +117,10 @@ PRIVATE>
<PRIVATE
: (complete-single-vocab?) ( str -- ? )
{ "IN:" "USE:" "UNUSE:" "QUALIFIED:" "QUALIFIED-WITH:" }
member? ; inline
{
"IN:" "USE:" "UNUSE:" "QUALIFIED:"
"QUALIFIED-WITH:" "FROM:" "EXCLUDE:"
} member? ; inline
: complete-single-vocab? ( tokens -- ? )
dup last empty? [
@ -136,6 +141,13 @@ PRIVATE>
: complete-vocab? ( tokens -- ? )
{ [ complete-single-vocab? ] [ complete-vocab-list? ] } 1|| ;
: complete-vocab-words? ( tokens -- ? )
harvest chop-; {
[ length 3 >= ]
[ first { "FROM:" "EXCLUDE:" } member? ]
[ third "=>" = ]
} 1&& ;
<PRIVATE
: complete-token? ( tokens token -- ? )

View File

@ -59,7 +59,7 @@ delete-staging-images
! { } [ "bunny" shake-and-bake 2559640 small-enough? ] long-unit-test
{ } [ "bunny" shake-and-bake 2700000 small-enough? ] long-unit-test
{ } [ "gpu.demos.bunny" shake-and-bake 3630000 small-enough? ] long-unit-test
{ } [ "gpu.demos.bunny" shake-and-bake 3640000 small-enough? ] long-unit-test
os macosx? [
[ ] [ "webkit-demo" shake-and-bake 600000 small-enough? ] long-unit-test

View File

@ -17,12 +17,7 @@ ERROR: not-a-vocab-root string ;
<PRIVATE
: vocab-root? ( string -- ? )
trim-tail-separators
vocab-roots get member? ;
: contains-dot? ( string -- ? ) ".." swap subseq? ;
: contains-separator? ( string -- ? ) [ path-separator? ] any? ;
trim-tail-separators vocab-roots get member? ;
: ensure-vocab-exists ( string -- string )
dup loaded-vocab-names member? [ no-vocab ] unless ;
@ -41,8 +36,7 @@ ERROR: not-a-vocab-root string ;
[ ] [ replace-vocab-separators ] bi* append-path ;
: vocab>path ( vocab -- path )
check-vocab
[ find-vocab-root ] keep vocab-root/vocab>path ;
check-vocab [ find-vocab-root ] keep vocab-root/vocab>path ;
: vocab-root/vocab/file>path ( vocab-root vocab file -- path )
[ vocab-root/vocab>path ] dip append-path ;
@ -147,12 +141,9 @@ M: string add-using drop ;
M: object add-using ( object -- )
vocabulary>> using get [ adjoin ] [ drop ] if* ;
: 4bl ( -- )
" " write ; inline
: ($values.) ( array -- )
[
4bl
" " write
[ bl ] [
"{ " write
dup array? [ first ] when
@ -186,16 +177,13 @@ M: object add-using ( object -- )
] when* ;
: class-description. ( word -- )
drop
"{ $class-description \"\" } ;" print ;
drop "{ $class-description \"\" } ;" print ;
: symbol-description. ( word -- )
drop
"{ $var-description \"\" } ;" print ;
drop "{ $var-description \"\" } ;" print ;
: $description. ( word -- )
drop
"{ $description \"\" } ;" print ;
drop "{ $description \"\" } ;" print ;
: docs-body. ( word/symbol -- )
{

View File

@ -76,10 +76,10 @@ M: pasteboard set-clipboard-contents
! after register-window.
dup { 0 0 } = [
drop
ui-windows get-global length 1 <= [ send: center ] [
ui-windows get-global last second window-loc>>
dupd first2 <CGPoint> send: \cascadeTopLeftFromPoint:
send: \setFrameTopLeftPoint:
worlds get-global length 1 <= [ -> center ] [
worlds get-global last second window-loc>>
dupd first2 <CGPoint> -> \cascadeTopLeftFromPoint:
-> \setFrameTopLeftPoint:
] if
] [ first2 <CGPoint> send: \setFrameTopLeftPoint: ] if ;
@ -222,8 +222,13 @@ M: cocoa-ui-backend (with-ui)
stop-io-thread
init-thread-timer
reset-thread-timer
<<<<<<< HEAD
NSApp send: run
] ui-running
=======
NSApp -> run
] with-ui-running
>>>>>>> origin/master
] with-cocoa ;
cocoa-ui-backend ui-backend set-global

View File

@ -162,16 +162,24 @@ CONSTANT: selector>action H{
[ swap world-focus parents-handle-gesture? t ] [ drop f f ] if* ;
: touchbar-commands ( -- commands/f gadget )
world get [
world get-global [
children>> [
class-of "commands" word-prop
"touchbar" of dup [ commands>> ] when
] map-find
] [ f f ] if* ;
TUPLE: send-touchbar-command target command ;
M: send-touchbar-command send-queued-gesture
[ target>> ] [ command>> ] bi invoke-command ;
: touchbar-invoke-command ( n -- )
[ touchbar-commands ] dip over
[ rot nth second invoke-command ] [ 3drop ] if ;
[ touchbar-commands ] dip over [
rot nth second
send-touchbar-command queue-gesture notify-ui-thread
yield
] [ 3drop ] if ;
<CLASS: FactorView < NSOpenGLView
COCOA-PROTOCOL: NSTextInput

View File

@ -78,6 +78,7 @@ M: gtk-clipboard set-clipboard-contents
:: with-timer ( quot -- )
<timer-funcs> &free
GSource heap-size g_source_new &g_source_unref :> source
source G_PRIORITY_DEFAULT_IDLE g_source_set_priority
source f g_source_attach drop
[ quot call( -- ) ]
[ source g_source_destroy ] [ ] cleanup ;
@ -512,7 +513,7 @@ M: gtk-ui-backend (with-ui)
[
[ [ gtk_main ] with-timer ] with-event-loop
] with-destructors
] ui-running ;
] with-ui-running ;
M: gtk-ui-backend stop-event-loop
gtk_main_quit ;

View File

@ -712,7 +712,7 @@ M: windows-ui-backend (with-ui)
start-ui
event-loop
] [ cleanup-win32-ui ] [ ] cleanup
] ui-running ;
] with-ui-running ;
M: windows-ui-backend beep ( -- )
0 MessageBeep drop ;

View File

@ -327,7 +327,7 @@ M: x11-ui-backend (with-ui) ( quot -- )
event-loop
] with-xim
] with-x
] ui-running ;
] with-ui-running ;
M: x11-ui-backend beep ( -- )
dpy get 100 XBell drop ;

View File

@ -3,4 +3,4 @@ IN: ui.event-loop
HELP: event-loop?
{ $values { "?" boolean } }
{ $description { $link t } " if there is active windows." } ;
{ $description { $link t } " if there are active windows." } ;

View File

@ -7,7 +7,7 @@ IN: ui.event-loop
: event-loop? ( -- ? )
{
{ [ graft-queue deque-empty? not ] [ t ] }
{ [ ui-windows get-global empty? not ] [ t ] }
{ [ worlds get-global empty? not ] [ t ] }
[ f ]
} cond ;

View File

@ -8,7 +8,7 @@ HELP: <multiline-editor>
{ $description "Creates a new multi-line editor gadget." } ;
HELP: editor
{ $class-description "An editor is a control for editing a multi-line passage of text stored in a " { $link document } " model. Editors are crated by calling " { $link <editor> } "."
{ $class-description "An editor is a control for editing a multi-line passage of text stored in a " { $link document } " model. Editors are created by calling " { $link <editor> } "."
$nl
"Editors have the following slots:"
{ $list

View File

@ -6,6 +6,11 @@ HELP: <gadget>
{ $values { "gadget" "a new " { $link gadget } } }
{ $description "Creates a new gadget." } ;
HELP: children-on
{ $values { "rect" rect } { "gadget" gadget } { "seq" "a sequence of gadgets" } }
{ $contract "Outputs a sequence of gadgets which potentially intersect a rectangle in the co-ordinate system of the gadget." }
{ $notes "This does not have to be an accurate intersection test, and simply returning " { $link children>> } " is a valid implementation. However, an accurate intersection test reduces the amount of work done when drawing this gadget if it is partially clipped and not all children are visible." } ;
HELP: control-value
{ $values { "control" gadget } { "value" object } }
{ $description "Outputs the value of the control's model." } ;
@ -19,6 +24,10 @@ HELP: notify
{ $description "Notifies the gadget that it has a graft message to handle." }
{ $see-also graft* ungraft* } ;
HELP: notify-ui-thread
{ $description "Notifies the UI thread that there is work to do." }
{ $see-also ui-notify-flag } ;
HELP: nth-gadget
{ $values { "n" "a non-negative integer" } { "gadget" gadget } { "child" gadget } }
{ $description "Outputs the " { $snippet "n" } "th child of the gadget." }
@ -37,11 +46,6 @@ HELP: user-input*
{ $values { "str" string } { "gadget" gadget } { "?" boolean } }
{ $contract "Handle free-form textual input while the gadget has keyboard focus." } ;
HELP: children-on
{ $values { "rect" rect } { "gadget" gadget } { "seq" "a sequence of gadgets" } }
{ $contract "Outputs a sequence of gadgets which potentially intersect a rectangle in the co-ordinate system of the gadget." }
{ $notes "This does not have to be an accurate intersection test, and simply returning " { $link children>> } " is a valid implementation. However, an accurate intersection test reduces the amount of work done when drawing this gadget if it is partially clipped and not all children are visible." } ;
HELP: pick-up
{ $values { "point" "a pair of integers" } { "gadget" gadget } { "child/f" { $maybe gadget } } }
{ $description "Outputs the child at a point in the gadget's co-ordinate system. This word recursively descends the gadget hierarchy, and so outputs the deepest child." } ;
@ -70,7 +74,7 @@ HELP: relayout
HELP: relayout-1
{ $values { "gadget" gadget } }
{ $description "Relayout and redraw a gadget before the next iteration of the event loop. Unlike " { $link relayout } ", this does not propagate requests up to the parent, and so this word should only be used when the gadget's internal layout or appearance has changed, but the dimensions have not." } ;
{ $description "Relayout and redraw a gadget before the next iteration of the event loop. Unlike " { $link relayout } ", this does not propagate requests up to the parent, and so this word should be used when the gadget's internal layout or appearance has changed, but the dimensions have not." } ;
{ relayout relayout-1 } related-words

View File

@ -54,7 +54,9 @@ TUPLE: world-attributes
gadgets
{ pixel-format-attributes initial: $ default-world-pixel-format-attributes }
{ window-controls initial: $ default-world-window-controls }
pref-dim ;
pref-dim
{ fill initial: 1 }
{ orientation initial: $ vertical } ;
: <world-attributes> ( -- world-attributes )
world-attributes new ; inline
@ -102,8 +104,7 @@ TUPLE: world-attributes
ERROR: no-world-found ;
: find-gl-context ( gadget -- )
find-world dup
[ set-gl-context ] [ no-world-found ] if ;
find-world [ set-gl-context ] [ no-world-found ] if* ;
: (request-focus) ( child world ? -- )
pick parent>> pick eq? [
@ -141,6 +142,8 @@ M: world apply-world-attributes
[ grab-input?>> >>grab-input? ]
[ gadgets>> dup sequence? [ [ 1 track-add ] each ] [ 1 track-add ] if ]
[ pref-dim>> >>pref-dim ]
[ fill>> >>fill ]
[ orientation>> >>orientation ]
} cleave ;
: <world> ( world-attributes -- world )
@ -212,14 +215,12 @@ ui-error-hook [ [ rethrow ] ] initialize
: draw-world ( world -- )
dup draw-world? [
dup world [
[
dup [ draw-world* ] with-gl-context
flush-layout-cache-hook get call( -- )
] [
swap f >>active? <world-error> throw
] recover
] with-variable
[
dup [ draw-world* ] with-gl-context
flush-layout-cache-hook get call( -- )
] [
swap f >>active? <world-error> throw
] recover
] [ drop ] if ;
world

View File

@ -30,7 +30,7 @@ HELP: parents-handle-gesture?
HELP: propagate-gesture
{ $values { "gesture" "a gesture" } { "gadget" gadget } }
{ $description "Calls " { $link handle-gesture } " on every parent of " { $snippet "gadget" } "." } ;
{ $description "Calls " { $link handle-gesture } " on every parent of the " { $snippet "gadget" } ", starting with the " { $snippet "gadget" } " itself." } ;
HELP: motion
{ $class-description "Mouse motion gesture." }
@ -261,7 +261,9 @@ ARTICLE: "gesture-differences" "Gesture handling differences between platforms"
}
"On Windows, " { $link key-up } " gestures are not reported for all keyboard events."
$nl
{ $link "multitouch-gestures" } " are only supported on Mac OS X." ;
{ $link "multitouch-gestures" } " are only supported on Mac OS X."
$nl
{ $link "filedrop-gestures" } " are only supported on Windows." ;
ARTICLE: "ui-gestures" "UI gestures"
"User actions such as keyboard input and mouse button clicks deliver " { $emphasis "gestures" } " to gadgets. If the direct receiver of the gesture does not handle it, the gesture is passed on to the receiver's parent, and this way it travels up the gadget hierarchy. Gestures which are not handled at some point are ignored."
@ -283,6 +285,7 @@ $nl
{ $subsections
"mouse-gestures"
"multitouch-gestures"
"filedrop-gestures"
}
"Guidelines for cross-platform applications:"
{ $subsections "gesture-differences" }
@ -418,6 +421,18 @@ $nl
zoom-out-action
} ;
ARTICLE: "filedrop-gestures" "File drop gestures"
"File drop gestures are only supported on Windows. When user drags-and-drops a file or a group of files from another application, the following gesture can be handled:"
{ $subsections file-drop } ;
HELP: file-drop
{ $class-description "File drop gesture. The " { $slot "mods" } " slot contains the keyboard modifiers active at the time of the drop (see " { $link "keyboard-gestures" } "). The " { $link dropped-files } " global variable contains an array of full paths of the files that were dropped."
$nl
"The " { $link hand-loc } " global variable contains the drop location. If the user dropped files onto the non-client area of a window (the caption or the border), the gesture will not be triggered, but the contents of the " { $link dropped-files } " will be updated." } ;
HELP: dropped-files
{ $var-description "The global variable holds an array of full paths of the files that were dropped by the last " { $link file-drop } " gesture." } ;
ARTICLE: "action-gestures" "Action gestures"
"Action gestures exist to keep keyboard shortcuts for common application operations consistent."
{ $subsections

View File

@ -79,6 +79,9 @@ M: user-input-tuple send-queued-gesture
TUPLE: drag # ; C: <drag> drag
TUPLE: button-up mods # ; C: <button-up> button-up
TUPLE: button-down mods # ; C: <button-down> button-down
TUPLE: file-drop mods ; C: <file-drop> file-drop
SYMBOL: dropped-files
SINGLETONS:
motion
@ -357,6 +360,8 @@ M: button-down gesture>string
#>> [ " " % # ] when*
] "" make ;
M: file-drop gesture>string drop "Drop files" ;
M: left-action gesture>string drop "Swipe left" ;
M: right-action gesture>string drop "Swipe right" ;

View File

@ -17,6 +17,9 @@ HELP: +keyboard+
HELP: +primary+
{ $description "A key which may be set in the hashtable passed to " { $link define-operation } ". If set to a true value, this operation becomes the default operation performed when a presentation matching the operation's predicate is clicked with the mouse." } ;
HELP: +secondary+
{ $description "A key which may be set in the hashtable passed to " { $link define-operation } ". If set to a true value, this operation becomes the default operation performed when " { $snippet "RET" } " is pressed while a presentation matching the operation's predicate is selected in a list." } ;
HELP: operation
{ $description "An abstraction for an operation which may be performed on a presentation."
$nl

View File

@ -104,9 +104,9 @@ M: gadget gadget-foreground dup interior>> pen-foreground ;
] with-translation ;
: draw-border ( object -- )
dup boundary>> dup [
dup boundary>> [
origin get [ draw-boundary ] with-translation
] [ 2drop ] if ;
] [ drop ] if* ;
PRIVATE>

View File

@ -226,6 +226,8 @@ browser-gadget "multi-touch" f {
} define-command-map
browser-gadget "touchbar" f {
{ f com-back }
{ f com-forward }
{ f com-home }
{ f browser-help }
{ f glossary }

View File

@ -28,9 +28,13 @@ SLOT: history
TUPLE: word-completion manifest ;
C: <word-completion> word-completion
TUPLE: vocab-word-completion vocab-name ;
C: <vocab-word-completion> vocab-word-completion
SINGLETONS: vocab-completion color-completion char-completion
path-completion history-completion ;
UNION: definition-completion word-completion vocab-completion ;
UNION: definition-completion word-completion
vocab-word-completion vocab-completion ;
UNION: listener-completion definition-completion
color-completion char-completion path-completion history-completion ;
@ -40,6 +44,7 @@ GENERIC: completion-quot ( interactor completion-mode -- quot )
2nip '[ [ { } ] _ if-empty ] ; inline
M: word-completion completion-quot [ words-matching ] (completion-quot) ;
M: vocab-word-completion completion-quot nip vocab-name>> '[ _ vocab-words-matching ] ;
M: vocab-completion completion-quot [ vocabs-matching ] (completion-quot) ;
M: color-completion completion-quot [ colors-matching ] (completion-quot) ;
M: char-completion completion-quot [ chars-matching ] (completion-quot) ;
@ -54,6 +59,7 @@ M: history-completion completion-element drop one-line-elt ;
GENERIC: completion-banner ( completion-mode -- string )
M: word-completion completion-banner drop "Words" ;
M: vocab-word-completion completion-banner drop "Words" ;
M: vocab-completion completion-banner drop "Vocabularies" ;
M: color-completion completion-banner drop "Colors" ;
M: char-completion completion-banner drop "Unicode code point names" ;
@ -80,6 +86,8 @@ M: word-completion row-color
[ color: dark-gray ]
} cond 2nip ;
M: vocab-word-completion row-color 2drop COLOR: black ;
M: vocab-completion row-color
drop dup vocab? [
name>> ".private" tail? color: dark-red color: black ?
@ -98,6 +106,7 @@ M: color-completion row-color
{ [ dup complete-char? ] [ 2drop char-completion ] }
{ [ dup complete-color? ] [ 2drop color-completion ] }
{ [ dup complete-pathname? ] [ 2drop path-completion ] }
{ [ dup complete-vocab-words? ] [ nip harvest second <vocab-word-completion> ] }
[ drop <word-completion> ]
} cond ;

View File

@ -56,6 +56,9 @@ M: word-completion (word-at-caret)
'[ _ _ search-manifest ] [ drop f ] recover
] [ drop f ] if* ;
M: vocab-word-completion (word-at-caret)
vocab-name>> lookup-word ;
M: char-completion (word-at-caret) 2drop f ;
M: path-completion (word-at-caret) 2drop f ;
@ -444,6 +447,11 @@ interactor "completion" f {
\ com-auto-use H{ { +nullary+ t } { +listener+ t } } define-command
: com-file-drop ( -- files )
dropped-files get-global ;
\ com-file-drop H{ { +nullary+ t } { +listener+ t } } define-command
listener-gadget "toolbar" f {
{ f restart-listener }
{ T{ key-down f { A+ } "u" } com-auto-use }
@ -472,6 +480,11 @@ listener-gadget "touchbar" f {
{ f com-help }
} define-command-map
listener-gadget "file-drop" "Files can be drag-and-dropped onto the listener."
{
{ T{ file-drop f f } com-file-drop }
} define-command-map
M: listener-gadget graft*
[ call-next-method ] [ restart-listener ] bi ;

View File

@ -1,8 +1,8 @@
USING: editors help.markup help.syntax summary inspector io io.styles
listener parser prettyprint tools.walker ui.commands
ui.gadgets.panes ui.gadgets.presentations ui.operations
ui.tools.operations ui.tools.common vocabs see
help.tips ;
ui.gadgets.panes ui.gadgets.presentations ui.gestures
ui.operations ui.tools.operations ui.tools.common
vocabs see help.tips ;
IN: ui.tools
ARTICLE: "starting-ui-tools" "Starting the UI tools"
@ -41,9 +41,12 @@ $nl
"Dropping a source file onto the Factor icon in the dock runs the source file in the listener."
$nl
"If you install " { $strong "Factor.app" } " in your " { $strong "Applications" } " folder, then other applications will be able to call Factor via the System Services feature. For example, you can select some text in " { $strong "TextEdit.app" } ", then invoke the " { $strong "TextEdit->Services->Factor->Evaluate Selection" } " menu item, which will replace the selected text with the result of evaluating it in Factor."
;
ARTICLE: "ui-windows" "Functionality specific to Windows"
"Files can be dropped from other applications onto the listener window to push their names onto the stack:"
{ $subsections "filedrop-gestures" } ;
ARTICLE: "ui-tools" "UI developer tools"
"The " { $vocab-link "ui.tools" } " vocabulary hierarchy implements a collection of simple developer tools."
{ $subsections "starting-ui-tools" }
@ -65,7 +68,10 @@ $nl
"ui.tools.deploy"
}
"Platform-specific features:"
{ $subsections "ui-cocoa" } ;
{ $subsections
"ui-cocoa"
"ui-windows"
} ;
TIP: "All UI developer tools support a common set of " { $link "ui-shortcuts" } ". Each individual tool has its own shortcuts as well; the F1 key is context-sensitive." ;

View File

@ -6,18 +6,34 @@ vocabs.loader ;
IN: ui
HELP: ui-windows
{ $var-description "Global variable holding an association list mapping native window handles to " { $link world } " instances." } ;
{ ui-windows open-window find-window world-attributes } related-words
HELP: close-window
{ $values { "gadget" gadget } }
{ $description "Close the native window containing " { $snippet "gadget" } "." } ;
HELP: open-window
{ $values { "gadget" gadget } { "title/attributes" { "a " { $link string } " or a " { $link world-attributes } " tuple" } } }
{ $description "Opens a native window containing " { $snippet "gadget" } " with the specified attributes. If a string is provided, it is used as the window title; otherwise, the window attributes are specified in a " { $link world-attributes } " tuple." } ;
HELP: close-window
{ $values { "gadget" gadget } }
{ $description "Close the native window containing " { $snippet "gadget" } "." } ;
HELP: set-fullscreen
{ $values { "gadget" gadget } { "?" boolean } }
{ $description "Sets and unsets fullscreen mode for the gadget's world." } ;
HELP: set-up-window
{ $values { "world" world } }
{ $description "Initializes the window that shows the world." } ;
HELP: ui-thread
{ $var-description "Holds a reference to the running UI thread. This variable is used to ensure that there can only be one UI thread running at the same time." }
{ $see-also start-ui-thread } ;
HELP: ui-running?
{ $values { "?" boolean } }
{ $description "Whether the UI is running or not." } ;
HELP: worlds
{ $var-description "Global variable holding an association list mapping native window handles to " { $link world } " instances." } ;
{ worlds open-window find-window world-attributes } related-words
HELP: world-attributes
{ $values { "world-class" class } { "title" string } { "status" gadget } { "gadgets" sequence } { "pixel-format-attributes" sequence } { "window-controls" sequence } }
@ -31,32 +47,28 @@ HELP: world-attributes
{ { $snippet "window-controls" } " is a sequence of " { $link "ui.gadgets.worlds-window-controls" } " that will be placed in the window." }
} ;
HELP: set-fullscreen
{ $values { "gadget" gadget } { "?" boolean } }
{ $description "Sets and unsets fullscreen mode for the gadget's world." } ;
HELP: set-up-window
{ $values { "world" world } }
{ $description "Initializes the window that shows the world." } ;
HELP: fullscreen?
{ $values { "gadget" gadget } { "?" boolean } }
{ $description "Queries the gadget's world to see if it is running in fullscreen mode." } ;
{ fullscreen? set-fullscreen } related-words
HELP: find-windows
{ $values { "quot" { $quotation ( world -- ? ) } } { "seq" sequence } }
{ $description "Finds all native windows such that the gadget passed to " { $link open-window } " satisfies the quotation, outputting an empty sequence if no such gadget could be found. The front-most native window is the last in the " { $snippet "seq" } "." } ;
HELP: find-window
{ $values { "quot" { $quotation ( world -- ? ) } } { "world/f" { $maybe world } } }
{ $description "Finds a native window such that the gadget passed to " { $link open-window } " satisfies the quotation, outputting " { $link f } " if no such gadget could be found. The front-most native window is checked first." } ;
HELP: register-window
{ $values { "world" world } { "handle" "a backend-specific handle" } }
{ $description "Adds a window to the global " { $link ui-windows } " variable." }
{ $description "Adds a window to the global " { $link worlds } " variable." }
{ $notes "This word should only be called by the UI backend. User code can open new windows with " { $link open-window } "." } ;
HELP: unregister-window
{ $values { "handle" "a backend-specific handle" } }
{ $description "Removes a window from the global " { $link ui-windows } " variable." }
{ $description "Removes a window from the global " { $link worlds } " variable." }
{ $notes "This word should only be called only by the UI backend, and not user code." } ;
HELP: (with-ui)
@ -114,7 +126,7 @@ ARTICLE: "building-ui" "Building user interfaces"
"ui-geometry"
"ui-layouts"
"gadgets"
"ui-windows"
"ui-worlds"
"ui.gadgets.status-bar"
}
{ $see-also "models" } ;
@ -148,13 +160,13 @@ ARTICLE: "ui-geometry" "Gadget geometry"
children-on
} ;
ARTICLE: "ui-windows" "Top-level windows"
ARTICLE: "ui-worlds" "Top-level windows"
"Opening a top-level window:"
{ $subsections open-window }
"Finding top-level windows:"
{ $subsections find-window }
"Top-level windows are stored in a global variable:"
{ $subsections ui-windows }
{ $subsections worlds }
"When a gadget is displayed in a top-level window, or added to a parent which is already showing in a top-level window, a generic word is called allowing the gadget to perform initialization tasks:"
{ $subsections graft* }
"When the gadget is removed from a parent shown in a top-level window, or when the top-level window is closed, a corresponding generic word is called to clean up:"

View File

@ -11,10 +11,10 @@ IN: ui
<PRIVATE
! Assoc mapping aliens to gadgets
SYMBOL: ui-windows
! Assoc mapping aliens to worlds
SYMBOL: worlds
: window ( handle -- world ) ui-windows get-global at ;
: window ( handle -- world ) worlds get-global at ;
: register-window ( world handle -- )
! Add the new window just below the topmost window. Why?
@ -23,15 +23,15 @@ SYMBOL: ui-windows
! in the new window when it appears) Factor doesn't get
! confused and send workspace operations to the new window,
! etc.
swap 2array ui-windows get-global push
ui-windows get-global dup length 1 >
swap 2array worlds get-global push
worlds get-global dup length 1 >
[ [ length 1 - dup 1 - ] keep exchange ] [ drop ] if ;
: unregister-window ( handle -- )
ui-windows [ [ first = ] with reject ] change-global ;
worlds [ [ first = ] with reject ] change-global ;
: raised-window ( world -- )
ui-windows get-global
worlds get-global
[ [ second eq? ] with find drop ] keep
[ nth ] [ remove-nth! drop ] [ nip ] 2tri push ;
@ -105,7 +105,7 @@ M: world ungraft*
<dlist> \ graft-queue set-global
100 <vector> \ layout-queue set-global
<dlist> \ gesture-queue set-global
V{ } clone ui-windows set-global ;
V{ } clone worlds set-global ;
: update-hand ( world -- )
dup hand-world get-global eq?
@ -132,28 +132,35 @@ M: world ungraft*
redraw-worlds
send-queued-gestures ;
: ui-running ( quot -- )
t \ ui-running set-global
[ f \ ui-running set-global ] [ ] cleanup ; inline
SYMBOL: ui-running
: with-ui-running ( quot -- )
t ui-running set-global
[ f ui-running set-global ] [ ] cleanup ; inline
PRIVATE>
: find-window ( quot: ( world -- ? ) -- world/f )
[ ui-windows get-global values ] dip
: find-windows ( quot: ( world -- ? ) -- seq )
[ worlds get-global values ] dip
'[ dup children>> [ ] [ nip first ] if-empty @ ]
find-last nip ; inline
filter ; inline
: find-window ( quot: ( world -- ? ) -- world/f )
find-windows ?last ; inline
: ui-running? ( -- ? )
\ ui-running get-global ;
ui-running get-global ;
<PRIVATE
SYMBOL: ui-thread
: update-ui-loop ( -- )
! Note the logic: if update-ui fails, we open an error window and
! run one iteration of update-ui. If that also fails, well, the
! whole UI subsystem is broken so we throw the error to terminate
! the update-ui-loop.
[ ui-running? ]
[ { [ ui-running? ] [ ui-thread get-global self eq? ] } 0&& ]
[
ui-notify-flag get lower-flag
[ update-ui ] [
@ -164,7 +171,8 @@ PRIVATE>
] while ;
: start-ui-thread ( -- )
[ update-ui-loop ] "UI update" spawn drop ;
[ self ui-thread set-global update-ui-loop ]
"UI update" spawn drop ;
: start-ui ( quot -- )
call( -- ) notify-ui-thread start-ui-thread ;
@ -197,7 +205,7 @@ PRIVATE>
find-world raise-window* ;
: topmost-window ( -- world )
ui-windows get-global last second ;
worlds get-global last second ;
HOOK: close-window ui-backend ( gadget -- )
@ -205,7 +213,7 @@ M: object close-window
find-world [ ungraft ] when* ;
[
f \ ui-running set-global
f ui-running set-global
<flag> ui-notify-flag set-global
] "ui" add-startup-hook

View File

@ -1,26 +1,18 @@
! Copyright (C) 2008, 2009 Joe Groff, Slava Pestov.
! Copyright (C) 2017 Alexander Ilin.
! Copyright (C) 2017-2018 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien.accessors alien.data alien.strings
classes.struct io.encodings.utf16n kernel make math namespaces
prettyprint sequences specialized-arrays
ui.gadgets.worlds ui.tools.listener windows.com
windows.com.wrapper windows.kernel32 windows.ole32
windows.shell32 windows.types ;
specialized-arrays.instances.alien.c-types.ushort
ui.backend.windows ui.gadgets.worlds ui.gestures
ui.tools.listener windows.com windows.com.wrapper
windows.dropfiles windows.kernel32 windows.ole32 windows.shell32
windows.types ;
SPECIALIZED-ARRAY: WCHAR
IN: windows.dragdrop-listener
: filecount-from-hdrop ( hdrop -- n )
0xFFFFFFFF f 0 DragQueryFile ;
: filenames-from-hdrop ( hdrop -- filenames )
dup filecount-from-hdrop <iota>
[
2dup f 0 DragQueryFile 1 + ! get size of filename buffer
dup WCHAR <c-array>
[ swap DragQueryFile drop ] keep
utf16n alien>string
] with map ;
CONSTANT: E_OUTOFMEMORY -2147024882 ! 0x8007000e
: handle-data-object ( handler: ( hdrop -- x ) data-object -- filenames )
FORMATETC <struct>
@ -42,9 +34,9 @@ IN: windows.dragdrop-listener
: filecount-from-data-object ( data-object -- n )
\ filecount-from-hdrop swap handle-data-object ;
TUPLE: listener-dragdrop hWnd last-drop-effect ;
TUPLE: listener-dragdrop world last-drop-effect ;
: <listener-dragdrop> ( hWnd -- object )
: <listener-dragdrop> ( world -- object )
DROPEFFECT_NONE listener-dragdrop boa ;
<<
@ -55,27 +47,24 @@ SYMBOL: +listener-dragdrop-wrapper+
{
{ IDropTarget {
[ ! HRESULT DragEnter ( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect )
[
2drop filecount-from-data-object
1 = DROPEFFECT_COPY DROPEFFECT_NONE ?
dup
] dip 0 set-alien-unsigned-4
>>last-drop-effect drop
DROPEFFECT_COPY swap 0 set-alien-unsigned-4 3drop
DROPEFFECT_COPY >>last-drop-effect drop
S_OK
] [ ! HRESULT DragOver ( DWORD grfKeyState, POINTL pt, DWORD* pdwEffect )
[ 2drop last-drop-effect>> ] dip 0 set-alien-unsigned-4
[
2drop
[ world>> children>> first hand-gadget set-global ]
[ last-drop-effect>> ] bi
] dip 0 set-alien-unsigned-4
S_OK
] [ ! HRESULT DragLeave ( )
drop S_OK
] [ ! HRESULT Drop ( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect )
[
2drop nip
filenames-from-data-object
dup length 1 = [
first unparse [ "USE: parser " % % " run-file" % ] "" make
eval-listener
DROPEFFECT_COPY
] [ drop DROPEFFECT_NONE ] if
filenames-from-data-object dropped-files set-global
key-modifiers <file-drop> hand-gadget get-global propagate-gesture
DROPEFFECT_COPY
] dip 0 set-alien-unsigned-4
S_OK
]
@ -84,6 +73,10 @@ SYMBOL: +listener-dragdrop-wrapper+
>>
: dragdrop-listener-window ( -- )
world get handle>> hWnd>> dup <listener-dragdrop>
+listener-dragdrop-wrapper+ get-global com-wrap
[ RegisterDragDrop check-ole32-error ] with-com-interface ;
world get dup <listener-dragdrop>
+listener-dragdrop-wrapper+ get-global com-wrap [
[ handle>> hWnd>> ] dip
2dup RegisterDragDrop dup E_OUTOFMEMORY =
[ drop ole-initialize RegisterDragDrop ] [ 2nip ] if
check-ole32-error
] with-com-interface ;

View File

@ -0,0 +1 @@
Alexander Ilin

View File

@ -0,0 +1,53 @@
! Copyright (C) 2017-2018 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays help.markup help.syntax kernel math
ui.backend.windows ui.gestures windows.types ;
IN: windows.dropfiles
ABOUT: "windows-dropfiles"
ARTICLE: "windows-dropfiles" "File drop gesture for Windows"
"A window has to declare whether it wants to accept dropped files. By default files are rejected:"
{ $subsections
accept-files
reject-files
world-accept-files
world-reject-files
}
"When user drops files onto a window, the target gadget may handle the corresponding gesture:"
{ $subsections file-drop }
"Implementation details:"
{ $subsections
"about-dragdrop"
init-message-filter
} ;
ARTICLE: "about-dragdrop" "File drag-and-drop in Windows"
"There are two mechanisms in Windows that can be used to drag-and-drop files across applications:"
{ $list
{ { $snippet "WM_DROPFILES" } " - was introduced back in the early days, it is a message that's posted to a window's message queue after the user has dropped some files on it. While handling the message, the application can fetch the list of the dropped files and the mouse position of the drop." }
{ { $snippet "IDropTarget" } " - an OLE reinvention of the same. It provides more fine-grained capabilities of dynamically accepting or rejecting the drop based on the mouse location and the contents of the drop, while the user still drags the files over the window." }
}
"Windows Vista has introduced some security features that made it impossible for the OLE to work between two applications with different security tokens. E.g. if one of the applications is ran with administrative privileges, and the other is without, the OLE drag-and-drop will not work between them."
$nl
"By default, WM_DROPFILES doesn't work either, because the necessary window messages are filtered out from the queue, but it is possible to configure the filters and make it work, see " { $link init-message-filter } "." ;
HELP: init-message-filter
{ $description "Call " { $snippet "ChangeWindowMessageFilter" } " to allow the window messages necessary for file dropping pass through the filters. This will have a process-wide effect, and will only be called once."
$nl
"The API function is only available since Windows Vista, and is not needed in earlier versions. On Windows XP the missing function will cause an exception on the first call, which will be suppressed, and no more calls will be made." }
{ $notes "It is generally preferrable to use " { $snippet "ChangeWindowMessageFilterEx" } ", because it has a per-window-handle effect, thus gives a more fine-grained security control. Unfortunately, the " { $snippet "Ex" } "-version is only available since Windows 7, and in any case the " { $link add-wm-handler } " has global effect for all Factor native windows, so it's not like we are exposing any additional code to potential exploitation." } ;
HELP: filecount-from-hdrop
{ $values
{ "hdrop" HDROP }
{ "n" number }
}
{ $description "Return the number of files in the drop." } ;
HELP: filenames-from-hdrop
{ $values
{ "hdrop" HDROP }
{ "filenames" array }
}
{ $description "Return an array of file names in the drop. Each file name is a string with a full path to a file or a folder." } ;

View File

@ -0,0 +1,67 @@
! Copyright (C) 2017-2018 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien alien.data alien.libraries alien.strings
continuations fry init io.encodings.utf16n kernel literals math
namespaces sequences ui.backend.windows ui.gadgets.worlds
ui.gestures windows.errors windows.messages windows.shell32
windows.types windows.user32 ;
IN: windows.dropfiles
: filecount-from-hdrop ( hdrop -- n )
0xFFFFFFFF f 0 DragQueryFile ;
: filenames-from-hdrop ( hdrop -- filenames )
dup filecount-from-hdrop <iota>
[
2dup f 0 DragQueryFile 1 + ! get size of filename buffer
dup WCHAR <c-array>
[ swap DragQueryFile drop ] keep
utf16n alien>string
] with map ;
! : point-from-hdrop ( hdrop -- loc )
! POINT <struct> [ DragQueryPoint drop ] keep [ x>> ] [ y>> ] bi 2array ;
: handle-wm-dropfiles ( hdrop -- )
<alien> [ filenames-from-hdrop dropped-files set-global ] [ DragFinish ] bi
key-modifiers <file-drop> hand-gadget get-global propagate-gesture ;
! The ChangeWindowMessageFilter has a global per-process effect, and so is the
! list of wm-handlers. Therefore, there is no benefit in using the stricter
! ChangeWindowMessageFilterEx approach. Plus, the latter is not in Vista.
: (init-message-filter) ( -- )
"ChangeWindowMessageFilter" "user32" dlsym? [
${ WM_DROPFILES WM_COPYDATA WM_COPYGLOBALDATA }
[ MSGFLT_ADD ChangeWindowMessageFilter win32-error=0/f ] each
] when ;
: do-once ( guard-variable quot -- )
dupd '[ t _ set-global @ ] [ get-global ] dip unless ; inline
: init-message-filter ( -- )
\ init-message-filter [ (init-message-filter) ] do-once ;
: install-wm-handler ( -- )
[ drop 2nip handle-wm-dropfiles 0 ] WM_DROPFILES add-wm-handler ;
: hwnd-accept-files ( hwnd -- )
TRUE DragAcceptFiles init-message-filter install-wm-handler ;
: hwnd-reject-files ( hwnd -- )
FALSE DragAcceptFiles ;
: world-accept-files ( world -- )
handle>> hWnd>> hwnd-accept-files ;
: world-reject-files ( world -- )
handle>> hWnd>> hwnd-reject-files ;
: accept-files ( -- )
world get world-accept-files ;
: reject-files ( -- )
world get world-reject-files ;
[
f \ init-message-filter set-global
] "init-dropfiles" add-startup-hook

View File

@ -0,0 +1 @@
windows

View File

@ -0,0 +1 @@
Implementation of the file-drop gesture for Windows

View File

@ -248,7 +248,7 @@ ENUM: StringAlignment
{ StringAlignmentCenter 1 }
{ StringAlignmentFar 2 } ;
ENUM: StringDigitSubstitute
ENUM: StringDigitSubstitute
{ StringDigitSubstituteUser 0 }
{ StringDigitSubstituteNone 1 }
{ StringDigitSubstituteNational 2 }

View File

@ -1861,7 +1861,7 @@ FUNCTION: DWORD SetFilePointerEx ( HANDLE hFile, LARGE_INTEGER lDistanceToMove,
! FUNCTION: SetFileShortNameA
! FUNCTION: SetFileShortNameW
FUNCTION: BOOL SetFileTime ( HANDLE hFile, FILETIME* lpCreationTime, FILETIME* lpLastAccessTime, FILETIME* lpLastWriteTime )
! FUNCTION: SetFileValidData
FUNCTION: BOOL SetFileValidData ( HANDLE hFile, LONGLONG ValidDataLength )
! FUNCTION: SetFirmwareEnvironmentVariableA
! FUNCTION: SetFirmwareEnvironmentVariableW
! FUNCTION: SetHandleContext

View File

@ -69,6 +69,7 @@ CONSTANT: WM_COMMNOTIFY 0x0044
CONSTANT: WM_WINDOWPOSCHANGING 0x0046
CONSTANT: WM_WINDOWPOSCHANGED 0x0047
CONSTANT: WM_POWER 0x0048
CONSTANT: WM_COPYGLOBALDATA 0x0049
CONSTANT: WM_COPYDATA 0x004A
CONSTANT: WM_CANCELJOURNAL 0x004B
CONSTANT: WM_NOTIFY 0x004E

View File

@ -231,7 +231,6 @@ STRUCT: DROPFILES
{ fWide BOOL } ;
TYPEDEF: DROPFILES* LPDROPFILES
TYPEDEF: DROPFILES* LPCDROPFILES
TYPEDEF: HANDLE HDROP
STRUCT: SHITEMID
{ cb USHORT }
@ -309,10 +308,16 @@ COM-INTERFACE: IShellFolder IUnknown {000214E6-0000-0000-C000-000000000046}
FUNCTION: HRESULT SHGetDesktopFolder ( IShellFolder** ppshf )
FUNCTION: void DragAcceptFiles ( HWND hWnd, BOOL fAccept )
FUNCTION: UINT DragQueryFileW ( HDROP hDrop,
UINT iFile,
LPWSTR lpszFile,
UINT cch )
ALIAS: DragQueryFile DragQueryFileW
FUNCTION: BOOL DragQueryPoint ( HDROP hDrop, POINT* lppt )
FUNCTION: void DragFinish ( HDROP hDrop )
FUNCTION: BOOL IsUserAnAdmin ( )

View File

@ -1008,6 +1008,18 @@ STRUCT: DEVMODE
TYPEDEF: DEVMODE* PDEVMODE
TYPEDEF: DEVMODE* LPDEVMODE
CONSTANT: MSGFLT_ADD 1
CONSTANT: MSGFLT_REMOVE 2
CONSTANT: MSGFLT_RESET 0
CONSTANT: MSGFLT_ALLOW 1
CONSTANT: MSGFLT_DISALLOW 2
STRUCT: CHANGEFILTERSTRUCT
{ cbSize DWORD }
{ ExtStatus DWORD } ;
TYPEDEF: CHANGEFILTERSTRUCT* PCHANGEFILTERSTRUCT
LIBRARY: user32
FUNCTION: HKL ActivateKeyboardLayout ( HKL hkl, UINT Flags )
@ -1052,6 +1064,16 @@ ALIAS: ChangeDisplaySettingsEx ChangeDisplaySettingsExW
ALIAS: ChangeDisplaySettings ChangeDisplaySettingsW
! FUNCTION: ChangeMenuA
! FUNCTION: ChangeMenuW
FUNCTION: BOOL ChangeWindowMessageFilter (
UINT message,
DWORD dwFlag )
FUNCTION: BOOL ChangeWindowMessageFilterEx (
HWND hWnd,
UINT message,
DWORD action,
PCHANGEFILTERSTRUCT pChangeFilterStruct )
! FUNCTION: CharLowerA
! FUNCTION: CharLowerBuffA
! FUNCTION: CharLowerBuffW

View File

@ -1,5 +1,5 @@
USING: alien.libraries.finder sequences tools.test ;
IN: alien.libraries.fidner.linux
IN: alien.libraries.finder.linux.tests
{ t } [ "libm.so" "m" find-library subseq? ] unit-test
{ t } [ "libc.so" "c" find-library subseq? ] unit-test

View File

@ -40,13 +40,8 @@ CONSTANT: mach-map {
: ldconfig-matches? ( lib triple -- ? )
{ [ name-matches? ] [ arch-matches? ] } 2&& ;
: ldconfig-find-soname ( lib -- seq )
load-ldconfig-cache [ ldconfig-matches? ] with filter
[ third ] map ;
PRIVATE>
M: linux find-library*
"lib" prepend ldconfig-find-soname [
{ [ exists? ] [ file-info regular-file? ] } 1&&
] find nip ;
"lib" prepend load-ldconfig-cache
[ ldconfig-matches? ] with find nip ?first ;

View File

@ -41,7 +41,7 @@ HELP: checksum-file
{ $example
"USING: checksums checksums.crc32 prettyprint ;"
"\"resource:LICENSE.txt\" crc32 checksum-file ."
"B{ 47 65 106 90 }"
"B{ 125 29 106 28 }"
}
} ;

View File

@ -1,5 +1,5 @@
USING: accessors compiler.units kernel locals.types tools.test words ;
IN: locals.types.test
IN: locals.types.tests
{ t } [
[ "hello" <local> ] with-compilation-unit "local?" word-prop

View File

@ -1343,7 +1343,7 @@ HELP: sift
{ $values
{ "seq" sequence }
{ "newseq" sequence } }
{ $description "Outputs a new sequence with all instance of " { $link f } " removed." }
{ $description "Outputs a new sequence with all instances of " { $link f } " removed." }
{ $examples
{ $example "USING: prettyprint sequences ;"
"{ \"a\" 3 { } f } sift ."

View File

@ -41,20 +41,18 @@ TUPLE: merge-state
push-all-unsafe ; inline
: l-next ( merge -- )
[ [ l-elt ] [ [ 1 + ] change-from1 drop ] bi ] [ accum>> ] bi
push-unsafe ; inline
[ l-elt ] [ [ 1 + ] change-from1 accum>> ] bi push-unsafe ; inline
: r-next ( merge -- )
[ [ r-elt ] [ [ 1 + ] change-from2 drop ] bi ] [ accum>> ] bi
push-unsafe ; inline
[ r-elt ] [ [ 1 + ] change-from2 accum>> ] bi push-unsafe ; inline
: decide ( merge quot: ( elt1 elt2 -- <=> ) -- ? )
: decide? ( merge quot: ( elt1 elt2 -- <=> ) -- ? )
[ [ l-elt ] [ r-elt ] bi ] dip call +gt+ eq? ; inline
: (merge) ( merge quot: ( elt1 elt2 -- <=> ) -- )
over r-done? [ drop dump-l ] [
over l-done? [ drop dump-r ] [
2dup decide
2dup decide?
[ over r-next ] [ over l-next ] if
(merge)
] if

View File

@ -122,7 +122,7 @@ M: f (literal) current-word get bad-macro-input ;
GENERIC: known>callable ( known -- quot )
: ?@ ( x -- y )
dup callable? [ drop [ @ ] ] unless ;
dup callable? [ drop _ ] unless ;
M: object known>callable drop \ _ ;

View File

@ -671,16 +671,16 @@ HELP: \nan:
HELP: \GENERIC:
{ $syntax "GENERIC: word ( stack -- effect )" }
{ $values { "word" "a new word to define" } }
{ $description "Defines a new generic word in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." } ;
{ $description "Defines a new generic word in the current vocabulary. The word dispatches on the topmost stack element. Initially it contains no methods, and thus will throw a " { $link no-method } " error when called." } ;
HELP: \GENERIC#:
{ $syntax "GENERIC#: word n ( stack -- effect )" }
{ $values { "word" "a new word to define" } { "n" "the stack position to dispatch on" } }
{ $description "Defines a new generic word which dispatches on the " { $snippet "n" } "th most element from the top of the stack in the current vocabulary. Initially, it contains no methods, and thus will throw a " { $link no-method } " error when called." }
{ $description "Defines a new generic word in the current vocabulary. The word dispatches on the " { $snippet "n" } "th element from the top of the stack. Initially it contains no methods, and thus will throw a " { $link no-method } " error when called." }
{ $notes
"The following two definitions are equivalent:"
{ $code "GENERIC: foo ( obj -- )" }
{ $code "GENERIC#: foo 0 ( obj -- )" }
{ $code "GENERIC: foo ( x y z obj -- )" }
{ $code "GENERIC#: foo 0 ( x y z obj -- )" }
} ;
HELP: \MATH:

View File

@ -45,7 +45,7 @@ GENERIC: lookup-vocab ( vocab-spec -- vocab )
M: vocab lookup-vocab ;
M: object lookup-vocab ( name -- vocab ) vocab-name dictionary get at ;
M: object lookup-vocab vocab-name dictionary get at ;
GENERIC: vocab-words-assoc ( vocab-spec -- assoc/f )

View File

@ -2,12 +2,13 @@
! Copyright (C) 2011 Anton Gorenko.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays boids.simulation calendar classes
colors.constants combinators.smart.syntax kernel locals math
math.functions math.trig models opengl opengl.gl
processing.shapes sequences threads ui ui.gadgets
ui.gadgets.borders ui.gadgets.buttons ui.gadgets.frames
ui.gadgets.grids ui.gadgets.labeled ui.gadgets.labels
ui.gadgets.packs ui.gadgets.sliders ui.render ui.tools.common ;
colors.constants kernel literals locals math math.functions
math.trig models namespaces opengl opengl.demo-support opengl.gl
sequences threads ui ui.commands ui.gadgets ui.gadgets.borders
ui.gadgets.buttons ui.gadgets.frames ui.gadgets.grids
ui.gadgets.labeled ui.gadgets.labels ui.gadgets.packs
ui.gadgets.sliders ui.gadgets.tracks ui.gadgets.worlds ui.render
ui.tools.common ;
QUALIFIED-WITH: models.range mr
IN: boids
@ -30,7 +31,7 @@ CONSTANT: initial-dt 5
initial-behaviours >>behaviours
initial-dt >>dt ;
M: boids-gadget ungraft*
M: boids-gadget ungraft*
t >>paused drop ;
: vec>deg ( vec -- deg )
@ -104,12 +105,19 @@ M: range-observer model-changed
[ neg random-boids append ] if
] change-boids drop ;
: pause-toggle ( boids-gadget -- )
<PRIVATE
: find-boids-gadget ( gadget -- boids-gadget )
dup boids-gadget? [ children>> [ boids-gadget? ] find nip ] unless ;
PRIVATE>
: com-pause ( boids-gadget -- )
find-boids-gadget
dup paused>> not [ >>paused ] keep
[ drop ] [ start-boids-thread ] if ;
: randomize-boids ( boids-gadget -- )
[ length random-boids ] change-boids drop ;
: com-randomize ( boids-gadget -- )
find-boids-gadget
[ length random-boids ] change-boids relayout-1 ;
:: simulation-panel ( boids-gadget -- gadget )
<pile> white-interior
@ -129,17 +137,19 @@ M: range-observer model-changed
{ 5 5 } <border> add-gadget
<shelf> { 2 2 } >>gap
"pause" [ drop boids-gadget pause-toggle ]
"pause" [ drop boids-gadget com-pause ]
<border-button> add-gadget
"randomize" [ drop boids-gadget randomize-boids ]
"randomize" [ drop boids-gadget com-randomize ]
<border-button> add-gadget
{ 5 5 } <border> add-gadget
"simulation" color: gray <framed-labeled-gadget> ;
:: create-gadgets ( -- gadgets )
<shelf>
TUPLE: boids-frame < pack ;
:: <boids-frame> ( -- boids-frame )
boids-frame new horizontal >>orientation
<boids-gadget> :> boids-gadget
boids-gadget [ start-boids-thread ] keep
add-gadget
@ -154,6 +164,10 @@ M: range-observer model-changed
{ 5 5 } <border> add-gadget ;
boids-frame "touchbar" f {
{ f com-pause }
{ f com-randomize }
} define-command-map
MAIN-WINDOW: boids { { title "Boids" } }
create-gadgets
>>gadgets ;
<boids-frame> >>gadgets ;

16
extra/boids/deploy.factor Normal file
View File

@ -0,0 +1,16 @@
USING: tools.deploy.config ;
H{
{ deploy-console? f }
{ deploy-io 3 }
{ deploy-reflection 2 }
{ deploy-ui? t }
{ deploy-word-defs? f }
{ deploy-threads? t }
{ "stop-after-last-window?" t }
{ deploy-math? t }
{ deploy-word-props? f }
{ deploy-c-types? f }
{ deploy-help? f }
{ deploy-name "Boids" }
{ deploy-unicode? f }
}

View File

@ -0,0 +1 @@
Slava Pestov

View File

@ -0,0 +1,128 @@
! Copyright (C) 2018 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: arrays help.markup help.syntax kernel quotations sequences ;
IN: boolean-expr
ABOUT: "boolean-expr"
ARTICLE: "boolean-expr" "Boolean expressions"
"The " { $vocab-link "boolean-expr" } " vocab demonstrates the use of Unicode symbols in source files and multi-method dispatch."
;
HELP: dnf
{ $values
{ "expr" □ }
{ "dnf" array }
}
{ $description "Convert the " { $snippet "expr" } " to Disjunctive Normal Form (DNF), i.e. an array of subexpressions, each not containing disjunctions. See " { $url "https://en.wikipedia.org/wiki/Disjunctive_normal_form" } "." }
{ $examples
{ $example "USING: boolean-expr prettyprint ;"
"X Y Z ⋀ ⋀ dnf ."
"{ { X Y Z } }"
}
{ $example "USING: boolean-expr prettyprint ;"
"X Y Z dnf ."
"{ { X } { Y } { Z } }"
}
} ;
HELP: expr.
{ $values
{ "expr" □ }
}
{ $description "Print the expression followed by newline." }
{ $examples
{ $example "USING: boolean-expr ;"
"X Y X ¬ Y ⋀ ⋀ op."
"((X ⋀ (¬X ⋀ Y)) (Y ⋀ (¬X ⋀ Y)))"
}
} ;
HELP: op.
{ $values
{ "expr" □ }
}
{ $description "Print the expression." }
{ $examples
{ $example "USING: boolean-expr ;"
"X Y X ¬ Y ⋀ ⋀ op."
"((X ⋀ (¬X ⋀ Y)) (Y ⋀ (¬X ⋀ Y)))"
}
} ;
{ expr. op. } related-words
HELP: satisfiable?
{ $values
{ "expr" □ }
{ "?" boolean }
}
{ $description "Return " { $link t } " if the " { $snippet "expr" } " can be true." }
{ $examples
{ $example "USING: boolean-expr prettyprint ;"
" satisfiable? ."
"t"
}
{ $example "USING: boolean-expr prettyprint ;"
"⊥ satisfiable? ."
"f"
}
{ $example "USING: boolean-expr prettyprint ;"
"X X ¬ ⋀ satisfiable? ."
"f"
}
{ $example "USING: boolean-expr prettyprint ;"
"X Y X ¬ Y ¬ ⋀ ⋀ satisfiable? ."
"f"
}
{ $example "USING: boolean-expr prettyprint ;"
"X Y X ¬ Y ⋀ ⋀ satisfiable? ."
"t"
}
} ;
HELP: ¬
{ $class-description "Logical negation (NOT)." $nl
{ $snippet "¬(¬A) " { $link ≣ } " A" } "."
} ;
HELP:
{ $values
{ "x" □ } { "y" □ }
{ "expr" □ }
}
{ $description "Material implication (if..then)." $nl
{ $snippet "x→y" } " " { $link ≣ } " " { $link ¬ } "x" { $link } "y"
} ;
HELP:
{ $values
{ "x" □ } { "y" □ }
{ "expr" □ }
}
{ $description "Material equivalence (if and only if)." $nl
{ $snippet "(x≣y) ≣ ((x" } { $link ⋀ } { $snippet "y) " }
{ $link } { $snippet " (" } { $link ¬ } { $snippet "x" } { $link ⋀ } { $link ¬ } { $snippet "y))" }
} ;
HELP:
{ $values
{ "x" □ } { "y" □ }
{ "expr" □ }
}
{ $description "Exclusive disjunction (XOR)." } ;
HELP:
{ $class-description "Logical tautology. This statement is unconditionally true." } ;
HELP:
{ $class-description "Logical contradiction. This statement is unconditionally false." } ;
HELP:
{ $class-description "Logical conjuction (AND)." } ;
HELP:
{ $class-description "Logical disjunction (OR)." } ;
HELP:
{ $class-description "A union class of all classes defined in this vocab. In methods signatures it stands for \"any variable or expression\"." } ;

View File

@ -0,0 +1,91 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays classes kernel sequences sets
io prettyprint ;
FROM: multi-methods => GENERIC: METHOD: ;
IN: boolean-expr
TUPLE: x y ;
TUPLE: x y ;
TUPLE: ¬ x ;
SINGLETONS: ;
SINGLETONS: P Q R S T U V W X Y Z ;
UNION: ¬ ⊥ P Q R S T U V W X Y Z ;
GENERIC: ( x y -- expr )
METHOD: ⋀ { □ } nip ;
METHOD: ⋀ { □ } drop ;
METHOD: ⋀ { ⊥ □ } drop ;
METHOD: ⋀ { □ ⊥ } nip ;
METHOD: ⋀ { □ } [ [ x>> ] dip ⋀ ] [ [ y>> ] dip ⋀ ] 2bi ;
METHOD: ⋀ { □ } [ x>> ⋀ ] [ y>> ⋀ ] 2bi ;
METHOD: ⋀ { □ □ } \ ⋀ boa ;
GENERIC: ( x y -- expr )
METHOD: { □ } drop ;
METHOD: { □ } nip ;
METHOD: { ⊥ □ } nip ;
METHOD: { □ ⊥ } drop ;
METHOD: { □ □ } \ boa ;
GENERIC: ¬ ( x -- expr )
METHOD: ¬ { } drop ⊥ ;
METHOD: ¬ { ⊥ } drop ;
METHOD: ¬ { ⋀ } [ x>> ¬ ] [ y>> ¬ ] bi ;
METHOD: ¬ { } [ x>> ¬ ] [ y>> ¬ ] bi ⋀ ;
METHOD: ¬ { □ } \ ¬ boa ;
: ( x y -- expr ) ¬ ⋀ ;
: ( x y -- expr ) [ ] [ ⋀ ¬ ] 2bi ⋀ ;
: ( x y -- expr ) [ ⋀ ] [ [ ¬ ] bi@ ⋀ ] 2bi ;
GENERIC: (dnf) ( expr -- dnf )
METHOD: (dnf) { ⋀ } [ x>> (dnf) ] [ y>> (dnf) ] bi append ;
METHOD: (dnf) { □ } 1array ;
GENERIC: dnf ( expr -- dnf )
METHOD: dnf { } [ x>> dnf ] [ y>> dnf ] bi append ;
METHOD: dnf { □ } (dnf) 1array ;
GENERIC: satisfiable? ( expr -- ? )
METHOD: satisfiable? { } drop t ;
METHOD: satisfiable? { ⊥ } drop f ;
! See if there is a term along with its negation in the conjunction seq.
: (satisfiable?) ( seq -- ? )
[ ¬? ] partition swap [ x>> ] map intersect empty? ;
METHOD: satisfiable? { □ }
dnf [ (satisfiable?) ] any? ;
GENERIC: (expr.) ( expr -- )
METHOD: (expr.) { □ } pprint ;
: op. ( expr -- )
"(" write
[ x>> (expr.) ]
[ bl class-of pprint bl ]
[ y>> (expr.) ]
tri
")" write ;
METHOD: (expr.) { ⋀ } op. ;
METHOD: (expr.) { } op. ;
METHOD: (expr.) { ¬ } [ class-of pprint ] [ x>> (expr.) ] bi ;
: expr. ( expr -- ) (expr.) nl ;

View File

@ -0,0 +1 @@
Simple boolean expression evaluator and simplifier

View File

@ -13,8 +13,6 @@ IN: bson.writer
CONSTANT: INT32-SIZE 4
CONSTANT: INT64-SIZE 8
PRIVATE>
TYPED: get-output ( -- stream: byte-vector )
output-stream get ; inline
@ -32,8 +30,6 @@ TYPED: with-length ( quot -- bytes-written: integer start-index: integer )
: with-length-prefix-excl ( quot: ( .. -- .. ) -- )
[ 4 - ] (with-length-prefix) ; inline
<PRIVATE
: write-le ( x n -- )
<iota> [ nth-byte write1 ] with each ; inline

View File

@ -0,0 +1,500 @@
USING: accessors arrays ascii calendar colors colors.gray
combinators.short-circuit fry kernel locals math math.constants
math.functions math.libm math.order math.points math.ranges
math.vectors namespaces opengl processing.shapes quotations
random sequences splitting threads timers ui ui.gadgets
ui.gadgets.borders ui.gadgets.buttons ui.gadgets.frame-buffer
ui.gadgets.packs ui.gestures ;
IN: bubble-chamber
! This is a Factor implementation of an art piece by Jared Tarbell:
!
! http://complexification.net/gallery/machines/bubblechamber/
!
! Jared's version is written in Processing (Java)
: 2random ( a b -- num ) 2dup swap - 100 / <range> random ;
: 1random ( b -- num ) 0 swap 2random ;
: at-fraction ( seq fraction -- val ) over length 1 - * >integer swap nth ;
: at-fraction-of ( fraction seq -- val ) swap at-fraction ;
: mouse ( -- point ) hand-loc get ;
: mouse-x ( -- x ) mouse first ;
: mouse-y ( -- y ) mouse second ;
: draw ( point -- )
gl-scale-factor get-global [
stroke-color get fill-color set
>integer draw-circle
] [
draw-point
] if* ;
GENERIC: collide ( particle -- )
GENERIC: move ( particle -- )
TUPLE: particle
bubble-chamber pos vel speed speed-d theta theta-d theta-dd myc mya ;
: initialize-particle ( particle -- particle )
{ 0 0 } >>pos
{ 0 0 } >>vel
0 >>speed
0 >>speed-d
0 >>theta
0 >>theta-d
0 >>theta-dd
0 0 0 1 rgba boa >>myc
0 0 0 1 rgba boa >>mya ;
: center ( particle -- point ) bubble-chamber>> size>> 2 v/n ;
DEFER: collision-theta
: move-by ( obj delta -- obj ) over pos>> v+ >>pos ;
: theta-dd-small? ( par limit -- par ? ) [ dup theta-dd>> abs ] dip < ;
: random-theta-dd ( par a b -- par ) 2random >>theta-dd ;
: turn ( particle -- particle )
dup
[ speed>> ] [ theta>> [ sin ] [ cos ] bi 2array ] bi n*v
>>vel ;
: step-theta ( p -- p ) [ ] [ theta>> ] [ theta-d>> ] tri + >>theta ;
: step-theta-d ( p -- p ) [ ] [ theta-d>> ] [ theta-dd>> ] tri + >>theta-d ;
: step-speed-sub ( p -- p ) [ ] [ speed>> ] [ speed-d>> ] tri - >>speed ;
: step-speed-mul ( p -- p ) [ ] [ speed>> ] [ speed-d>> ] tri * >>speed ;
:: out-of-bounds? ( PARTICLE -- ? )
PARTICLE pos>> first :> X
PARTICLE pos>> second :> Y
PARTICLE bubble-chamber>> size>> first :> WIDTH
PARTICLE bubble-chamber>> size>> second :> HEIGHT
WIDTH neg :> LEFT
WIDTH 2 * :> RIGHT
HEIGHT neg :> BOTTOM
HEIGHT 2 * :> TOP
{ [ X LEFT < ] [ X RIGHT > ] [ Y BOTTOM < ] [ Y TOP > ] } 0|| ;
TUPLE: axion < particle ;
: <axion> ( -- axion ) axion new initialize-particle ;
M: axion collide
dup center >>pos
2 pi * 1random >>theta
1.0 6.0 2random >>speed
0.998 1.000 2random >>speed-d
0 >>theta-d
0 >>theta-dd
[ 0.00001 theta-dd-small? ] [ -0.001 0.001 random-theta-dd ] while
drop ;
: dy>alpha ( dy -- alpha ) neg 6 * 30 + 255.0 / ;
! : axion-white ( dy -- dy ) dup 1 swap dy>alpha 2array stroke-color set ;
! : axion-black ( dy -- dy ) dup 0 swap dy>alpha 2array stroke-color set ;
: axion-white ( dy -- dy ) dup 1 swap dy>alpha gray boa stroke-color set ;
: axion-black ( dy -- dy ) dup 0 swap dy>alpha gray boa stroke-color set ;
: axion-point- ( particle dy -- particle ) [ dup pos>> ] dip v-y draw ;
: axion-point+ ( particle dy -- particle ) [ dup pos>> ] dip v+y draw ;
M: axion move
T{ gray f 0.06 0.59 } stroke-color set
dup pos>> draw
1 4 [a,b] [ axion-white axion-point- ] each
1 4 [a,b] [ axion-black axion-point+ ] each
dup vel>> move-by
turn
step-theta
step-theta-d
step-speed-mul
[ ] [ speed-d>> 0.9999 * ] bi >>speed-d
1000 random 996 >
[
dup speed>> neg >>speed
dup speed-d>> neg 2 + >>speed-d
100 random 30 > [ collide ] [ drop ] if
]
[ drop ]
if ;
TUPLE: hadron < particle ;
: <hadron> ( -- hadron ) hadron new initialize-particle ;
M: hadron collide
dup center >>pos
2 pi * 1random >>theta
0.5 3.5 2random >>speed
0.996 1.001 2random >>speed-d
0 >>theta-d
0 >>theta-dd
[ 0.00001 theta-dd-small? ] [ -0.001 0.001 random-theta-dd ] while
0 1 0 1 rgba boa >>myc
drop ;
M: hadron move
T{ gray f 1 0.11 } stroke-color set dup pos>> 1 v-y draw
T{ gray f 0 0.11 } stroke-color set dup pos>> 1 v+y draw
dup vel>> move-by
turn
step-theta
step-theta-d
step-speed-mul
1000 random 997 >
[
1.0 >>speed-d
0.00001 >>theta-dd
100 random 70 > [ dup collide ] when
]
when
dup out-of-bounds? [ collide ] [ drop ] if ;
CONSTANT: good-colors {
T{ rgba f 0.23 0.14 0.17 1 }
T{ rgba f 0.23 0.14 0.15 1 }
T{ rgba f 0.21 0.14 0.15 1 }
T{ rgba f 0.51 0.39 0.33 1 }
T{ rgba f 0.49 0.33 0.20 1 }
T{ rgba f 0.55 0.45 0.32 1 }
T{ rgba f 0.69 0.63 0.51 1 }
T{ rgba f 0.64 0.39 0.18 1 }
T{ rgba f 0.73 0.42 0.20 1 }
T{ rgba f 0.71 0.45 0.29 1 }
T{ rgba f 0.79 0.45 0.22 1 }
T{ rgba f 0.82 0.56 0.34 1 }
T{ rgba f 0.88 0.72 0.49 1 }
T{ rgba f 0.85 0.69 0.40 1 }
T{ rgba f 0.96 0.92 0.75 1 }
T{ rgba f 0.99 0.98 0.87 1 }
T{ rgba f 0.85 0.82 0.69 1 }
T{ rgba f 0.99 0.98 0.87 1 }
T{ rgba f 0.82 0.82 0.79 1 }
T{ rgba f 0.65 0.69 0.67 1 }
T{ rgba f 0.53 0.60 0.55 1 }
T{ rgba f 0.57 0.53 0.68 1 }
T{ rgba f 0.47 0.42 0.56 1 }
}
: anti-colors ( -- seq ) good-colors <reversed> ;
: color-fraction ( particle -- particle fraction ) dup theta>> pi + 2 pi * / ;
: set-good-color ( particle -- particle )
color-fraction dup 0 1 between?
[ good-colors at-fraction-of >>myc ] [ drop ] if ;
: set-anti-color ( particle -- particle )
color-fraction dup 0 1 between?
[ anti-colors at-fraction-of >>mya ] [ drop ] if ;
TUPLE: muon < particle ;
: <muon> ( -- muon ) muon new initialize-particle ;
M: muon collide
dup center >>pos
2 32 [a,b] random >>speed
0.0001 0.001 2random >>speed-d
dup collision-theta -0.1 0.1 2random + >>theta
0 >>theta-d
0 >>theta-dd
[ 0.001 theta-dd-small? ] [ -0.1 0.1 random-theta-dd ] while
set-good-color
set-anti-color
drop ;
M:: muon move ( MUON -- )
MUON bubble-chamber>> size>> first :> WIDTH
MUON
dup myc>> >rgba-components drop 0.16 <rgba> stroke-color set
dup pos>> draw
dup mya>> >rgba-components drop 0.16 <rgba> stroke-color set
dup pos>> first2 [ WIDTH swap - ] dip 2array draw
dup
[ speed>> ] [ theta>> [ sin ] [ cos ] bi 2array ] bi n*v
move-by
step-theta
step-theta-d
step-speed-sub
dup out-of-bounds? [ collide ] [ drop ] if ;
TUPLE: quark < particle ;
: <quark> ( -- quark ) quark new initialize-particle ;
M: quark collide
dup center >>pos
dup collision-theta -0.11 0.11 2random + >>theta
0.5 3.0 2random >>speed
0.996 1.001 2random >>speed-d
0 >>theta-d
0 >>theta-dd
[ 0.00001 theta-dd-small? ] [ -0.001 0.001 random-theta-dd ] while
drop ;
M:: quark move ( QUARK -- )
QUARK bubble-chamber>> size>> first :> WIDTH
QUARK
dup myc>> >rgba-components drop 0.13 <rgba> stroke-color set
dup pos>> draw
dup pos>> first2 [ WIDTH swap - ] dip 2array draw
[ ] [ vel>> ] bi move-by
turn
step-theta
step-theta-d
step-speed-mul
1000 random 997 > [
dup speed>> neg >>speed
2 over speed-d>> - >>speed-d
] when
dup out-of-bounds? [ collide ] [ drop ] if ;
TUPLE: bubble-chamber < frame-buffer
particles collision-theta size timer ;
M: bubble-chamber graft*
[ timer>> start-timer yield ] [ call-next-method ] bi ;
M: bubble-chamber ungraft*
[ timer>> stop-timer ] [ call-next-method ] bi ;
! : randomize-collision-theta ( bubble-chamber -- bubble-chamber )
! 0 2 pi * 0.001 <range> random >>collision-theta ;
: randomize-collision-theta ( bubble-chamber -- bubble-chamber )
pi neg pi 0.001 <range> random >>collision-theta ;
: collision-theta ( particle -- theta ) bubble-chamber>> collision-theta>> ;
M: bubble-chamber pref-dim* ( gadget -- dim ) size>> ;
: iterate-particle ( particle -- ) move ;
M:: bubble-chamber update-frame-buffer ( BUBBLE-CHAMBER -- )
BUBBLE-CHAMBER particles>> [ iterate-particle ] each ;
: iterate-system ( bubble-chamber -- ) drop ;
: <bubble-chamber> ( -- bubble-chamber )
bubble-chamber new
{ 1000 1000 } >>size
randomize-collision-theta
dup '[ _ dup iterate-system relayout-1 ]
f 10 milliseconds <timer> >>timer ;
: bubble-chamber-window ( -- bubble-chamber )
<bubble-chamber> dup "Bubble Chamber" open-window ;
:: add-particle ( BUBBLE-CHAMBER PARTICLE -- bubble-chamber )
PARTICLE BUBBLE-CHAMBER >>bubble-chamber drop
BUBBLE-CHAMBER [ PARTICLE suffix ] change-particles ;
:: mouse->collision-theta ( BUBBLE-CHAMBER -- BUBBLE-CHAMBER )
mouse
BUBBLE-CHAMBER size>> 2 v/n
v-
first2
fatan2
BUBBLE-CHAMBER collision-theta<<
BUBBLE-CHAMBER ;
:: mouse-pressed ( BUBBLE-CHAMBER -- )
BUBBLE-CHAMBER mouse->collision-theta drop
11 [
BUBBLE-CHAMBER particles>> [ hadron? ] filter random [ collide ] when*
BUBBLE-CHAMBER particles>> [ quark? ] filter random [ collide ] when*
BUBBLE-CHAMBER particles>> [ muon? ] filter random [ collide ] when*
] times ;
bubble-chamber H{
{ T{ button-down } [ mouse-pressed ] }
} set-gestures
: collide-random-particle ( bubble-chamber -- bubble-chamber )
dup particles>> random collide ;
: big-bang ( bubble-chamber -- bubble-chamber )
dup particles>> [ collide ] each ;
: collide-one-of-each ( bubble-chamber -- bubble-chamber )
dup
particles>>
[ [ muon? ] filter random collide ]
[ [ quark? ] filter random collide ]
[ [ hadron? ] filter random collide ]
tri ;
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
: ten-hadrons ( -- )
bubble-chamber-window
10 [ <hadron> add-particle ] times
drop ;
: original ( -- )
bubble-chamber-window
1789 [ <muon> add-particle ] times
1300 [ <quark> add-particle ] times
1000 [ <hadron> add-particle ] times
111 [ <axion> add-particle ] times
particles>>
[ [ muon? ] filter random collide ]
[ [ quark? ] filter random collide ]
[ [ hadron? ] filter random collide ]
tri ;
: hadron-chamber ( -- )
bubble-chamber-window
1000 [ <hadron> add-particle ] times
big-bang
drop ;
: quark-chamber ( -- )
bubble-chamber-window
100 [ <quark> add-particle ] times
big-bang
drop ;
: small ( -- )
<bubble-chamber>
{ 200 200 } >>size
dup "Bubble Chamber" open-window
42 [ <muon> add-particle ] times
30 [ <quark> add-particle ] times
21 [ <hadron> add-particle ] times
7 [ <axion> add-particle ] times
collide-one-of-each
drop ;
: medium ( -- )
<bubble-chamber>
{ 400 400 } >>size
dup "Bubble Chamber" open-window
100 [ <muon> add-particle ] times
81 [ <quark> add-particle ] times
60 [ <hadron> add-particle ] times
9 [ <axion> add-particle ] times
collide-one-of-each
drop ;
: large ( -- )
<bubble-chamber>
{ 600 600 } >>size
dup "Bubble Chamber" open-window
550 [ <muon> add-particle ] times
339 [ <quark> add-particle ] times
100 [ <hadron> add-particle ] times
11 [ <axion> add-particle ] times
collide-one-of-each
drop ;
: muon-chamber ( -- )
bubble-chamber-window
1000 [ <muon> add-particle ] times
dup particles>> [ collide randomize-collision-theta ] each
drop ;
: original-big-bang ( -- )
<bubble-chamber>
{ 1000 1000 } >>size
dup "Bubble Chamber" open-window
1789 [ <muon> add-particle ] times
1300 [ <quark> add-particle ] times
1000 [ <hadron> add-particle ] times
111 [ <axion> add-particle ] times
big-bang
drop ;
: original-big-bang-variant ( -- )
bubble-chamber-window
1789 [ <muon> add-particle ] times
1300 [ <quark> add-particle ] times
1000 [ <hadron> add-particle ] times
111 [ <axion> add-particle ] times
dup particles>> [ collide randomize-collision-theta ] each
drop ;
MAIN-WINDOW: run-bubble-chamber { { title "Bubble Chamber" } }
<filled-pile> { 2 2 } >>gap {
original small medium large hadron-chamber
quark-chamber muon-chamber ten-hadrons
original-big-bang original-big-bang-variant
} [
[ name>> "-" " " replace >title ]
[ 1quotation [ drop ] prepend ] bi
<border-button> add-gadget
] each { 2 2 } <border> >>gadgets ;

View File

@ -0,0 +1 @@
demos

View File

@ -3,7 +3,7 @@
USING: calendar calendar.elapsed kernel tools.test ;
IN: calendar.elapsed.test
IN: calendar.elapsed.tests
[ -1 elapsed-time ] [ "negative seconds" = ] must-fail-with

View File

@ -12,7 +12,7 @@ IN: cap
[ gl-scale ] bi@ * >fixnum <byte-array> ;
: gl-screenshot ( gadget -- byte-array )
[ find-world handle>> select-gl-context ]
[ find-gl-context ]
[
[
GL_BACK glReadBuffer

View File

@ -6,6 +6,6 @@ IN: changer
MACRO: inline-changer ( name -- quot' )
[ ">>" append ] [ ">>" prepend ] bi
[ "accessors" lookup-word 1quotation ] bi@
'[ over [ [ @ ] dip call ] dip swap @ ] ;
'[ over [ _ dip call ] dip swap @ ] ;
SYNTAX: \change: scan-token '[ _ inline-changer ] append! ;

View File

@ -0,0 +1 @@
Alexander Ilin

View File

@ -0,0 +1,21 @@
! Copyright (C) 2018 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: tools.test checksums checksums.sodium ;
IN: checksums.sodium.tests
CONSTANT: test-lines { "Hello," "world!" }
CONSTANT: key B{ 1 2 3 4 5 }
{ B{
139 36 186 84 68 114 23 158 49 88 99 135 7 27 173 126 1 166
211 245 212 87 23 116 86 191 32 15 106 139 134 168 184 156
246 65 84 90 77 78 127 26 18 229 103 211 131 111 224 131 48
77 157 208 10 231 152 223 132 200 228 141 25 64
} } [ test-lines 64 f <sodium-checksum> checksum-lines ] unit-test
{ B{
51 107 65 253 93 78 146 11 36 184 39 107 133 237 22 60 249
171 78 26 189 168 126 117 78 134 62 73 166 1 208 132 76 197
54 33 174 82 148 192 158 211 190 77 104 154 39 187 128 118
216 161 100 21 241 244 199 135 79 62 233 12 137 185
} } [ test-lines 64 key <sodium-checksum> checksum-lines ] unit-test

View File

@ -0,0 +1,45 @@
! Copyright (C) 2017 Alexander Ilin.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors alien byte-arrays checksums checksums.common
destructors kernel math sequences sodium sodium.ffi ;
IN: checksums.sodium
TUPLE: sodium-checksum
{ output-size fixnum }
{ key maybe{ byte-array } } ;
INSTANCE: sodium-checksum block-checksum
C: <sodium-checksum> sodium-checksum
<PRIVATE
TUPLE: sodium-state < disposable
{ state alien }
{ output-size fixnum }
{ output maybe{ byte-array } } ;
PRIVATE>
M: sodium-checksum initialize-checksum-state
[ key>> ] [ output-size>> ] bi
sodium-state new-disposable swap >>output-size
crypto_generichash_statebytes sodium_malloc >>state
[
[ state>> ] [ drop swap dup length ] [ output-size>> ] tri
crypto_generichash_init check0
] keep ;
M: sodium-state dispose*
state>> [ sodium_free ] when* ;
M: sodium-state add-checksum-bytes
[ dup state>> ] dip dup length crypto_generichash_update check0 ;
M: sodium-state get-checksum
dup output>> [
dup state>> [
over output-size>> [ <byte-array> ] keep
[ crypto_generichash_final check0 ] 2keep drop
] [ B{ } clone ] if*
[ >>output ] keep
] unless* nip ;

View File

@ -0,0 +1 @@
The default hash implementation provided by the Sodium crypto library

View File

@ -0,0 +1,2 @@
not loaded
not tested

View File

@ -9,7 +9,7 @@ IN: demos
dup '[ drop [ _ run ] \ run call-listener ] <border-button> ;
: <demo-runner> ( -- gadget )
<pile> 1 >>fill { 2 2 } >>gap demo-vocabs [ <run-vocab-button> add-gadget ] each ;
<filled-pile> { 2 2 } >>gap demo-vocabs [ <run-vocab-button> add-gadget ] each ;
MAIN-WINDOW: demos { { title "Demos" } }
<demo-runner> { 2 2 } <border> <scroller> >>gadgets ;

View File

@ -14,18 +14,18 @@ IN: fuel.tests
"Defer word in current vocabulary" f
fake-continuation <restart> ;
{ f } [ make-defer-restart is-use-restart ] unit-test
{ t } [ make-uses-restart is-use-restart ] unit-test
{ f } [ make-defer-restart is-use-restart? ] unit-test
{ t } [ make-uses-restart is-use-restart? ] unit-test
{ "words" } [ make-uses-restart get-restart-vocab ] unit-test
{ f } [ make-defer-restart is-suggested-restart ] unit-test
{ f } [ make-uses-restart is-suggested-restart ] unit-test
{ f } [ make-defer-restart is-suggested-restart? ] unit-test
{ f } [ make-uses-restart is-suggested-restart? ] unit-test
{ f } [ { "io" } :uses-suggestions
[ make-uses-restart is-suggested-restart ] with-variable
[ make-uses-restart is-suggested-restart? ] with-variable
] unit-test
{ t } [ { "words" } :uses-suggestions
[ make-uses-restart is-suggested-restart ] with-variable
[ make-uses-restart is-suggested-restart? ] with-variable
] unit-test
{ } [

Some files were not shown because too many files have changed in this diff Show More