--- /dev/null
+USING: help.syntax help.markup kernel math classes classes.tuple\r
+calendar models ;\r
+IN: models.arrow\r
+\r
+HELP: arrow\r
+{ $class-description "Arrow model values are computed by applying a quotation to the value of another model. Arrows are automatically updated when the underlying model changes. Arrows are constructed by " { $link <arrow> } "." }\r
+{ $examples\r
+ "The following code displays a label showing the result of applying " { $link sq } " to the value 5:"\r
+ { $code\r
+ "USING: models ui.gadgets.labels ui.gadgets.panes ;"\r
+ "5 <model> [ sq ] <arrow> [ number>string ] <arrow>"\r
+ "<label-control> gadget."\r
+ }\r
+ "An exercise for the reader is to keep the original model around on the stack, and change its value to 6, observing that the label will immediately display 36."\r
+} ;\r
+\r
+HELP: <arrow>\r
+{ $values { "model" model } { "quot" { $quotation "( obj -- newobj )" } } { "arrow" "a new " { $link arrow } } }\r
+{ $description "Creates a new instance of " { $link arrow } ". The value of the new arrow model is computed by applying the quotation to the value." }\r
+{ $examples "See the example in the documentation for " { $link arrow } "." } ;\r
+\r
+ARTICLE: "models.arrow" "Arrow models"\r
+"Arrow model values are computed by applying a quotation to the value of another model."\r
+{ $subsection arrow }\r
+{ $subsection <arrow> } ;\r
+\r
+ABOUT: "models.arrow"\r
--- /dev/null
+USING: arrays generic kernel math models namespaces sequences assocs\r
+tools.test models.arrow accessors ;\r
+IN: models.arrow.tests\r
+\r
+3 <model> "x" set\r
+"x" get [ 2 * ] <arrow> dup "z" set\r
+[ 1+ ] <arrow> "y" set\r
+[ ] [ "y" get activate-model ] unit-test\r
+[ t ] [ "z" get "x" get connections>> memq? ] unit-test\r
+[ 7 ] [ "y" get value>> ] unit-test\r
+[ ] [ 4 "x" get set-model ] unit-test\r
+[ 9 ] [ "y" get value>> ] unit-test\r
+[ ] [ "y" get deactivate-model ] unit-test\r
+[ f ] [ "z" get "x" get connections>> memq? ] unit-test\r
+\r
+3 <model> "x" set\r
+"x" get [ sq ] <arrow> "y" set\r
+\r
+4 "x" get set-model\r
+\r
+"y" get activate-model\r
+[ 16 ] [ "y" get value>> ] unit-test\r
+"y" get deactivate-model\r
--- /dev/null
+! Copyright (C) 2008, 2009 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: accessors models kernel call ;\r
+IN: models.arrow\r
+\r
+TUPLE: arrow < model model quot ;\r
+\r
+: <arrow> ( model quot -- arrow )\r
+ f arrow new-model\r
+ swap >>quot\r
+ over >>model\r
+ [ add-dependency ] keep ;\r
+\r
+M: arrow model-changed\r
+ [ [ value>> ] [ quot>> ] bi* call( old -- new ) ] [ nip ] 2bi\r
+ set-model ;\r
+\r
+M: arrow model-activated [ model>> ] keep model-changed ;\r
--- /dev/null
+Arrow models apply a quotation to the value of an underlying model
+++ /dev/null
-USING: help.syntax help.markup kernel math classes classes.tuple\r
-calendar models ;\r
-IN: models.compose\r
-\r
-HELP: compose\r
-{ $class-description "Composed model values are computed by collecting the values from a sequence of underlying models into a new sequence. Composed models are automatically updated when underlying models change. Composed models are constructed by " { $link <compose> } "."\r
-$nl\r
-"A composed model whose children are all " { $link "models-range" } " conforms to the " { $link "range-model-protocol" } " and represents a point in n-dimensional space which is bounded by a rectangle." }\r
-{ $examples\r
- "The following code displays a pair of sliders, and an updating label showing their current values:"\r
- { $code\r
- "USING: models models.compose models.range ui.gadgets"\r
- "ui.gadgets.labels ui.gadgets.packs ui.gadgets.panes"\r
- "ui.gadgets.sliders ;"\r
- ""\r
- ": <funny-model> ( -- model ) 0 10 0 100 <range> ;"\r
- ": <funny-slider> ( model -- slider ) horizontal <slider> ;"\r
- ""\r
- "<funny-model> <funny-model> 2array"\r
- "[ <pile> [ horizontal <slider> add-gadget ] reduce gadget. ]"\r
- "[ <compose> [ unparse ] <filter> <label-control> gadget. ]"\r
- "bi"\r
- }\r
-} ;\r
-\r
-HELP: <compose>\r
-{ $values { "models" "a sequence of models" } { "compose" "a new " { $link compose } } }\r
-{ $description "Creates a new instance of " { $link compose } ". The value of the new compose model is obtained by mapping the " { $snippet "value" } " slot accessor over the given sequence of models." }\r
-{ $examples "See the example in the documentation for " { $link compose } "." } ;\r
-\r
-ARTICLE: "models-compose" "Composed models"\r
-"Composed model values are computed by collecting the values from a sequence of underlying models into a new sequence."\r
-{ $subsection compose }\r
-{ $subsection <compose> } ;\r
-\r
-ABOUT: "models-compose"\r
+++ /dev/null
-USING: arrays generic kernel math models namespaces sequences assocs\r
-tools.test models.compose accessors locals ;\r
-IN: models.compose.tests\r
-\r
-! Test compose\r
-[ ] [\r
- 1 <model> "a" set\r
- 2 <model> "b" set\r
- "a" get "b" get 2array <compose> "c" set\r
-] unit-test\r
-\r
-[ ] [ "c" get activate-model ] unit-test\r
-\r
-[ { 1 2 } ] [ "c" get value>> ] unit-test\r
-\r
-[ ] [ 3 "b" get set-model ] unit-test\r
-\r
-[ { 1 3 } ] [ "c" get value>> ] unit-test\r
-\r
-[ ] [ { 4 5 } "c" get set-model ] unit-test\r
-\r
-[ { 4 5 } ] [ "c" get value>> ] unit-test\r
-\r
-[ ] [ "c" get deactivate-model ] unit-test\r
-\r
-TUPLE: an-observer { i integer } ;\r
-\r
-M: an-observer model-changed nip [ 1+ ] change-i drop ;\r
-\r
-[ 1 0 ] [\r
- [let* | m1 [ 1 <model> ]\r
- m2 [ 2 <model> ]\r
- c [ { m1 m2 } <compose> ]\r
- o1 [ an-observer new ]\r
- o2 [ an-observer new ] |\r
- \r
- o1 m1 add-connection\r
- o2 m2 add-connection\r
-\r
- c activate-model\r
- \r
- "OH HAI" m1 set-model\r
- o1 i>>\r
- o2 i>>\r
- ]\r
-] unit-test
\ No newline at end of file
+++ /dev/null
-! Copyright (C) 2008 Slava Pestov.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: accessors models kernel sequences ;\r
-IN: models.compose\r
-\r
-TUPLE: compose < model ;\r
-\r
-: new-compose ( models class -- compose )\r
- f swap new-model\r
- swap clone >>dependencies ; inline\r
-\r
-: <compose> ( models -- compose )\r
- compose new-compose ;\r
-\r
-: composed-value [ dependencies>> ] dip map ; inline\r
-\r
-: set-composed-value [ dependencies>> ] dip 2each ; inline\r
-\r
-M: compose model-changed\r
- nip\r
- dup [ value>> ] composed-value >>value\r
- notify-connections ;\r
-\r
-M: compose model-activated dup model-changed ;\r
-\r
-M: compose update-model\r
- dup value>> swap [ set-model ] set-composed-value ;\r
-\r
-M: compose range-value\r
- [ range-value ] composed-value ;\r
-\r
-M: compose range-page-value\r
- [ range-page-value ] composed-value ;\r
-\r
-M: compose range-min-value\r
- [ range-min-value ] composed-value ;\r
-\r
-M: compose range-max-value\r
- [ range-max-value ] composed-value ;\r
-\r
-M: compose range-max-value*\r
- [ range-max-value* ] composed-value ;\r
-\r
-M: compose set-range-value\r
- [ clamp-value ] keep\r
- [ set-range-value ] set-composed-value ;\r
-\r
-M: compose set-range-page-value\r
- [ set-range-page-value ] set-composed-value ;\r
-\r
-M: compose set-range-min-value\r
- [ set-range-min-value ] set-composed-value ;\r
-\r
-M: compose set-range-max-value\r
- [ set-range-max-value ] set-composed-value ;\r
+++ /dev/null
-Composed models combine the values of a sequence of models into one
{ $examples\r
"The following code displays a sliders and a label which is updated half a second after the slider stops changing:"\r
{ $code\r
- "USING: models models.delay models.filter models.range"\r
+ "USING: models models.delay models.arrow models.range"\r
"ui.gadgets ui.gadgets.labels ui.gadgets.sliders ui.gadgets.panes"\r
"math.parser calendar ;"\r
""\r
" 0 10 0 100 <range> horizontal <slider> ;"\r
""\r
"<funny-slider> dup gadget."\r
- "model>> 1/2 seconds <delay> [ unparse ] <filter>"\r
+ "model>> 1/2 seconds <delay> [ unparse ] <arrow>"\r
"<label-control> gadget."\r
}\r
} ;\r
+++ /dev/null
-USING: help.syntax help.markup kernel math classes classes.tuple\r
-calendar models ;\r
-IN: models.filter\r
-\r
-HELP: filter\r
-{ $class-description "Filter model values are computed by applying a quotation to the value of another model. Filters are automatically updated when the underlying model changes. Filters are constructed by " { $link <filter> } "." }\r
-{ $examples\r
- "The following code displays a label showing the result of applying " { $link sq } " to the value 5:"\r
- { $code\r
- "USING: models ui.gadgets.labels ui.gadgets.panes ;"\r
- "5 <model> [ sq ] <filter> [ number>string ] <filter>"\r
- "<label-control> gadget."\r
- }\r
- "An exercise for the reader is to keep the original model around on the stack, and change its value to 6, observing that the label will immediately display 36."\r
-} ;\r
-\r
-HELP: <filter>\r
-{ $values { "model" model } { "quot" { $quotation "( obj -- newobj )" } } { "filter" "a new " { $link filter } } }\r
-{ $description "Creates a new instance of " { $link filter } ". The value of the new filter model is computed by applying the quotation to the value." }\r
-{ $examples "See the example in the documentation for " { $link filter } "." } ;\r
-\r
-ARTICLE: "models-filter" "Filter models"\r
-"Filter model values are computed by applying a quotation to the value of another model."\r
-{ $subsection filter }\r
-{ $subsection <filter> } ;\r
-\r
-ABOUT: "models-filter"\r
+++ /dev/null
-USING: arrays generic kernel math models namespaces sequences assocs\r
-tools.test models.filter accessors ;\r
-IN: models.filter.tests\r
-\r
-! Test multiple filters\r
-3 <model> "x" set\r
-"x" get [ 2 * ] <filter> dup "z" set\r
-[ 1+ ] <filter> "y" set\r
-[ ] [ "y" get activate-model ] unit-test\r
-[ t ] [ "z" get "x" get connections>> memq? ] unit-test\r
-[ 7 ] [ "y" get value>> ] unit-test\r
-[ ] [ 4 "x" get set-model ] unit-test\r
-[ 9 ] [ "y" get value>> ] unit-test\r
-[ ] [ "y" get deactivate-model ] unit-test\r
-[ f ] [ "z" get "x" get connections>> memq? ] unit-test\r
-\r
-3 <model> "x" set\r
-"x" get [ sq ] <filter> "y" set\r
-\r
-4 "x" get set-model\r
-\r
-"y" get activate-model\r
-[ 16 ] [ "y" get value>> ] unit-test\r
-"y" get deactivate-model\r
+++ /dev/null
-! Copyright (C) 2008, 2009 Slava Pestov.\r
-! See http://factorcode.org/license.txt for BSD license.\r
-USING: accessors models kernel call ;\r
-IN: models.filter\r
-\r
-TUPLE: filter < model model quot ;\r
-\r
-: <filter> ( model quot -- filter )\r
- f filter new-model\r
- swap >>quot\r
- over >>model\r
- [ add-dependency ] keep ;\r
-\r
-M: filter model-changed\r
- [ [ value>> ] [ quot>> ] bi* call( old -- new ) ] [ nip ] 2bi\r
- set-model ;\r
-\r
-M: filter model-activated [ model>> ] keep model-changed ;\r
+++ /dev/null
-Filter models apply a quotation to the value of an underlying model
{ $subsection activate-model }
{ $subsection deactivate-model }
{ $subsection "models-impl" }
-{ $subsection "models-filter" }
-{ $subsection "models-compose" }
+{ $subsection "models.arrow" }
+{ $subsection "models.product" }
{ $subsection "models-history" }
{ $subsection "models-range" }
{ $subsection "models-delay" } ;
-USING: arrays generic kernel math models models.compose
+USING: arrays generic kernel math models models.product
namespaces sequences assocs accessors tools.test ;
IN: models.tests
3 <model> "model-a" set
4 <model> "model-b" set
-"model-a" get "model-b" get 2array <compose> "model-c" set
+"model-a" get "model-b" get 2array <product> "model-c" set
"model-c" get activate-model
[ { 3 4 } ] [ "model-c" get value>> ] unit-test
--- /dev/null
+USING: help.syntax help.markup kernel math classes classes.tuple\r
+calendar models ;\r
+IN: models.product\r
+\r
+HELP: product\r
+{ $class-description "Product model values are computed by collecting the values from a sequence of underlying models into a new sequence. Product models are automatically updated when underlying models change. Product models are constructed by " { $link <product> } "."\r
+$nl\r
+"A product model whose children are all " { $link "models-range" } " conforms to the " { $link "range-model-protocol" } " and represents a point in n-dimensional space which is bounded by a rectangle." }\r
+{ $examples\r
+ "The following code displays a pair of sliders, and an updating label showing their current values:"\r
+ { $code\r
+ "USING: models models.product models.range ui.gadgets"\r
+ "ui.gadgets.labels ui.gadgets.packs ui.gadgets.panes"\r
+ "ui.gadgets.sliders ;"\r
+ ""\r
+ ": <funny-model> ( -- model ) 0 10 0 100 <range> ;"\r
+ ": <funny-slider> ( model -- slider ) horizontal <slider> ;"\r
+ ""\r
+ "<funny-model> <funny-model> 2array"\r
+ "[ <pile> [ horizontal <slider> add-gadget ] reduce gadget. ]"\r
+ "[ <product> [ unparse ] <arrow> <label-control> gadget. ]"\r
+ "bi"\r
+ }\r
+} ;\r
+\r
+HELP: <product>\r
+{ $values { "models" "a sequence of models" } { "product" "a new " { $link product } } }\r
+{ $description "Creates a new instance of " { $link product } ". The value of the new product model is obtained by mapping the " { $snippet "value" } " slot accessor over the given sequence of models." }\r
+{ $examples "See the example in the documentation for " { $link product } "." } ;\r
+\r
+ARTICLE: "models.product" "Product models"\r
+"Product model values are computed by collecting the values from a sequence of underlying models into a new sequence."\r
+{ $subsection product }\r
+{ $subsection <product> } ;\r
+\r
+ABOUT: "models.product"\r
--- /dev/null
+USING: arrays generic kernel math models namespaces sequences assocs\r
+tools.test models.product accessors locals ;\r
+IN: models.product.tests\r
+\r
+[ ] [\r
+ 1 <model> "a" set\r
+ 2 <model> "b" set\r
+ "a" get "b" get 2array <product> "c" set\r
+] unit-test\r
+\r
+[ ] [ "c" get activate-model ] unit-test\r
+\r
+[ { 1 2 } ] [ "c" get value>> ] unit-test\r
+\r
+[ ] [ 3 "b" get set-model ] unit-test\r
+\r
+[ { 1 3 } ] [ "c" get value>> ] unit-test\r
+\r
+[ ] [ { 4 5 } "c" get set-model ] unit-test\r
+\r
+[ { 4 5 } ] [ "c" get value>> ] unit-test\r
+\r
+[ ] [ "c" get deactivate-model ] unit-test\r
+\r
+TUPLE: an-observer { i integer } ;\r
+\r
+M: an-observer model-changed nip [ 1+ ] change-i drop ;\r
+\r
+[ 1 0 ] [\r
+ [let* | m1 [ 1 <model> ]\r
+ m2 [ 2 <model> ]\r
+ c [ { m1 m2 } <product> ]\r
+ o1 [ an-observer new ]\r
+ o2 [ an-observer new ] |\r
+ \r
+ o1 m1 add-connection\r
+ o2 m2 add-connection\r
+\r
+ c activate-model\r
+ \r
+ "OH HAI" m1 set-model\r
+ o1 i>>\r
+ o2 i>>\r
+ ]\r
+] unit-test
\ No newline at end of file
--- /dev/null
+! Copyright (C) 2008 Slava Pestov.\r
+! See http://factorcode.org/license.txt for BSD license.\r
+USING: accessors models kernel sequences ;\r
+IN: models.product\r
+\r
+TUPLE: product < model ;\r
+\r
+: new-product ( models class -- product )\r
+ f swap new-model\r
+ swap clone >>dependencies ; inline\r
+\r
+: <product> ( models -- product )\r
+ product new-product ;\r
+\r
+: product-value ( model quot -- seq )\r
+ [ dependencies>> ] dip map ; inline\r
+\r
+: set-product-value ( seq model quot -- )\r
+ [ dependencies>> ] dip 2each ; inline\r
+\r
+M: product model-changed\r
+ nip\r
+ dup [ value>> ] product-value >>value\r
+ notify-connections ;\r
+\r
+M: product model-activated dup model-changed ;\r
+\r
+M: product update-model\r
+ dup value>> swap [ set-model ] set-product-value ;\r
+\r
+M: product range-value\r
+ [ range-value ] product-value ;\r
+\r
+M: product range-page-value\r
+ [ range-page-value ] product-value ;\r
+\r
+M: product range-min-value\r
+ [ range-min-value ] product-value ;\r
+\r
+M: product range-max-value\r
+ [ range-max-value ] product-value ;\r
+\r
+M: product range-max-value*\r
+ [ range-max-value* ] product-value ;\r
+\r
+M: product set-range-value\r
+ [ clamp-value ] keep\r
+ [ set-range-value ] set-product-value ;\r
+\r
+M: product set-range-page-value\r
+ [ set-range-page-value ] set-product-value ;\r
+\r
+M: product set-range-min-value\r
+ [ set-range-min-value ] set-product-value ;\r
+\r
+M: product set-range-max-value\r
+ [ set-range-max-value ] set-product-value ;\r
--- /dev/null
+Product models combine the values of a sequence of models into one
! Copyright (C) 2008 Slava Pestov.\r
! See http://factorcode.org/license.txt for BSD license.\r
USING: accessors kernel models arrays sequences math math.order\r
-models.compose ;\r
+models.product ;\r
IN: models.range\r
\r
-TUPLE: range < compose ;\r
+TUPLE: range < product ;\r
\r
: <range> ( value page min max -- range )\r
- 4array [ <model> ] map range new-compose ;\r
+ 4array [ <model> ] map range new-product ;\r
\r
: range-model ( range -- model ) dependencies>> first ;\r
: range-page ( range -- model ) dependencies>> second ;\r
! Copyright (C) 2008, 2009 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
-USING: arrays fry kernel models.compose models.filter
+USING: arrays fry kernel models.product models.arrow
sequences unicode.case ;
IN: models.search
: <search> ( values search quot -- model )
- [ 2array <compose> ] dip
- '[ first2 _ curry filter ] <filter> ;
+ [ 2array <product> ] dip
+ '[ first2 _ curry filter ] <arrow> ;
: <string-search> ( values search quot -- model )
'[ swap @ [ >case-fold ] bi@ subseq? ] <search> ;
! Copyright (C) 2008 Slava Pestov
! See http://factorcode.org/license.txt for BSD license.
-USING: arrays fry kernel models.compose models.filter
+USING: arrays fry kernel models.product models.arrow
sequences sorting ;
IN: models.sort
: <sort> ( values sort -- model )
- 2array <compose> [ first2 sort ] <filter> ;
\ No newline at end of file
+ 2array <product> [ first2 sort ] <arrow> ;
\ No newline at end of file