\ device \ \ device class. Specification class for a less "intelligent" device driver \ than hmsl's cannonic instrument class. This class is more "general" \ than the instrument class in the sense that it does not assume the use \ of note.on: or note.off: methods. \ \ \ description of methods: \ \ OPEN: ( -- , open device for use ) \ CLOSE: ( -- , close device after use ) \ \ RAW.OPEN: ( -- , device specific open ) \ RAW.CLOSE: ( -- , device specific close ) \ \ the OPEN: and CLOSE: methods call the corresponfing device specific method. \ Subclasses of device should override the RAW.OPEN: and RAW.CLOSE: methods. \ \ ELEMENT.ON: ( elm# sh -- , standard way to use ths device ) \ ELEMENT.OFF: ( elm# sh -- ) \ \ PUT.ON.FUNCTION: ( cfa -- ) \ PUT.OFF.FUNCTION: ( cfa -- ) \ \ ELEMENT.ON: and ELEMENT.OFF: methods call the corresponding 'interpreter' \ function. Subclasses may override the ELEMENT.ON: or ELEMENT.OFF: methods. \ \ DEFAULT: ( -- , set object to default state ) \ UPDATE: ( -- , set hardware to the object's current state ) \ RESET: ( -- , set hardware and object to default state ) \ REFRESH: ( -- , a "softer" version of update ) \ \ PREFAB: ( -- , set object to useable state ) \ \ some standard device class methods. Most of these are dummy methods here, \ but can be defined in a subclass. \ \ PUT.DATA: ( n -- ) \ GET.DATA: ( -- n ) \ \ store and retrieve miscellaneous user data. \ \ \ code: Han-earl Park \ copyright 2004 buster & friends' C-ALTO Labs \ (Valencia, January 1999 - \ (Southampton, September 2000 - \ \ MOD: HeP 01/18/99 Started project. \ MOD: HeP 02/16/99 Add UPDATE: that replaces the function of RESET: method. \ RESET: now acts as a kind of panic messgae, and sets the \ device to a "null" state. \ MOD: HeP 07/08/99 OPEN: calls UPDATE: method and not RESET: \ MOD: HeP 07/30/99 Device is closed only when the open count reaches 0. \ Add the methods RAW.OPEN: and RAW.CLOSE: \ MOD: HeP 07/30/99 Create subclass midi.device. \ MOD: HeP 08/09/99 Device is opened only when the open count is 0. \ replace the single "interp" function with hmsl standard \ on and off functions. \ MOD: HeP 11/13/99 Add the FREE: method for compatibility with jobs and \ players. \ No more error messages if closed more times than opened. \ MOD: HeP 11/16/99 Add REFRESH: method. \ MOD: HeP 03/28/00 FREE: now acts as a "force close" method, setting the \ #opened count to zero and calls RAW.CLOSE: if object \ is open. \ MOD: HeP 09/24/00 Update docs & comments. \ MOD: HeP 10/13/00 Add the PUT.DATA: and GET.DATA: methods. Not elegant, but \ still useful. \ MOD: HeP 11/03/00 Prints message on OPEN: and CLOSE: if if-debug is on. \ MOD: HeP 04-02-04 Minor change in the wording of the error messages. \ MOD: HeP 04-04-04 Trash the "no interpreter" error reporting which was too \ intrusive in tests. anew task-device method REFRESH: method RAW.OPEN: method RAW.CLOSE: :class OB.DEVICE iv-dev-#opened 0 iv=> iv-dev-on-cfa 0 iv=> iv-dev-off-cfa 0 iv=> iv-dev-data self default: [] ;m :m PREFAB: ( -- , set object to useable state ) ;m :m DEFAULT: ( -- , set object to default state ) ;m :m UPDATE: ( -- , update state of the object and the hardware ) ;m :m REFRESH: ( -- , set hardware to the object's current state ) self update: [] ;m :m RESET: ( -- , set hardware and object to the default state ) self default: [] self update: [] ;m :m RAW.OPEN: ( -- , device specific open ) self update: [] ;m :m RAW.CLOSE: ( -- , device specific close ) self reset: [] ;m : DEVICE.DEBUG.PRINT ( $method -- ) >newline space $. space name: self tab ascii ( emit .class: self ascii ) emit ; :m OPEN: ( -- , open device for use ) iv-dev-#opened dup 0= IF if-debug @ IF " open:" device.debug.print THEN self raw.open: [] THEN 1+ iv=> iv-dev-#opened ;m :m CLOSE: ( -- , close device after use ) iv-dev-#opened IF iv-dev-#opened 1 = IF if-debug @ IF " close:" device.debug.print THEN self raw.close: [] THEN iv-dev-#opened 1- iv=> iv-dev-#opened THEN ;m :m FREE: ( -- , for compatibility with jobs and players ) iv-dev-#opened IF 0 iv=> iv-dev-#opened self raw.close: [] THEN ;m :m PUT.ON.FUNCTION: ( cfa -- ) iv=> iv-dev-on-cfa ;m :m PUT.OFF.FUNCTION: ( cfa -- ) iv=> iv-dev-off-cfa ;m :m ELEMENT.ON: ( elm# sh -- ) iv-dev-on-cfa IF self iv-dev-on-cfa -3 exec.stack? ELSE 2drop THEN ;m :m ELEMENT.OFF: ( elm# sh -- ) iv-dev-off-cfa IF self iv-dev-off-cfa -3 exec.stack? ELSE 2drop THEN ;m :m PUT.DATA: ( n -- ) iv=> iv-dev-data ;m :m GET.DATA: ( -- n ) iv-dev-data ;m :m PRINT: ( -- ) cr name: self cr ." #Opened = " iv-dev-#opened 4 .r cr ." ON function = " iv-dev-on-cfa cfa. cr ." OFF function = " iv-dev-off-cfa cfa. cr ." User data = " iv-dev-data 4 .r cr ;m ;class