GolfService Example Class
:Class GolfService
:Using System
:Field Private GOLFILE←'' ⍝ Name of Golf data file
:Field Private GOLFID←0 ⍝ Tie number Golf data file
:Class GolfCourse
:Field Public Code←¯1
:Field Public Name←''
∇ ctor args
:Implements Constructor
:Access Public Instance
Code Name←args
⎕DF Name,'(',(⍕Code),')'
∇
:EndClass
:Class Slot
:Field Public Time
:Field Public Players
∇ ctor1 t
:Implements Constructor
:Access Public Instance
Time←t
Players←0⍴⊂''
∇
∇ ctor2 (t pl)
:Implements Constructor
:Access Public Instance
Time Players←t pl
∇
∇ format
:Implements Trigger Players
⎕DF⍕Time Players
∇
:EndClass
:Class Booking
:Field Public OK
:Field Public Course
:Field Public TeeTime
:Field Public Message
∇ ctor args
:Implements Constructor
:Access Public Instance
OK Course TeeTime Message←args
∇
∇ format
:Implements Trigger OK,Message
⎕DF⍕Course TeeTime(⊃OK⌽Message'OK')
∇
:EndClass
:Class StartingSheet
:Field Public OK
:Field Public Course
:Field Public Date
:Field Public Slots←⎕NULL
:Field Public Message
∇ ctor args
:Implements Constructor
:Access Public Instance
OK Course Date←args
∇
∇ format
:Implements Trigger OK,Message
⎕DF⍕2 1⍴(⍕Course Date)(↑⍕¨Slots)
∇
:EndClass
∇ ctor file
:Implements Constructor
:Access Public Instance
GOLFILE←file
⎕FUNTIE(((↓⎕FNAMES)~' ')⍳⊂GOLFILE)⊃⎕FNUMS,0
:Trap 22
GOLFID←GOLFILE ⎕FTIE 0
:Else
InitFile
:EndTrap
∇
∇ dtor
:Implements Destructor
⎕FUNTIE GOLFID
∇
∇ InitFile;COURSECODES;COURSES;INDEX;I
:Access Public
:If GOLFID≠0
GOLFILE ⎕FERASE GOLFID
:EndIf
GOLFID←GOLFILE ⎕FCREATE 0
COURSECODES←1 2 3
COURSES←'St Andrews' 'Hindhead' 'Basingstoke'
INDEX←(⍴COURSES)⍴0
COURSECODES COURSES INDEX ⎕FAPPEND GOLFID
:For I :In ⍳⍴COURSES
INDEX[I]←⍬ ⍬ ⎕FAPPEND 1
:EndFor
COURSECODES COURSES INDEX ⎕FREPLACE GOLFID 1
∇
∇ R←GetCourses;COURSECODES;COURSES;INDEX
:Access Public
COURSECODES COURSES INDEX←⎕FREAD GOLFID 1
R←{⎕NEW GolfCourse ⍵}¨↓⍉↑COURSECODES COURSES
∇
∇ R←GetStartingSheet ARGS;CODE;COURSE;DATE;COURSECODES
;COURSES;INDEX;COURSEI;IDN
;DATES;COMPS;IDATE;TEETIMES
;GOLFERS;I;T
:Access Public
CODE DATE←ARGS
COURSECODES COURSES INDEX←⎕FREAD GOLFID 1
COURSEI←COURSECODES⍳CODE
COURSE←⎕NEW GolfCourse(CODE(COURSEI⊃COURSES,⊂''))
R←⎕NEW StartingSheet(0 COURSE DATE)
:If COURSEI>⍴COURSECODES
R.Message←'Invalid course code'
:Return
:EndIf
IDN←2 ⎕NQ'.' 'DateToIDN',DATE.(Year Month Day)
DATES COMPS←⎕FREAD GOLFID,COURSEI⊃INDEX
IDATE←DATES⍳IDN
:If IDATE>⍴DATES
R.Message←'No Starting Sheet available'
:Return
:EndIf
TEETIMES GOLFERS←⎕FREAD GOLFID,IDATE⊃COMPS
T←DateTime.New¨(⊂DATE.(Year Month Day)),¨↓[1]
24 60 1⊤TEETIMES
R.Slots←{⎕NEW Slot ⍵}¨T,∘⊂¨↓GOLFERS
R.OK←1
∇
∇ R←MakeBooking ARGS;CODE;COURSE;SLOT;TEETIME
;COURSECODES;COURSES;INDEX
;COURSEI;IDN;DATES;COMPS;IDATE
;TEETIMES;GOLFERS;OLD;COMP;HOURS
;MINUTES;NEAREST;TIME;NAMES;FREE
;FREETIMES;I;J;DIFF
:Access Public
⍝ If GimmeNearest is 0, tries for specified time ⍝ If GimmeNearest is 1, gets nearest time
CODE TEETIME NEAREST←3↑ARGS
COURSECODES COURSES INDEX←⎕FREAD GOLFID 1
COURSEI←COURSECODES⍳CODE
COURSE←⎕NEW GolfCourse(CODE(COURSEI⊃COURSES,⊂''))
SLOT←⎕NEW Slot TEETIME
R←⎕NEW Booking(0 COURSE SLOT'')
:If COURSEI>⍴COURSECODES
R.Message←'Invalid course code'
:Return
:EndIf
:If TEETIME.Now>TEETIME
R.Message←'Requested tee-time is in the past'
:Return
:EndIf
:If TEETIME>TEETIME.Now.AddDays 30
R.Message←'Requested tee-time is more than 30
days from now'
:Return
:EndIf
IDN←2 ⎕NQ'.' 'DateToIDN',TEETIME.(Year Month Day)
DATES COMPS←⎕FREAD GOLFID,COURSEI⊃INDEX
IDATE←DATES⍳IDN
:If IDATE>⍴DATES
TEETIMES←(24 60⊥7 0)+10ׯ1+⍳1+8×6
GOLFERS←((⍴TEETIMES),4)⍴⊂''llowed per tee time
:If 0=OLD←⊃(DATES<2 ⎕NQ'.' 'DateToIDN',3↑⎕TS)/
⍳⍴DATES
COMP←(TEETIMES GOLFERS)⎕FAPPEND GOLFID
DATES,←IDN
COMPS,←COMP
(DATES COMPS)⎕FREPLACE GOLFID,COURSEI⊃INDEX
:Else
DATES[OLD]←IDN
(TEETIMES GOLFERS)⎕FREPLACE GOLFID,
COMP←OLD⊃COMPS
DATES COMPS ⎕FREPLACE GOLFID,COURSEI⊃INDEX
:EndIf
:Else
COMP←IDATE⊃COMPS
TEETIMES GOLFERS←⎕FREAD GOLFID COMP
:EndIf
HOURS MINUTES←TEETIME.(Hour Minute)
NAMES←(3↓ARGS)~⍬''
TIME←24 60⊥HOURS MINUTES
TIME←10×⌊0.5+TIME÷10
:If ~NEAREST
I←TEETIMES⍳TIME
:If I>⍴TEETIMES
:OrIf (⍴NAMES)>⊃,/+/0=⍴¨GOLFERS[I;]
R.Message←'Not available'
:Return
:EndIf
:Else
:If ~∨/FREE←(⍴NAMES)≤⊃,/+/0=⍴¨GOLFERS
R.Message←'Not available'
:Return
:EndIf
FREETIMES←(FREE×TEETIMES)+32767×~FREE
DIFF←|FREETIMES-TIME
I←DIFF⍳⌊/DIFF
:EndIf
J←(⊃,/0=⍴¨GOLFERS[I;])/⍳4
GOLFERS[I;(⍴NAMES)↑J]←NAMES
(TEETIMES GOLFERS)⎕FREPLACE GOLFID COMP
TEETIME←DateTime.New TEETIME.(Year Month Day),
3↑24 60⊤I⊃TEETIMES
SLOT.Time←TEETIME
SLOT.Players←(⊃,/0<⍴¨GOLFERS[I;])/GOLFERS[I;]
R.(OK TeeTime)←1 SLOT
∇
:EndClass