RJLRef: $CASE/02f522/LCPphase2andBdeReplay.txt - Created:021112 Revised by RJL 031030 - (see parags beginning '[RJL031030' ... ) Revised by RJL 040401 in ~/public_html/04s522/LCPupdateProject.txt. [LCPphase2andBdeReplay.hlp is RJL's revision for 02f522 of LCPphases2and3.hlp in ~/02s522/LCPproject. I included final results of the progress made during 02f522 and 02f592.] For 02f522: Class HD Hominid is replaced by IM InspectionMachine, PA (Path Assigner) is replaced by FileReader to get items to inspect and LCPMain phase 2 replaces the hominid application. Number and type of events and states may be different than below. Logfile output is optional, but is supported by genv11 and v12. We don't have a bde graphic display of the inspection history. [One trivial display of inspection history would update the heights of two HN rectangular 'pillars': One that represents items that'PASS', the other items that 'FAIL'. BDE would show the accumulated counts. The initial bde diagram can be drawn with zero node heights.\ ======================================================= 02S522/LCPPhases2and3.hlp 020502 replaced lcpPhase2and3.hlp 020416. Parags have been numbered for reference, and new comments have been inserted as 7A, 8A and 9A below. mostly about storing and accessing 64-bit function ptrs. R Lechner This note describes LCP Phase 2 (simulation) from 02s522, and a new LCP phase 3 (a generic BDE Replay interface) from 02s592. This would be a good start point for an online interface project: one-way between thread1 Inspection and thread2 bdeReplay. ============================================ I. LCP Phase 2 (Prototype Simulation) (02s522 not 02f522) ---------------------------------- 1. Phase 2 is the next assignment - you should be able to reuse the state action routines from your asgnt4 HD and HL state code blocks,, but they should now be called from the state actions of LCP. 2.For Phase 2, I expect a new version of your navigation or Path Assigner program, one which will generate event instances (EI-rows) for 3 distinct command types (ET-rows). 3. You'll need to generate event instances during each iteration of the PA navigation program, which should now have a separately callable single-stepping function that will execute one navigation step. 4. PA-generated EI-rows are directed to your HD Active Instance. HD State Actions will generate events (EI-rows) of two other event types (ET_rows) and direct them to the HX and HY Active Instances. (Setting the AIid2 fkey in the EI 'sends' the event to that AI-row's state machine. 5. Each event instance should come from a single iteration of the PA loop. To achieve single-stepping, you need to break open this loop. The stepping control could be a keypress by the user (but see Phase 3). 6. The hominid's state should be reported by logging its database changes. This logfile (plus your code) is the minimum deliverable from Phase 2. II. LCP dispatcher code changes to DoTranstion: 7. The simulator's main loop calls ProcessAllEvents. [NB: This really means process all events that are aleady on the queue, but not ones generated by actions during this call. They are saved until the next main loop iteration.] This function indirectly calls ProcessOneEvent and DoTransition. [RJL 031030: The addition of an olcState variable to each table row as a persistent field2 would permit the row to be in state 0 (now represented by hidden, non-persistent (RFLAG==0) before it is pr_added (to disable change logging) in state 1 (RFLAG==1) after it is pr-added (to enable logging), and in a new state 2 or 3 (DFLAG = 1) to mark it as deleted. A runtime FILE/SAVE[-AS] option could choose whether or not to save rows marked as deleted.] [7A. If lcpmain also processes newly added events, it could read the entire input file during one main loop iteration. (WAIT commands can be inserted in the logfile to prevent this.) Either way is OK for the Hominid and inspection projects, since the event que can always be emptied before the next navigation step. - RJL 020502] 8. DoTransition as now implemented won't work because an I4 (32-bit) ST or FT field can't hold the alpha-platform's 64-bit function pointer. You should modify the Setup Phase 1 source code to define Function pointers. (E.g., you could declare an array of ActRtn function names and pointers, just like the functions to declare ST, TR and ET array. Access to these functions will be by an index stored in table ST or FT. [02s522 project teams did this in various ways below.- RJL 021112) [8A. Three ways have been suggested and all will work: ALL OF THEM require mods to processevent.c (LCP Phase 2) and StateModel (LCP Phase 1) code. (1) and (2) require mods to schema.sch; (3) does not. (1) Split function address into 2 32-bit I4 fields hi_adr and lo_adr. Rejoin them (worry about signed vs. unsigned) by calling: (**(hi_adr<<32+lo_adr))(EIid). (2) Decode the 64-bit address into 16 Hex chars (hexadr, c16 in schema); Encode them by a2l by calling (**(a2l(STcurr->hexadr)))(EIid). (3) Store function index or state code in existing ST.ActFunc I4 field; Define array FuncTbl[STrow_count] like StateModelCreate does, and initialize each component to a STate's action routine name: During the setup phase, for each state model Sm and state code k, execute code to assign the addresses: { FuncTbl[k] = &StatekActionName; } At runtime, call it as (**FuncTbl[(ActFuncIndex=(STcurr->ActFunc))]). [8B: CAVEAT: Syntax of ptr defs and calls has not been checked above; they may require casts and more or fewer * or & operators. For example, (1) and (2) require unsigned long; I4 is a signed int.] [RJL 040401: Method 8A(4) - My recommended replacement for (1)-(3) above. It requires a project to modify newArchitecture.pdf (LCPsetup and run code). This alternate is described in ~/public_html/04s522/LCPupdateProject.txt III. LCP schema change: - 9. Note that in 8A(1) or 8A(2) above table ST or FT will need a schema change (and chgen rerun): A function pointer array index must replace the ActRtn pointer value. A new post-condition on pr_load is that the name at this array index matches the ActRtn name in table ST or FT. [Bde2htm can only create a browsable documentation if HNcurr->nodeName also matches a switch(state) case name in the source code.-RJL021112] In 8A(3) the index is still stored as an I4, so the schema could stay the same (its content is renamed in my call above). [In fact, by using the ST-row number (STcurr->STid) modulo 256) as an index, we can ignore the ActRtn field altogether. LCP Phase1 and Phase2 code still needs changes.] [RJL040401: I recommend splititing the ACtRtn index into SMrow# and STrow#: If SMrow range is [1..SM.rcount] and the ST-row range is [1..ST.rcount], then one state code is SMrow# * max(SM-->ST_child_count) + ST_row#.] IV. LCP Phase 3 (new): Design of BDE REPLAY system: ----------------------------------------------- 10. [LCP Phase 3 is a continuation of spring 2002 work in $CASE/02s592 - it is not an 02f522 responsibility, although I know they would welcome your test and bug-finding help:-)] 11. If bde -DREPLAY can open your logfile as input, it can display the hominid motion. SJaganathan's version of bde can now accept a keypress input, and call an arbitrarily-named callback function. If that callback 'wraps' your navigator's single-step function call, step control can come from within the bde runtime environment (which is NOT a vt100 text window). [RJL Update 021112: This means your application gets linked into bde.exe. Otherwise, a file must be generated for bde to replay later (or pipe in now). [RJL Update 021112: 'bde logfile.txt' will begin the replay process IFF line1 contains the "SR" (StartReplay) command, AND an initial checkpoint file logfileDB1.dat exists. LogfileDB1.txt was created by calling startlog in an earlier bde or other application. (In the hominid project, I used bdeivcpp to draw and bde to edit and pr_dump the initial diagram to ringPathDB1.dat. Only hominid changes were logged to ringPath.txt. Pr_replay initializes bde by calling pr_load on logfileDB1.dat before enabling the replay_log callback on logfile.txt.] 12. [This section updated by RJL 021112] The method by which bde will play back hominid motion was implemented in 02f592. Its design concept is described below: [RJL031030: Note: genv12 must be executed with -DGENLOG to generate pr_log.c.] (1) Build bde with "#define BDELOG" in bde/configure.h. This compiles bde/pr_util/pr_log.c and bde/src/bdeReplay.cc. (new): Bde now accepts argv[1]= filename.* as the file to be opened. [ Current filetypes are {dat,txt} but the next one will be 'bde'.] If argv[1] is missing, you must use the bde menu's 'File/Open menu option to select the filename. (2) If pr_load finds "SR" in line 1 after a successful FileOpen command, it begins replay by closing filename.dat and calling pr_replay: pr_replay("filename.dat", viewname"); //Caveat: check syntax :-) Otherwise the file is opened [and HG#1 displayed?] as an ordinary diagram to be edited. (3) pr_replay does its normal file name processing, calls load_data( to initialize the database from checkpoint or snapshot filenameDB1.dat, reopens the log input file filename.dat and confirms the "SR" command. Pr_replay has been modified to initialze a global replayState to State0. This enables a bde/X11-specific callback function Keypress() in bdeReplay.cc to execute briefly and then return. (4) Further replay actions depend on events that interrupt the X11 main event loop in bde/src/init.cc (e.g. the Hominid playback used a keypress event). These external events invoke the Keypress callback function's switch(replayState). State0's action verifies the "SR" command, the next command(s), changes replayState to State1 and returns. [RJL031030: Keypress now calls replay_log() in pr_log.c to replay database change commands, and then does two bde-specific functions updatedisplaylist() and ReDraw() before exiting back to the X11AppMainLoop event dispatcher. ] (5) State1's action reads and interprets one or more commands on each entry. (4a)An EOF reports a missing "SP" command, sets replayState to State2 and returns. (4b) A "SP" command sets replayState to State2 and returns. (4c) A WAIT n command just returns if near_real_time = 0. [If near_real_time = 0, WAIT n sleeps for n msecs before returning. TBD: Verify proper interaction of sleep with X11.]. (4d) Any other command updates the database, then calls GraphSelect to rebuild the graph object list of drawable elements commands, calls ReDraw to repaint the canvas window, and returns without updating the state (bde loops in this state during replay). [RJL031030: The goal is to minimize bde-specific code (application-dependent behavior) in the Keypress state model itself and move the state model code into pr_log.c. (updatedisplaylist and ReDraw are bde-specific and happen on each Keypress iteration, so a bde-specific callback function must be executed in Keypress itself, after it calls replay_log in pr_log.c.) ] (6) State2's action closes the log file and normal bde operation resumes (at least until a subsequent FileOpen finds another "SR" command :-). [12A: You can avoid the FileOpen menu by calling bde with a filename argument. You can avoid the GraphSelection menu: bde opens the first HG by default. [RJL031030: Replay may fail on a multi-diagram file since GraphSelect operations are not yet logged.]