\ ob.space \ \ hp_space \ class of morph that holds particles and scheules the updating of their \ states by poling the force object. part of the collection of software \ componenets: "henri poincare." \ \ description of methods: \ \ NEW: ( n -- , allocate memory to hold n particles ) \ \ GET.ON.TIME: ( -- ticks , on time for use by instruments ) \ \ ACT.SEQUENTIAL: ( -- , sequentially send update particles ) \ ACT.PARALLEL: ( -- , update particles in parallel ) \ \ TASK: ( -- , check time and maybe update particles ) \ UPDATE: ( -- , poll force and update particles ) \ \ TASK: \ --> clear force values of all particle objects \ --> request that force object calculate forces for each puck \ --> update puck status (position, velocity, etc) \ \ FREEZE: ( -- , stop the motion of all particles ) \ \ BUILD: ( p1 p2...pn n for ins -- , add instrument force & n particles ) \ PREFAB: ( -- , create 3 particles one instrument and one force object ) \ \ based on ideas presented by Joel Ryan. \ \ Code: Han-earl Park \ Copyright 2000 Buster & Friends C-ALTO Labs \ (Den Haag, December 1997 - \ (Valencia, October 1998 - \ (Southampton, May 2000 - \ \ MOD: HeP 10/24/98 Yet another redesign of the components with the addition \ of the space class which does all the calculation. \ thus, the puck classes no longer hold any "intelligence." \ thanks to mark trayle for suggesting this arrangement. \ !!! implement }stuff: !!! \ MOD: HeP 10/29/98 Redesigned so that the force class acts as a pluggin to \ the space class. Thus the scheduling intelligence is \ kept part of ob.space, but the forces are polled from \ the force objects. \ MOD: HeP 10/30/98 Move the dimension enabling to the force and puck classes. \ another redesign: ob.space can only hold one force object! \ (just create a class of ob.force that can hold more than \ one force object) \ MOD: HeP 11/17/98 The methods put.size: put.wrap: put.enable: etc, and \ corresponding and get...: methods now work like the \ old put...dim: and get...dim: methods. To alter all \ dimensions, pass -1 as the dimension number. \ Added parallel and sequential updating of praticles. \ MOD: HeP 11/19/98 Add get.on.time: method. This is used to update the \ value on.time, which is used by many interpreters. \ MOD: HeP 11/29/98 The put.wrap: get.wrap: and put.size: get.size: are \ now "pass through" methods with the actual functionality \ is in the particle class. \ MOD: HeP 12/14/98 Rewrite (task): method to use elm.calc.force: if in \ sequential mode. \ MOD: HeP 03/02/99 Finished (re)writing (task): \ MOD: HeP 07/27/99 Change name of components to "henri poincare" \ MOD: HeP 11/16/99 Rename (TASK): as UPDATE: \ add standard REFRESH: method. \ MOD: HeP 05/28/00 Print.element: checks for non-zero values, and prints \ class name. \ \ ToDo: some way of playing instrument from space object. include? task-hp_particle myt:hp_particle include? task-hp_force myt:hp_force anew task-hp_space 255 value hp_default_size method GET.ON.TIME: :class OB.SPACE iv-space-parallel? ;m :m DEFAULT.HIERARCHY: ( -- , reset instrument too ) many: self 0 DO i get: self default: [] LOOP \ iv-space-force IF iv-space-force default: [] THEN \ default.hierarchy: super \ reset instrument ;m :m NEW: ( #obj -- , allocate memory to hold bodies ) new: super ;m :m FREE: ( -- ) free: super ;m :m FREE.HIERARCHY: ( -- , sends free: to force and particles ) many: self 0 DO i get: self free: [] LOOP \ iv-space-force IF iv-space-force free: [] THEN \ free: super ;m \ sequential or parallel update of particles :M ACT.SEQUENTIAL: ( -- , sequentially send update: messages ) false iv=> iv-space-parallel? ;M :M ACT.PARALLEL: ( -- , send update: to particles "simultaneously" ) true iv=> iv-space-parallel? ;M \ force object :m PUT.FORCE: ( force -- , assign a force object ) iv=> iv-space-force ;m :m GET.FORCE: ( -- force , retrieve force object address ) iv-space-force ;m \ change state of particles :m FREEZE: ( -- , "freeze" all particles ) many: self 0 DO i get: self freeze: [] LOOP ;m :m REFRESH: ( -- , refresh all particles ) many: self 0 DO i get: self refresh: [] LOOP ;m :m RANDOMIZE: ( -- , randomize particle position & velocity ) many: self 0 DO i get: self randomize: [] LOOP ;m \ on time \ this is called in late bound form during execution :m GET.ON.TIME: ( -- ticks , on time value for certain interpreters ) iv-space-parallel? IF self get.duration: [] ELSE self get.duration: [] many: self * THEN ;m \ execution :m CUSTOM.EXEC: ( -- flag , start tasking ) many: self 0> IF false iv=> iv-col-done? iv-jb-instrument ?dup IF open: [] THEN \ many: self 0 DO i get: self open: [] \ open each particle LOOP \ self ao.post false ELSE vtime@ true THEN ;m :m TERMINATE: ( time -- , stop tasking ) iv-if-active IF job.stop \ many: self 0 DO i get: self close: [] \ close each particle LOOP \ morph.stop ELSE drop THEN ;m \ task : SPACE.CLEAR.FORCE ( p -- , zero force value of the particle ) >r r@ dimension: [] 0 DO 0 LOOP hp_force r> PUT: [] ; : SPACE.CALC.FORCE ( -- , update all particles ) many: self 0 DO i get: self space.clear.force LOOP self iv-space-force calc.force: [] \ many: self 0 DO i get: self update: [] LOOP ; : SPACE.ELM.CALC.FORCE ( -- , update only current particle ) where: self dup get: self space.clear.force self iv-space-force elm.calc.force: [] \ nextwrap: self update: [] ; :m UPDATE: ( -- ) iv-space-force IF self get.on.time: [] -> on.time \ iv-space-parallel? IF SPACE.CALC.FORCE ELSE SPACE.ELM.CALC.FORCE THEN THEN ;m : SPACE.EXEC.STUFF ( -- , call parent task: method ) jb.in.time? \ is it too late? IF \ done? default_dur self self UPDATE: [] THEN self get.duration: [] \ late bounds so that subclasses can override jb.set.delay ; :m TASK: ( -- , check if time ) iv-time-next doitnow? IF iv-col-done? IF col.do.repeat iv-repcount 0= IF iv-time-next self terminate: [] ELSE false iv=> iv-col-done? iv-time-next doitnow? \ in case of repeat delay IF SPACE.EXEC.STUFF THEN THEN ELSE SPACE.EXEC.STUFF THEN THEN ;m \ print :m PRINT.ELEMENT: ( elm# -- ) get: self ?dup IF dup name: [] tab .class: [] ELSE ." --" THEN ;m :m PRINT: ( -- ) print: super ?pause \ ." Forces = " iv-space-force ob.name cr ;m \ utilities :m BUILD: ( p1 p2...pn n force instr -- , add instrument force & n pucks ) put.instrument: self put.force: self \ dup new: self 0 DO add: self LOOP ;m :m PREFAB: ( -- , instantiate instrument force and 3 particles ) free: self 3 new: self \ 3 0 DO instantiate ob.particle dup prefab: [] add: self LOOP instantiate ob.force put.force: self instantiate ob.midi.instrument put.instrument: self \ default.hierarchy: self ;m ;class