]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' of git://factorcode.org/git/factor
authorJoe Groff <arcata@gmail.com>
Fri, 12 Dec 2008 01:16:12 +0000 (17:16 -0800)
committerJoe Groff <arcata@gmail.com>
Fri, 12 Dec 2008 01:16:12 +0000 (17:16 -0800)
38 files changed:
basis/alien/c-types/c-types-tests.factor
basis/alien/syntax/syntax-docs.factor
basis/alien/syntax/syntax.factor
basis/compiler/tests/alien.factor
basis/core-foundation/fsevents/fsevents.factor
basis/environment/unix/unix.factor
basis/http/client/client.factor
basis/io/launcher/launcher-docs.factor
basis/io/launcher/launcher.factor
basis/io/unix/backend/backend.factor
basis/io/unix/bsd/bsd.factor
basis/io/unix/epoll/epoll.factor
basis/io/unix/files/freebsd/freebsd.factor
basis/io/unix/files/linux/linux.factor
basis/io/unix/files/netbsd/netbsd.factor
basis/io/unix/files/openbsd/openbsd.factor
basis/io/unix/kqueue/kqueue.factor
basis/io/unix/launcher/launcher-tests.factor
basis/io/unix/launcher/launcher.factor
basis/io/unix/macosx/macosx.factor
basis/io/unix/select/select.factor
basis/tools/disassembler/disassembler-docs.factor
basis/tools/disassembler/disassembler.factor
basis/tools/disassembler/gdb/gdb.factor [new file with mode: 0644]
basis/tools/disassembler/gdb/tags.txt [new file with mode: 0644]
basis/tools/disassembler/udis/tags.txt [new file with mode: 0644]
basis/tools/disassembler/udis/udis.factor [new file with mode: 0644]
basis/ui/cocoa/views/views.factor
basis/ui/gadgets/worlds/worlds-docs.factor
basis/ui/gestures/gestures-docs.factor
basis/ui/gestures/gestures.factor
basis/ui/ui.factor
basis/ui/windows/windows.factor
basis/ui/x11/x11.factor
basis/unix/process/process.factor
core/sequences/sequences.factor
extra/flatland/flatland.factor
extra/pong/pong.factor

index f57d102452ca132031787331aef8201729158683..31542b2699eb94224500aa3c5fe181e47d4f9fa0 100644 (file)
@@ -8,7 +8,7 @@ sequences system libc alien.strings io.encodings.utf8 ;
 
 [ { "blah" 123 } ] [ { "blah" xyz } expand-constants ] unit-test
 
-: foo ( -- n ) "fdafd" f dlsym [ 123 ] unless* ;
+: foo ( -- n ) &: fdafd [ 123 ] unless* ;
 
 [ 123 ] [ foo ] unit-test
 
index 586bb974028978b2e78e663c9b6061f21d49d0bf..a3215cd8c6ae737c739fd18208565f819aab6e04 100644 (file)
@@ -77,6 +77,11 @@ HELP: C-ENUM:
     { $code "C-ENUM: red green blue ;" ": red 0 ;  : green 1 ;  : blue 2 ;" }
 } ;
 
+HELP: &:
+{ $syntax "&: symbol" }
+{ $values { "symbol" "A C library symbol name" } }
+{ $description "Pushes the address of a symbol named " { $snippet "symbol" } " from the current library, set with " { $link POSTPONE: LIBRARY: } "." } ;
+
 HELP: typedef
 { $values { "old" "a string" } { "new" "a string" } }
 { $description "Alises the C type " { $snippet "old" } " under the name " { $snippet "new" } "." }
index b0ba10a316176e501699e8487a993e168d50f482..15d82884f9c82e6fa18bd4e3511a94471efe1f35 100644 (file)
@@ -3,7 +3,8 @@
 USING: accessors arrays alien alien.c-types alien.structs
 alien.arrays alien.strings kernel math namespaces parser
 sequences words quotations math.parser splitting grouping
-effects assocs combinators lexer strings.parser alien.parser ;
+effects assocs combinators lexer strings.parser alien.parser 
+fry ;
 IN: alien.syntax
 
 : DLL" lexer get skip-blank parse-string dlopen parsed ; parsing
@@ -33,3 +34,7 @@ IN: alien.syntax
     dup length
     [ [ create-in ] dip 1quotation define ] 2each ;
     parsing
+
+: &:
+    scan "c-library" get
+    '[ _ _ load-library dlsym ] over push-all ; parsing
index 230a7bf54213379bd5fcc0ccd66c31c05c4ed049..1b21e40bace1c762d5dd211f8ccebc53a6719f3d 100644 (file)
@@ -83,14 +83,14 @@ FUNCTION: tiny ffi_test_17 int x ;
 
 { 1 1 } [ indirect-test-1 ] must-infer-as
 
-[ 3 ] [ "ffi_test_1" f dlsym indirect-test-1 ] unit-test
+[ 3 ] [ &: ffi_test_1 indirect-test-1 ] unit-test
 
 : indirect-test-1' ( ptr -- )
     "int" { } "cdecl" alien-indirect drop ;
 
 { 1 0 } [ indirect-test-1' ] must-infer-as
 
-[ ] [ "ffi_test_1" f dlsym indirect-test-1' ] unit-test
+[ ] [ &: ffi_test_1 indirect-test-1' ] unit-test
 
 [ -1 indirect-test-1 ] must-fail
 
@@ -100,7 +100,7 @@ FUNCTION: tiny ffi_test_17 int x ;
 { 3 1 } [ indirect-test-2 ] must-infer-as
 
 [ 5 ]
-[ 2 3 "ffi_test_2" f dlsym indirect-test-2 ]
+[ 2 3 &: ffi_test_2 indirect-test-2 ]
 unit-test
 
 : indirect-test-3 ( a b c d ptr -- result )
index d4d5e88512e25c72c0e2c4d464a80c2b342d358f..b3c1444043c9ea6be3e706ce938db61aeae83516 100644 (file)
@@ -118,7 +118,7 @@ FUNCTION: CFStringRef FSEventStreamCopyDescription ( FSEventStreamRef streamRef
     FSEventStreamCreate ;
 
 : kCFRunLoopCommonModes ( -- string )
-    "kCFRunLoopCommonModes" f dlsym *void* ;
+    &: kCFRunLoopCommonModes *void* ;
 
 : schedule-event-stream ( event-stream -- )
     CFRunLoopGetMain
index c2dddc25ab8cea4444c18293680c85bd964aa232..7da19ee47b5f4b954ca1097d48df41539c0b6aee 100644 (file)
@@ -2,12 +2,13 @@
 ! See http://factorcode.org/license.txt for BSD license.
 USING: alien alien.c-types alien.strings alien.syntax kernel
 layouts sequences system unix environment io.encodings.utf8
-unix.utilities vocabs.loader combinators alien.accessors ;
+unix.utilities vocabs.loader combinators alien.accessors
+alien.syntax ;
 IN: environment.unix
 
 HOOK: environ os ( -- void* )
 
-M: unix environ ( -- void* ) "environ" f dlsym ;
+M: unix environ ( -- void* ) &: environ ;
 
 M: unix os-env ( key -- value ) getenv ;
 
index 119fa23567ce0b1e590d6bb62819b953d6c54d51..108ae5ecc4c28bbbea3f2441288f8ff48fc09088 100644 (file)
@@ -7,6 +7,7 @@ math.order hashtables byte-arrays destructors
 io.encodings
 io.encodings.string
 io.encodings.ascii
+io.encodings.utf8
 io.encodings.8-bit
 io.encodings.binary
 io.streams.duplex
@@ -40,11 +41,11 @@ GENERIC: >post-data ( object -- post-data )
 
 M: post-data >post-data ;
 
-M: string >post-data "application/octet-stream" <post-data> ;
+M: string >post-data utf8 encode "application/octet-stream" <post-data> ;
 
 M: byte-array >post-data "application/octet-stream" <post-data> ;
 
-M: assoc >post-data assoc>query "application/x-www-form-urlencoded" <post-data> ;
+M: assoc >post-data assoc>query ascii encode "application/x-www-form-urlencoded" <post-data> ;
 
 M: f >post-data ;
 
@@ -52,12 +53,13 @@ M: f >post-data ;
     [ >post-data ] change-post-data ;
 
 : write-post-data ( request -- request )
-    dup method>> "POST" = [ dup post-data>> raw>> write ] when ; 
+    dup method>> [ "POST" = ] [ "PUT" = ] bi or [ dup post-data>> raw>> write ] when ; 
 
 : write-request ( request -- )
     unparse-post-data
     write-request-line
     write-request-header
+    binary encode-output
     write-post-data
     flush
     drop ;
@@ -153,7 +155,7 @@ SYMBOL: redirects
 
 PRIVATE>
 
-: success? ( code -- ? ) 200 = ;
+: success? ( code -- ? ) 200 299 between? ;
 
 ERROR: download-failed response ;
 
index 45bbec20e345cd0cd9d70a4da7c26edfd56e1752..358521473540ce253234015f96c15a63ed1f62a9 100644 (file)
@@ -143,8 +143,9 @@ HELP: <process-stream>
 { $description "Launches a process and redirects its input and output via a pair of pipes which may be read and written as a stream of the given encoding." } ;
 
 HELP: wait-for-process
-{ $values { "process" process } { "status" integer } }
-{ $description "If the process is still running, waits for it to exit, otherwise outputs the exit code immediately. Can be called multiple times on the same process." } ;
+{ $values { "process" process } { "status" object } }
+{ $description "If the process is still running, waits for it to exit, otherwise outputs the status code immediately. Can be called multiple times on the same process." }
+{ $notes "The status code is operating system specific; it may be an integer, or another object (the latter is the case on Unix if the process was killed by a signal). However, one cross-platform behavior code can rely on is that a status code of 0 indicates success." } ;
 
 ARTICLE: "io.launcher.descriptors" "Launch descriptors"
 "Words which launch processes can take either a command line string, a sequence of command line arguments, or a " { $link process } "."
index 0ed10e63c3418330775c111090bcddce7293c596..7bafb95376876e7ef6987b6ca7a4ce95af40e21b 100644 (file)
@@ -157,7 +157,7 @@ M: process-failed error.
     process>> . ;
 
 : wait-for-success ( process -- )
-    dup wait-for-process dup zero?
+    dup wait-for-process dup 0 =
     [ 2drop ] [ process-failed ] if ;
 
 : try-process ( desc -- )
index 1666d60c83fee70f2678fc02e37efe6f9b0d7e60..954a0a61de93e6c6752633b5b0b2c8f6506fa9ea 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: alien alien.c-types generic assocs kernel kernel.private
-math io.ports sequences strings sbufs threads unix
-vectors io.buffers io.backend io.encodings math.parser
+USING: alien alien.c-types alien.syntax generic assocs kernel
+kernel.private math io.ports sequences strings sbufs threads
+unix vectors io.buffers io.backend io.encodings math.parser
 continuations system libc qualified namespaces make io.timeouts
 io.encodings.utf8 destructors accessors summary combinators
 locals unix.time fry ;
@@ -184,11 +184,11 @@ M: stdin dispose*
 M: stdin refill
     [ buffer>> ] [ dup wait-for-stdin ] bi* refill-stdin f ;
 
-: control-write-fd ( -- fd ) "control_write" f dlsym *uint ;
+: control-write-fd ( -- fd ) &: control_write *uint ;
 
-: size-read-fd ( -- fd ) "size_read" f dlsym *uint ;
+: size-read-fd ( -- fd ) &: size_read *uint ;
 
-: data-read-fd ( -- fd ) "stdin_read" f dlsym *uint ;
+: data-read-fd ( -- fd ) &: stdin_read *uint ;
 
 : <stdin> ( -- stdin )
     stdin new
@@ -207,10 +207,10 @@ TUPLE: mx-port < port mx ;
 : <mx-port> ( mx -- port )
     dup fd>> mx-port <port> swap >>mx ;
 
-: multiplexer-error ( n -- )
-    0 < [
+: multiplexer-error ( n -- )
+    dup 0 < [
         err_no [ EAGAIN = ] [ EINTR = ] bi or
-        [ (io-error) ] unless
+        [ drop 0 ] [ (io-error) ] if
     ] when ;
 
 : ?flag ( n mask symbol -- n )
index 50b4b610da1fc0177edd5f1c0986693c9fe34306..e1583478db867ad8f4beff2e30e869e4e2928782 100644 (file)
@@ -1,16 +1,11 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-IN: io.unix.bsd
 USING: namespaces system kernel accessors assocs continuations
-unix io.backend io.unix.backend io.unix.select ;
+unix io.backend io.unix.backend io.unix.kqueue ;
+IN: io.unix.bsd
 
 M: bsd init-io ( -- )
-    <select-mx> mx set-global ;
-!     <kqueue-mx> kqueue-mx set-global
-!     kqueue-mx get-global <mx-port> <mx-task>
-!     dup io-task-fd
-!     [ mx get-global reads>> set-at ]
-!     [ mx get-global writes>> set-at ] 2bi ;
+    <kqueue-mx> mx set-global ;
 
 ! M: bsd (monitor) ( path recursive? mailbox -- )
 !     swap [ "Recursive kqueue monitors not supported" throw ] when
index e8d33787f38b295f27d5fe90f6ff5550c7ac89a8..93d0b4aa99235d4b3f219828f036c9b978b0152d 100644 (file)
@@ -49,7 +49,7 @@ M: epoll-mx remove-output-callbacks ( fd mx -- seq )
 
 : wait-event ( mx us -- n )
     [ [ fd>> ] [ events>> ] bi [ underlying>> ] [ length ] bi ] [ 1000 /i ] bi*
-    epoll_wait dup multiplexer-error ;
+    epoll_wait multiplexer-error ;
 
 : handle-event ( event mx -- )
     [ epoll-event-fd ] dip
index 3786a82b55a248d21f3a821da938e0df0f9261b5..eaf217af6263ee9d51de195938bd342e2f4598f0 100644 (file)
@@ -3,7 +3,8 @@
 USING: accessors alien.c-types alien.syntax combinators
 io.backend io.files io.unix.files kernel math system unix
 unix.statfs.freebsd unix.statvfs.freebsd unix.getfsstat.freebsd
-sequences grouping alien.strings io.encodings.utf8 ;
+sequences grouping alien.strings io.encodings.utf8
+specialized-arrays.direct.uint arrays ;
 IN: io.unix.files.freebsd
 
 TUPLE: freebsd-file-system-info < unix-file-system-info
@@ -32,7 +33,7 @@ M: freebsd statfs>file-system-info ( file-system-info statvfs -- file-system-inf
         [ statfs-f_asyncreads >>asyncreads ]
         [ statfs-f_namemax >>name-max ]
         [ statfs-f_owner >>owner ]
-        [ statfs-f_fsid >>id ]
+        [ statfs-f_fsid 2 <direct-uint-array> >array >>id ]
         [ statfs-f_fstypename utf8 alien>string >>type ]
         [ statfs-f_mntfromname utf8 alien>string >>device-name ]
         [ statfs-f_mntonname utf8 alien>string >>mount-point ]
index 3e4e1c043a0e1589ee786558c306895132c44ffd..c30855c3ee850c3a4315d6b67a27ebd05e320022 100644 (file)
@@ -3,7 +3,8 @@
 USING: accessors alien.c-types alien.syntax combinators csv
 io.backend io.encodings.utf8 io.files io.streams.string
 io.unix.files kernel math.order namespaces sequences sorting
-system unix unix.statfs.linux unix.statvfs.linux ;
+system unix unix.statfs.linux unix.statvfs.linux
+specialized-arrays.direct.uint arrays ;
 IN: io.unix.files.linux
 
 TUPLE: linux-file-system-info < unix-file-system-info
@@ -23,7 +24,7 @@ M: linux statfs>file-system-info ( struct -- statfs )
         [ statfs64-f_bavail >>blocks-available ]
         [ statfs64-f_files >>files ]
         [ statfs64-f_ffree >>files-free ]
-        [ statfs64-f_fsid >>id ]
+        [ statfs64-f_fsid 2 <direct-uint-array> >array >>id ]
         [ statfs64-f_namelen >>namelen ]
         [ statfs64-f_frsize >>preferred-block-size ]
         ! [ statfs64-f_spare >>spare ]
index 23717b41a467a819ada468fccfc389774ec9da50..82ac3dc70d385e2acfefa6fe3c8812e979fe8392 100644 (file)
@@ -3,8 +3,8 @@
 USING: alien.syntax kernel unix.stat math unix
 combinators system io.backend accessors alien.c-types
 io.encodings.utf8 alien.strings unix.types io.unix.files
-io.files unix.statvfs.netbsd unix.getfsstat.netbsd
-grouping sequences io.encodings.utf8 ;
+io.files unix.statvfs.netbsd unix.getfsstat.netbsd arrays
+grouping sequences io.encodings.utf8 specialized-arrays.direct.uint ;
 IN: io.unix.files.netbsd
 
 TUPLE: netbsd-file-system-info < unix-file-system-info
@@ -35,7 +35,7 @@ M: netbsd statvfs>file-system-info ( file-system-info statvfs -- file-system-inf
         [ statvfs-f_syncwrites >>sync-writes ]
         [ statvfs-f_asyncreads >>async-reads ]
         [ statvfs-f_asyncwrites >>async-writes ]
-        [ statvfs-f_fsidx >>idx ]
+        [ statvfs-f_fsidx 2 <direct-uint-array> >array >>idx ]
         [ statvfs-f_fsid >>id ]
         [ statvfs-f_namemax >>name-max ]
         [ statvfs-f_owner >>owner ]
index 8c8f7c154b2bf79d7a286a7bbf156cd1805b29dc..e5e18b29ea93a470754e288fa0604bddd58dfff0 100644 (file)
@@ -3,7 +3,8 @@
 USING: accessors alien.c-types alien.strings alien.syntax
 combinators io.backend io.files io.unix.files kernel math
 sequences system unix unix.getfsstat.openbsd grouping
-unix.statfs.openbsd unix.statvfs.openbsd unix.types ;
+unix.statfs.openbsd unix.statvfs.openbsd unix.types
+specialized-arrays.direct.uint arrays ;
 IN: io.unix.files.openbsd
 
 TUPLE: freebsd-file-system-info < unix-file-system-info
@@ -30,7 +31,7 @@ M: openbsd statfs>file-system-info ( file-system-info statfs -- file-system-info
         [ statfs-f_syncreads >>sync-reads ]
         [ statfs-f_asyncwrites >>async-writes ]
         [ statfs-f_asyncreads >>async-reads ]
-        [ statfs-f_fsid >>id ]
+        [ statfs-f_fsid 2 <direct-uint-array> >array >>id ]
         [ statfs-f_namemax >>name-max ]
         [ statfs-f_owner >>owner ]
         ! [ statfs-f_spare >>spare ]
index b4e2b7af6fb017be664c9285806415d5561cfd4a..be99d1757264d4d881fb9f9d797a3d12cd0e0b20 100644 (file)
@@ -58,8 +58,7 @@ M: kqueue-mx remove-output-callbacks ( fd mx -- seq )
     [
         [ fd>> f 0 ]
         [ events>> [ underlying>> ] [ length ] bi ] bi
-    ] dip kevent
-    dup multiplexer-error ;
+    ] dip kevent multiplexer-error ;
 
 : handle-kevent ( mx kevent -- )
     [ kevent-ident swap ] [ kevent-filter ] bi {
index 33988c273bc871d124de968898b92b5f515b9821..68ca821ed43a43d20902e68bd2f29fac142e93d5 100644 (file)
@@ -2,7 +2,8 @@ IN: io.unix.launcher.tests
 USING: io.files tools.test io.launcher arrays io namespaces
 continuations math io.encodings.binary io.encodings.ascii
 accessors kernel sequences io.encodings.utf8 destructors
-io.streams.duplex ;
+io.streams.duplex locals concurrency.promises threads
+unix.process ;
 
 [ ] [
     [ "launcher-test-1" temp-file delete-file ] ignore-errors
@@ -121,3 +122,17 @@ io.streams.duplex ;
         input-stream get contents
     ] with-stream
 ] unit-test
+
+! Killed processes were exiting with code 0 on FreeBSD
+[ f ] [
+    [let | p [ <promise> ]
+           s [ <promise> ] |
+       [
+           "sleep 1000" run-detached
+           [ p fulfill ] [ wait-for-process s fulfill ] bi
+       ] in-thread
+
+       p ?promise handle>> 9 kill drop
+       s ?promise 0 =
+    ]
+] unit-test
index e80a372aefc475475cbbb7efed349be164437b4a..729c1545d83a1270b6c7b4bfe4cf82248ab49e4f 100644 (file)
@@ -92,14 +92,16 @@ M: unix kill-process* ( pid -- )
     processes get swap [ nip swap handle>> = ] curry
     assoc-find 2drop ;
 
+TUPLE: signal n ;
+
+: code>status ( code -- obj )
+    dup WIFEXITED [ WEXITSTATUS ] [ WTERMSIG signal boa ] if ;
+
 M: unix wait-for-processes ( -- ? )
     -1 0 <int> tuck WNOHANG waitpid
     dup 0 <= [
         2drop t
     ] [
-        find-process dup [
-            swap *int WEXITSTATUS notify-exit f
-        ] [
-            2drop f
-        ] if
+        find-process dup
+        [ swap *int code>status notify-exit f ] [ 2drop f ] if
     ] if ;
index ef52b676fb60d53070c9c0a80e034f53dc59cc83..388d266b48ac97d7ce732e4894378bdb66fd8da7 100644 (file)
@@ -1,10 +1,7 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 IN: io.unix.macosx
-USING: io.unix.backend io.unix.bsd io.unix.kqueue io.backend
+USING: io.unix.backend io.unix.bsd io.backend
 namespaces system ;
 
-M: macosx init-io ( -- )
-    <kqueue-mx> mx set-global ;
-
 macosx set-io-backend
index 27231aee5a8adc56e303ae7ac4cba27d38c4e20f..a6b61001a63c059403dbb1f6f9b9b11c4c4d57c2 100644 (file)
@@ -50,7 +50,7 @@ TUPLE: select-mx < mx read-fdset write-fdset ;
 
 M:: select-mx wait-for-events ( us mx -- )
     mx
-    [ init-fdsets us dup [ make-timeval ] when select multiplexer-error ]
+    [ init-fdsets us dup [ make-timeval ] when select multiplexer-error drop ]
     [ [ read-fdset/tasks ] keep [ input-available ] check-fdset ]
     [ [ write-fdset/tasks ] keep [ output-available ] check-fdset ]
     tri ;
index f03861a8ed76828d1bcc35c3cbe7b5f2ba253fec..7d193d0aac29ed03f9a65d3cfd10a214eb367c8b 100644 (file)
@@ -3,11 +3,11 @@ USING: help.markup help.syntax sequences.private ;
 \r
 HELP: disassemble\r
 { $values { "obj" "a word or a pair of addresses" } }\r
-{ $description "Disassembles either a compiled word definition or an arbitrary memory range (in the case " { $snippet "obj" } " is a pair of integers) by attaching " { $snippet "gdb" } " to the Factor VM and capturing the output." }\r
-{ $notes "In some cases the Factor compiler emits data inline with code, which can confuse " { $snippet "gdb" } ". This occurs in words which call " { $link dispatch } ", where the jump table addresses are compiled inline. Also on the ARM architecture, various pointers are often compiled inline, and the preceeding instruction jumps over the inline pinter." } ;\r
+{ $description "Disassembles either a compiled word definition or an arbitrary memory range (in the case " { $snippet "obj" } " is a pair of integers)." }\r
+{ $notes "In some cases the Factor compiler emits data inline with code, which can confuse the disassembler. This occurs in words which call " { $link dispatch } ", where the jump table addresses are compiled inline." } ;\r
 \r
 ARTICLE: "tools.disassembler" "Disassembling words"\r
-"The " { $vocab-link "tools.disassembler" } " vocabulary integrates Factor with the GNU debugger (" { $snippet "gdb" } ") for viewing the assembly code generated by the compiler. It can be used on both Unix and Windows as long as a working copy of " { $snippet "gdb" } " is installed and available in the " { $snippet "PATH" } "."\r
+"The " { $vocab-link "tools.disassembler" } " vocabulary provides support for disassembling compiled word definitions. It uses the " { $snippet "libudis86" } " library on x86-32 and x86-64, and " { $snippet "gdb" } " on PowerPC."\r
 { $subsection disassemble } ;\r
 \r
 ABOUT: "tools.disassembler"\r
index 76e1f0f1b86132ec2910258b3d7f577ae39d99ac..fac340845b8f1ade79f36c947dbbc309407f835c 100644 (file)
@@ -1,43 +1,25 @@
-! Copyright (C) 2008 Slava Pestov, Jorge Acereda Macia.
+! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: io.files io words alien kernel math.parser alien.syntax
-io.launcher system assocs arrays sequences namespaces make
-qualified system math compiler.codegen.fixup
-io.encodings.ascii accessors generic tr ;
+USING: tr arrays sequences io words generic system combinators
+vocabs.loader ;
 IN: tools.disassembler
 
-: in-file ( -- path ) "gdb-in.txt" temp-file ;
+GENERIC: disassemble ( obj -- )
 
-: out-file ( -- path ) "gdb-out.txt" temp-file ;
+SYMBOL: disassembler-backend
 
-GENERIC: make-disassemble-cmd ( obj -- )
+HOOK: disassemble* disassembler-backend ( from to -- lines )
 
-M: word make-disassemble-cmd
-    word-xt code-format - 2array make-disassemble-cmd ;
-
-M: pair make-disassemble-cmd
-    in-file ascii [
-        "attach " write
-        current-process-handle number>string print
-        "disassemble " write
-        [ number>string write bl ] each
-    ] with-file-writer ;
-
-M: method-spec make-disassemble-cmd
-    first2 method make-disassemble-cmd ;
+TR: tabs>spaces "\t" "\s" ;
 
-: gdb-binary ( -- string ) "gdb" ;
+M: pair disassemble first2 disassemble* [ tabs>spaces print ] each ;
 
-: run-gdb ( -- lines )
-    <process>
-        +closed+ >>stdin
-        out-file >>stdout
-        [ gdb-binary , "-x" , in-file , "-batch" , ] { } make >>command
-    try-process
-    out-file ascii file-lines ;
+M: word disassemble word-xt 2array disassemble ;
 
-TR: tabs>spaces "\t" "\s" ;
+M: method-spec disassemble first2 method disassemble ;
 
-: disassemble ( obj -- )
-    make-disassemble-cmd run-gdb
-    [ tabs>spaces ] map [ print ] each ;
+cpu {
+    { x86.32 [ "tools.disassembler.udis" ] }
+    { x86.64 [ "tools.disassembler.udis" ] }
+    { ppc [ "tools.disassembler.gdb" ] }
+} case require
diff --git a/basis/tools/disassembler/gdb/gdb.factor b/basis/tools/disassembler/gdb/gdb.factor
new file mode 100644 (file)
index 0000000..65d0e2f
--- /dev/null
@@ -0,0 +1,36 @@
+! Copyright (C) 2008 Slava Pestov, Jorge Acereda Macia.
+! See http://factorcode.org/license.txt for BSD license.
+USING: io.files io words alien kernel math.parser alien.syntax
+io.launcher system assocs arrays sequences namespaces make
+qualified system math io.encodings.ascii accessors
+tools.disassembler ;
+IN: tools.disassembler.gdb
+
+SINGLETON: gdb-disassembler
+
+: in-file ( -- path ) "gdb-in.txt" temp-file ;
+
+: out-file ( -- path ) "gdb-out.txt" temp-file ;
+
+: make-disassemble-cmd ( from to -- )
+    in-file ascii [
+        "attach " write
+        current-process-handle number>string print
+        "disassemble " write
+        [ number>string write bl ] bi@
+    ] with-file-writer ;
+
+: gdb-binary ( -- string ) "gdb" ;
+
+: run-gdb ( -- lines )
+    <process>
+        +closed+ >>stdin
+        out-file >>stdout
+        [ gdb-binary , "-x" , in-file , "-batch" , ] { } make >>command
+    try-process
+    out-file ascii file-lines ;
+
+M: gdb-disassembler disassemble*
+    make-disassemble-cmd run-gdb ;
+
+gdb-disassembler disassembler-backend set-global
diff --git a/basis/tools/disassembler/gdb/tags.txt b/basis/tools/disassembler/gdb/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/tools/disassembler/udis/tags.txt b/basis/tools/disassembler/udis/tags.txt
new file mode 100644 (file)
index 0000000..6bf6830
--- /dev/null
@@ -0,0 +1 @@
+unportable
diff --git a/basis/tools/disassembler/udis/udis.factor b/basis/tools/disassembler/udis/udis.factor
new file mode 100644 (file)
index 0000000..c5b5c80
--- /dev/null
@@ -0,0 +1,89 @@
+! Copyright (C) 2008 Slava Pestov, Jorge Acereda Macia.
+! See http://factorcode.org/license.txt for BSD license.
+USING: tools.disassembler namespaces combinators
+alien alien.syntax alien.c-types lexer parser kernel
+sequences layouts math math.parser system make fry arrays ;
+IN: tools.disassembler.udis
+
+<<
+"libudis86" {
+    { [ os macosx? ] [ "libudis86.0.dylib" ] }
+    { [ os unix? ] [ "libudis86.so.0" ] }
+    { [ os winnt? ] [ "libudis86.dll" ] }
+} cond "cdecl" add-library
+>>
+
+LIBRARY: libudis86
+
+TYPEDEF: char[592] ud
+
+FUNCTION: void ud_translate_intel ( ud* u ) ;
+FUNCTION: void ud_translate_att ( ud* u ) ;
+
+: UD_SYN_INTEL    &: ud_translate_intel ; inline
+: UD_SYN_ATT      &: ud_translate_att ; inline
+: UD_EOI          -1 ; inline
+: UD_INP_CACHE_SZ 32 ; inline
+: UD_VENDOR_AMD   0 ; inline
+: UD_VENDOR_INTEL 1 ; inline
+
+FUNCTION: void ud_init ( ud* u ) ;
+FUNCTION: void ud_set_mode ( ud* u, uint8_t mode ) ;
+FUNCTION: void ud_set_pc ( ud* u, ulonglong pc ) ;
+FUNCTION: void ud_set_input_buffer ( ud* u, uint8_t* offset, size_t size ) ;
+FUNCTION: void ud_set_vendor ( ud* u, uint vendor ) ;
+FUNCTION: void ud_set_syntax ( ud* u, void* syntax ) ;
+FUNCTION: void ud_input_skip ( ud* u, size_t size ) ;
+FUNCTION: int ud_input_end ( ud* u ) ;
+FUNCTION: uint ud_decode ( ud* u ) ;
+FUNCTION: uint ud_disassemble ( ud* u ) ;
+FUNCTION: char* ud_insn_asm ( ud* u ) ;
+FUNCTION: void* ud_insn_ptr ( ud* u ) ;
+FUNCTION: ulonglong ud_insn_off ( ud* u ) ;
+FUNCTION: char* ud_insn_hex ( ud* u ) ;
+FUNCTION: uint ud_insn_len ( ud* u ) ;
+FUNCTION: char* ud_lookup_mnemonic ( int c ) ;
+
+: <ud> ( -- ud )
+    "ud" <c-object>
+    dup ud_init
+    dup cell-bits ud_set_mode
+    dup UD_SYN_INTEL ud_set_syntax ;
+
+SINGLETON: udis-disassembler
+
+: buf/len ( from to -- buf len ) [ drop <alien> ] [ swap - ] 2bi ;
+
+: format-disassembly ( lines -- lines' )
+    dup [ second length ] map supremum
+    '[
+        [
+            [ first >hex cell 2 * CHAR: 0 pad-left % ": " % ]
+            [ second _ CHAR: \s pad-right % "  " % ]
+            [ third % ]
+            tri
+        ] "" make
+    ] map ;
+
+: (disassemble) ( ud -- lines )
+    [
+        dup '[
+            _ ud_disassemble 0 =
+            [ f ] [
+                _
+                [ ud_insn_off ]
+                [ ud_insn_hex ]
+                [ ud_insn_asm ]
+                tri 3array , t
+            ] if
+        ] loop
+    ] { } make ;
+
+M: udis-disassembler disassemble* ( from to -- buffer )
+    [ <ud> ] 2dip {
+        [ drop ud_set_pc ]
+        [ buf/len ud_set_input_buffer ]
+        [ 2drop (disassemble) format-disassembly ]
+    } 3cleave ;
+
+udis-disassembler disassembler-backend set-global
index 128fdceeb4f02065020c39f4f88741effc056470..7bb9679132e50b015b11db1b1bb3f1c366091393 100644 (file)
@@ -60,7 +60,7 @@ IN: ui.cocoa.views
     dup event-modifiers swap key-code ;
 
 : send-key-event ( view gesture -- )
-    swap window-focus propagate-gesture ;
+    swap window propagate-key-gesture ;
 
 : interpret-key-event ( view event -- )
     NSArray swap -> arrayWithObject: -> interpretKeyEvents: ;
@@ -266,30 +266,23 @@ CLASS: {
 { "writeSelectionToPasteboard:types:" "char" { "id" "SEL" "id" "id" }
     [
         CF>string-array NSStringPboardType swap member? [
-            >r drop window-focus gadget-selection dup [
-                r> set-pasteboard-string 1
-            ] [
-                r> 2drop 0
-            ] if
-        ] [
-            3drop 0
-        ] if
+            [ drop window-focus gadget-selection ] dip over
+            [ set-pasteboard-string 1 ] [ 2drop 0 ] if
+        ] [ 3drop 0 ] if
     ]
 }
 
 { "readSelectionFromPasteboard:" "char" { "id" "SEL" "id" }
     [
         pasteboard-string dup [
-            [ drop window-focus ] dip swap user-input 1
-        ] [
-            3drop 0
-        ] if
+            [ drop window ] dip swap user-input 1
+        ] [ 3drop 0 ] if
     ]
 }
 
 ! Text input
 { "insertText:" "void" { "id" "SEL" "id" }
-    [ nip CF>string swap window-focus user-input ]
+    [ nip CF>string swap window user-input ]
 }
 
 { "hasMarkedText" "char" { "id" "SEL" }
index 35781fa5685606d99137c1cf8acc2aa19f7d38da..60e4e58ed5d7e9539e24019d887927ffb0f505b5 100644 (file)
@@ -2,6 +2,10 @@ USING: ui.gadgets ui.render ui.gestures ui.backend help.markup
 help.syntax models opengl strings ;
 IN: ui.gadgets.worlds
 
+HELP: user-input
+{ $values { "string" string } { "world" world } }
+{ $description "Calls " { $link user-input* } " on every parent of the world's currently-focused child." } ;
+
 HELP: origin
 { $var-description "Within the dynamic extent of " { $link draw-world } ", holds the co-ordinate system origin for the gadget currently being drawn." } ;
 
index 602d3fd4255a25d7c032f24e3384b221d8106e07..f6495a14c3297f4dcc8c6ec5187dac8d7c084599 100644 (file)
@@ -1,5 +1,5 @@
-USING: ui.gadgets help.markup help.syntax hashtables
-strings kernel system ;
+USING: ui.gadgets ui.gadgets.worlds help.markup help.syntax
+hashtables strings kernel system ;
 IN: ui.gestures
 
 HELP: set-gestures
@@ -21,10 +21,6 @@ HELP: propagate-gesture
 { $values { "gesture" "a gesture" } { "gadget" gadget } }
 { $description "Calls " { $link handle-gesture } " on every parent of " { $snippet "gadget" } "." } ;
 
-HELP: user-input
-{ $values { "string" string } { "gadget" gadget } }
-{ $description "Calls " { $link user-input* } " on every parent of the gadget." } ;
-
 HELP: motion
 { $class-description "Mouse motion gesture." }
 { $examples { $code "T{ motion }" } } ;
index 5faaa93292ed4a4a5b5e294fa23b4610509e0ee6..123a7620d1f4b500b75d8217e8ed8209ca2922f7 100644 (file)
@@ -41,13 +41,25 @@ M: propagate-gesture send-queued-gesture
 : propagate-gesture ( gesture gadget -- )
     \ propagate-gesture queue-gesture ;
 
-TUPLE: user-input string gadget ;
+TUPLE: propagate-key-gesture gesture world ;
+
+: world-focus ( world -- gadget )
+    dup focus>> [ world-focus ] [ ] ?if ;
+
+M: propagate-key-gesture send-queued-gesture
+    [ gesture>> ] [ world>> world-focus ] bi
+    [ handle-gesture ] with each-parent drop ;
+
+: propagate-key-gesture ( gesture world -- )
+    \ propagate-key-gesture queue-gesture ;
+
+TUPLE: user-input string world ;
 
 M: user-input send-queued-gesture
-    [ string>> ] [ gadget>> ] bi
+    [ string>> ] [ world>> world-focus ] bi
     [ user-input* ] with each-parent drop ;
 
-: user-input ( string gadget -- )
+: user-input ( string world -- )
     '[ _ \ user-input queue-gesture ] unless-empty ;
 
 ! Gesture objects
@@ -261,9 +273,6 @@ SYMBOL: drag-timer
     scroll-direction set-global
     T{ mouse-scroll } hand-gadget get-global propagate-gesture ;
 
-: world-focus ( world -- gadget )
-    dup focus>> [ world-focus ] [ ] ?if ;
-
 : send-action ( world gesture -- )
     swap world-focus propagate-gesture ;
 
index e3401cdb332bf340fd1284532030fb22bfb6d3cc..1ee860c9748d0ea6316fd7e92f44331ff9748add 100644 (file)
@@ -143,7 +143,7 @@ SYMBOL: ui-hook
     graft-queue [ notify ] slurp-deque ;
 
 : send-queued-gestures ( -- )
-    gesture-queue [ send-queued-gesture ] slurp-deque ;
+    gesture-queue [ send-queued-gesture notify-queued ] slurp-deque ;
 
 : update-ui ( -- )
     [
index 8e60ad1bc583f9aed52a78c7a4660816d12d96cc..35ee9f9a600ca2ef67021c3887404487c112af05 100755 (executable)
@@ -183,7 +183,7 @@ SYMBOLS: msg-obj class-name-ptr mouse-captured ;
 
 : send-key-gesture ( sym action? quot hWnd -- )
     [ [ key-modifiers ] 3dip call ] dip
-    window-focus propagate-gesture ; inline
+    window propagate-key-gesture ; inline
 
 : send-key-down ( sym action? hWnd -- )
     [ [ <key-down> ] ] dip send-key-gesture ;
@@ -215,7 +215,7 @@ SYMBOLS: msg-obj class-name-ptr mouse-captured ;
         ctrl? alt? xor [
             wParam 1string
             [ f hWnd send-key-down ]
-            [ hWnd window-focus user-input ] bi
+            [ hWnd window user-input ] bi
         ] unless
     ] unless ;
 
index b65185967a17878d583797c0579b15968bd02202..817e356712505d2100b7b021f40ee1cfcd6290b0 100755 (executable)
@@ -86,8 +86,7 @@ M: world configure-event
 
 M: world key-down-event
     [ key-down-event>gesture ] keep
-    world-focus
-    [ propagate-gesture drop ]
+    [ propagate-key-gesture drop ]
     [ 2over valid-input? [ nip user-input ] [ 3drop ] if ]
     3bi ;
 
@@ -95,7 +94,7 @@ M: world key-down-event
     dup event-modifiers swap 0 XLookupKeysym key-code <key-up> ;
 
 M: world key-up-event
-    [ key-up-event>gesture ] dip world-focus propagate-gesture ;
+    [ key-up-event>gesture ] dip propagate-key-gesture ;
 
 : mouse-event>gesture ( event -- modifiers button loc )
     [ event-modifiers ]
@@ -141,7 +140,7 @@ M: world focus-out-event
 
 M: world selection-notify-event
     [ handle>> window>> selection-from-event ] keep
-    world-focus user-input ;
+    user-input ;
 
 : supported-type? ( atom -- ? )
     { "UTF8_STRING" "STRING" "TEXT" }
index 175425f948f7298c34eec524a4ad7fa603300bd4..7d5f9eb330468ee079f6f8bd2da03921297643b6 100644 (file)
@@ -74,7 +74,7 @@ FUNCTION: int setpriority ( int which, int who, int prio ) ;
     HEX: 7f bitand ; inline
 
 : WIFEXITED ( status -- ? )
-    WTERMSIG zero? ; inline
+    WTERMSIG 0 = ; inline
 
 : WEXITSTATUS ( status -- value )
     HEX: ff00 bitand -8 shift ; inline
@@ -86,7 +86,7 @@ FUNCTION: int setpriority ( int which, int who, int prio ) ;
     HEX: 80 ; inline
 
 : WCOREDUMP ( status -- ? )
-    WCOREFLAG bitand zero? not ; inline
+    WCOREFLAG bitand 0 = not ; inline
 
 : WIFSTOPPED ( status -- ? )
     HEX: ff bitand HEX: 7f = ; inline
index e36435992870da3b5c44eb742a76ca70ac619a5a..7bb509cb67072e8aabcdef8ea02cbe5537c0eac9 100644 (file)
@@ -343,7 +343,7 @@ PRIVATE>
     [ (each) ] dip collect ; inline
 
 : 2nth-unsafe ( n seq1 seq2 -- elt1 elt2 )
-    [ over ] dip nth-unsafe [ nth-unsafe ] dip ; inline
+    [ over ] dip [ nth-unsafe ] 2bi@ ; inline
 
 : (2each) ( seq1 seq2 quot -- n quot' )
     [ [ min-length ] 2keep ] dip
@@ -538,12 +538,12 @@ M: sequence <=>
 
 : sequence-hashcode-step ( oldhash newpart -- newhash )
     >fixnum swap [
-        dup -2 fixnum-shift-fast swap 5 fixnum-shift-fast
+        [ -2 fixnum-shift-fast ] [ 5 fixnum-shift-fast ] bi
         fixnum+fast fixnum+fast
     ] keep fixnum-bitxor ; inline
 
 : sequence-hashcode ( n seq -- x )
-    0 -rot [ hashcode* sequence-hashcode-step ] with each ; inline
+    [ 0 ] 2dip [ hashcode* sequence-hashcode-step ] with each ; inline
 
 M: reversed equal? over reversed? [ sequence= ] [ 2drop f ] if ;
 
index c98c5a6c574f22ebd1a628b7a035af1c2ce71e3e..72d9e50a9d8d6bbb816fbc5613b67823e60dbc9f 100644 (file)
@@ -2,6 +2,7 @@
 USING: accessors arrays fry kernel math math.vectors sequences
        math.intervals
        multi-methods
+       combinators.short-circuit
        combinators.cleave.enhanced
        multi-method-syntax ;
 
@@ -218,3 +219,16 @@ USING: locals combinators ;
   cond
 
   2array ;
+
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+GENERIC: within? ( a b -- ? )
+
+METHOD: within? ( <pos> <rectangle> -- ? )
+  {
+    [ left   to-the-right-of? ]
+    [ right  to-the-left-of?  ]
+    [ bottom above?           ]
+    [ top    below?           ]
+  }
+  2&& ;
index befb64a7a795ca4dfd3257026a09d15208305e9e..3f7626074a4cd87c935d1a4f6adc9ceffc3d7348 100644 (file)
@@ -15,6 +15,13 @@ USING: kernel accessors locals math math.intervals math.order
 
 IN: pong
 
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+! 
+! Inspired by this Ruby/Shoes version by why: http://gist.github.com/26431
+!
+! Which was based on this Nodebox version: http://billmill.org/pong.html
+! by Bill Mill.
+! 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
 : clamp-to-interval ( x interval -- x )
@@ -95,28 +102,37 @@ METHOD: draw ( <ball>   -- ) [ pos>>       ] [ diameter>> 2 / ] bi circle    ;
 USE: syntax ! Switch back to core 'TUPLE:' instead of the one provided
             ! by multi-methods
 
-TUPLE: <pong> < gadget draw closed ;
+TUPLE: <pong> < gadget paused field ball player computer ;
 
-M: <pong> pref-dim*    ( <pong> -- dim ) drop { 400 400 } ;
-M: <pong> draw-gadget* ( <pong> --     ) draw>> call      ;
-M: <pong> ungraft*     ( <pong> --     ) t >>closed drop  ;
+: pong ( -- gadget )
+  <pong> new-gadget
+  T{ <play-field> { pos {   0   0 } } { dim { 400 400 } } } clone >>field
+  T{ <ball>       { pos {  50  50 } } { vel {   3   4 } } } clone >>ball
+  T{ <paddle>     { pos { 200 396 } } { dim {  75   4 } } } clone >>player
+  T{ <computer>   { pos { 200   0 } } { dim {  75   4 } } } clone >>computer ;
 
+M: <pong> pref-dim* ( <pong> -- dim ) drop { 400 400 } ;
+M: <pong> ungraft*  ( <pong> --     ) t >>paused drop  ;
+    
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: make-draw-closure ( -- closure )
+M:: <pong> draw-gadget* ( PONG -- )
 
-  ! Establish some bindings
+  PONG computer>> draw
+  PONG player>>   draw
+  PONG ball>>     draw ;
 
-  [let | PLAY-FIELD [ T{ <play-field> { pos {  0  0 } } { dim { 400 400 } } } ]
-         BALL       [ T{ <ball>       { pos { 50 50 } } { vel {   3   4 } } } ]
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-         PLAYER   [ T{ <paddle>   { pos { 200 396 } } { dim { 75 4 } } } ]
-         COMPUTER [ T{ <computer> { pos { 200   0 } } { dim { 75 4 } } } ] |
+:: iterate-system ( GADGET -- )
 
-    ! Define some internal words in terms of those bindings ...
+  [let | FIELD    [ GADGET field>>    ]
+         BALL     [ GADGET ball>>     ]
+         PLAYER   [ GADGET player>>   ]
+         COMPUTER [ GADGET computer>> ] |
 
     [wlet | align-player-with-mouse [ ( -- )
-              PLAYER PLAY-FIELD align-paddle-with-mouse ]
+              PLAYER FIELD align-paddle-with-mouse ]
 
             move-ball [ ( -- ) BALL 1 move-for ]
 
@@ -127,69 +143,52 @@ M: <pong> ungraft*     ( <pong> --     ) t >>closed drop  ;
               BALL COMPUTER { [ below? ] [ in-between-horizontally? ] } && ]
 
             bounce-off-wall? [ ( -- ? )
-              BALL PLAY-FIELD in-between-horizontally? not ] |
-
-      ! Note, we're returning a quotation.
-      ! The quotation closes over the bindings established by the 'let'.
-      ! Thus the name of the word 'make-draw-closure'.
-      ! This closure is intended to be placed in the 'draw' slot of a
-      ! <pong> gadget.
-      
+              BALL FIELD in-between-horizontally? not ]
+
+            stop-game [ ( -- ) t GADGET (>>paused) ] |
+
+      BALL FIELD in-bounds?
       [
 
-        BALL PLAY-FIELD in-bounds?
-          [
-            align-player-with-mouse
-              
-            move-ball
-  
-            ! computer reaction
-  
-            BALL COMPUTER to-the-left-of?  [ COMPUTER computer-move-left  ] when
-            BALL COMPUTER to-the-right-of? [ COMPUTER computer-move-right ] when
-
-            ! check if ball bounced off something
-              
-            player-blocked-ball?   [ BALL PLAYER   bounce-off-paddle  ] when
-            computer-blocked-ball? [ BALL COMPUTER bounce-off-paddle  ] when
-            bounce-off-wall?       [ BALL reverse-horizontal-velocity ] when
+        align-player-with-mouse
 
-            ! draw the objects
-              
-            COMPUTER draw
-            PLAYER   draw
-            BALL     draw
-  
-          ]
-        when
-
-      ] ] ] ( -- closure ) ; ! The trailing stack effect here is a workaround.
-                             ! The stack effects in the wlet expression throw
-                             ! off the effect for the whole word, so we reset
-                             ! it to the correct one here.
+        move-ball
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        ! computer reaction
 
-:: pong-loop-step ( PONG -- ? )
-  PONG closed>>
-    [ f ]
-    [ PONG relayout-1 25 milliseconds sleep t ]
-  if ;
+        BALL COMPUTER to-the-left-of?  [ COMPUTER computer-move-left  ] when
+        BALL COMPUTER to-the-right-of? [ COMPUTER computer-move-right ] when
 
-:: start-pong-thread ( PONG -- ) [ [ PONG pong-loop-step ] loop ] in-thread ;
+        ! check if ball bounced off something
+              
+        player-blocked-ball?   [ BALL PLAYER   bounce-off-paddle  ] when
+        computer-blocked-ball? [ BALL COMPUTER bounce-off-paddle  ] when
+        bounce-off-wall?       [ BALL reverse-horizontal-velocity ] when
+      ]
+      [ stop-game ]
+      if
 
-! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+  ] ] ( gadget -- ) ;
 
-: play-pong ( -- )
+! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-  <pong> new-gadget
-    make-draw-closure >>draw
-  dup "PONG" open-window
-    
-  start-pong-thread ;
+:: start-pong-thread ( GADGET -- )
+  f GADGET (>>paused)
+  [
+    [
+      GADGET paused>>
+      [ f ]
+      [ GADGET iterate-system GADGET relayout-1 25 milliseconds sleep t ]
+      if
+    ]
+    loop
+  ]
+  in-thread ;
 
 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
-: play-pong-main ( -- ) [ play-pong ] with-ui ;
+: pong-window ( -- ) pong [ "PONG" open-window ] [ start-pong-thread ] bi ;
+
+: pong-main ( -- ) [ pong-window ] with-ui ;
 
-MAIN: play-pong-main
\ No newline at end of file
+MAIN: pong-window
\ No newline at end of file