User:Ian Clark/YellowJ

From J Wiki
Jump to navigation Jump to search

How to terminate a timer-process with the yellow J

The following script is self-explanatory.

Try the code with  JBREAK=:1 and:  JBREAK=:0 .

JBREAK=:0 disables the apparatus to check the "jbreak" file, which is located in: ~temp/jbreak/ .

Then the yellow J won't (reliably) stop the animation, and you'd need to execute RUNNING_z_=: 0

e.g. by use of Ctrl+R in an IJS window.

The script

NB. How to poll the yellow-J (jbreak)
NB. [[User:Ian Clark|Ian Clark]] Fri 27 May 2011 20:28:47

JBREAK=: 1	NB. Enable termination by Yellow-J

NB. ==============================================
NB. TO SEE THE EFFECT OF DISALLOWING THE YELLOW-J:
NB. SET: JBREAK=: 0
NB. SINCE THE DUTY CYCLE IS TIMER-DRIVEN,
NB. THE YELLOW-J DOES NOT (NORMALLY) HALT IT.
NB. ==============================================

	NB. -----------------------
	NB. Crude animation example
	NB. -----------------------

WORM=: '--->--->'	NB. animated contents
DELAY=: 0.2		NB. timer delay in SECONDS

doframe=: 3 : 0
	NB. draw next animation frame
smclear''
smoutput 8$'='
smoutput WORM=: _1 |. WORM
)

duty_cycle=: 3 : 0
	NB. animation duty-cycle
firstpass=. y	NB. (This may differ in future versions)
doframe''
if. firstpass do.
  sess 'duty_cycle:' ; 'firstpass'
  JBD=: 1!:0< JBF=: 9!:46''	NB. dir and pathname of jbreak file
  RUNNING_z_=: 1		NB. in z-locale --> seen everywhere
end.
	NB. If jbreak dir has changed, halt duty cycle ...
if. JBREAK *. -. JBD-: 1!:0< JBF do. RUNNING_z_=: 0 end.
if. RUNNING do. DELAY timexec 'duty_cycle 0'
else. sess 'duty_cycle:' ; 'RUNNING=' ; RUNNING
end.
)

immx=: runimmx1_jijs_	NB. this version echoes: y
immx=: runimmx0_jijs_	NB. this version is silent
nb=: [: ([: }. ([: ; (' ' (,&.>) ]))) (":&.>)
run=: duty_cycle bind 1
sess=: smoutput @ nb	NB. boxed output --> 1 line

smclear=: 3 : 0
	NB. clear the IJX window
try.
  if. IFIJX_0_ do.	NB. provided locale 0 is IJX...
    wd 'psel ',SMHWNDP_0_
    wd 'set e ""'
  else. @@		NB. force an error
  end.
catch.
  smoutput 'smclear: cannot identify J session window'
end.
)

timexec=: 3 : 0
	NB. execute stmt: y ONCE after x msec
DELAY timexec y
:
sess=. empty	NB. comment-out this line for trace
	NB. x is msec delay before executing phrase: y
	NB. if x<0 stop systimer and immx: y
	NB. if x=0 simply stop systimer.
if.     x=0 do.  wd 'timer 0'
  sess 'timexec:' ; 'stop systimer'
elseif. x<0 do.  immx y [ wd 'timer 0'
  sess 'timexec:' ; 'stop systimer and execute:' ; y
elseif. x>0 do.
  sys_timer_z_=: (_1&timexec) bind y
  wd nb 'timer' ; (<.x*1000)	NB. x is in SECONDS
  sess 'timexec: after' ; x ; 'seconds execute:' ; y
end.
)

smoutput 0 : 0
NB. To run the demo...
   run''
NB. or...
   duty_cycle 1

NB. To stop the animation, launch jbreak (the yellow J).
NB. Alternatively re-enter (Ctrl+R) one of these lines...
   RUNNING_z_=: 0	NB. flag: 1= continue the duty cycle
   0 timexec 0		NB. stop systimer
   wd 'timer 0'		NB. stop systimer directly
)

Notes

  • The principle is simple. When the yellow-J is launched, it updates the timestamp of the "jbreak" file. The verb duty_cycle fetches the directory entry of this file (which contains the timestamp) and watches for it to change.
  • This kind of duty cycle does not use a repeating timer. To achieve better control (during development) the verb duty_cycle sets systimer to call itself once-only after a given time interval (DELAY). It then turns off the timer and performs some checks (including reading the flag RUNNING_z_) and only if it is happy will it set the timer again for another duty cycle. This allows the J user to carry on with coding tasks in the foreground (which may give errors), with the duty cycle running invisibly in the background and trying to stay out of the way. And if duty_cycle is knocked off its horse, it doesn't get dragged along by the reins.
  • However if you want to use a repeating timer, the technique is similar, but you must stop systimer directly, using (wd 'timer 0').