guides:programming:programmers_reference_manual:rti_resolve_select_callback_function

Rti_resolve_select_callback

A system routine which displays progress messages during selects and reports. It is called from within RLIST, RESOLVE_SELECT, EXTERNAL.SORT, RTI_RLISTX_PRODUCE. You can register on or more of your own routines as a listener. Registered listeners will receive notification of progress and completion. A registered listener can cancel a long running select.

rti_resolve_Select_callback(method, cursor, p1,p2,p3,p4)

rti_resolve_Select_callback has the following parameters.

ParameterDescription
methodThe name of the table that contains the row or rows to be copied.
cursorThe select cursor number (0-8). See Select by . Defaults to 0
p1…p4 depends on the method, see method decriptions below

rti_resolve_Select_callback has the following methods.

ParameterDescription
rtirsc_start$ called at the beginning of a process
rtirsc_progress$ called periodically ( every couple of seconds ) while a select running
rtirsc_complete$ called when the select completes
rtirsc_cancel$ called if the select is cancelled
rtirsc_error$ called when there is an error
rtirsc_register_listener$ add a name to the list of registered listeners
rtirsc_unregister_listener$ remove a name from the list of registered listeners
rtirsc_getContinue$ get the value of the continue flag
rtirsc_SetContinue$ set the continue flag. pass false in P1 to stop the current select
rtirsc_IncrementCount$ increment the progress counter
rtirsc_setDisplayHandler$ provide the name of a routine to display progress
rtirsc_getDisplayHandler$ get the name of a routine which displays progress
rtirsc_EnableGui$ Turn on gui progress messages
rtirsc_DisableGui$Turn off gui progress messages
rtirsc_getGuiEnabled$ return true if gui is enabled

A sample of a custom callback routine

/*
**  Example of adding a select callback listener
*/

     #pragma format_indent_comments

     Declare Function retStack,IsEventContext

     $Insert logical
     $Insert rti_resolve_Select_callback_equates
     $Insert RTI_SEND_INFO_PROGRESS_EQUATES

     $Insert rti_resolve_Select_callback_Common

     Equ ancestor_Proc$ To "RTI_RESOLVE_SELECT_CALLBACK"

     common /test_Select_callback_com/callCount@
     
     * Count how many times called
     callCount@ += 1
     
     * The name of the program which called rti_resolve_select_callback
     caller = retstack()<3>
     
     If Assigned(method) Else method = ""
     retval = null$
     atProc = retstack()<1>

     * I only care about progress and completion for this example
     supported_methods = rtirsc_progress$ : @fm : rtirsc_complete$
     Locate method In supported_methods Using @fm Setting pos then
          On pos Gosub onProgress,onComplete
     End

Return retval
///////////////////////////

onProgress:

     progress_Count = If Assigned(p4) Then p4 Else null$

     * Pass somthing around?
     If Assigned(p4) Else p4 = null$
     myCustominfo = p4
     
     * For this example, count how many times called.
     
     
      * For this example, just write to a log
     Call rti_logit('', 'Progress', 'Called ' :callCount@ : ' times ' : myCustomInfo : ' Caller ' : caller)

Return
///////////////////////////

onComplete:
      progress_Count = If Assigned(p4) Then p4 Else null$
      If Assigned(p4) Else p4 = null$
       myCustominfo = p4
      Call rti_logit('', 'Completed', 'Called ' :callCount@ : ' times ' : myCustomInfo: ' Caller ' : caller)

     If isEventContext() then
          Call Msg(@Window, 'Called ' : callCount@ : ' times')
     End
     
     callCount@ = 0
Return
///////////////////////////

A BASIC+ Program which calls the above custom routine

Subroutine test_select_callback_harness(void)
/*
*  An example of using a custom callback routine for RTI_RESOLVE_SELECT_CALLBACK 
*/

     #pragma format_indent_Comments
     Declare Function get.reccount

     $Insert logical
     $Insert rlist_equates
     $insert select.constants
     $insert fserrors_hdr
     $Insert fserrors_100
     $Insert msg_equates
     
     * See this equate for the rti_resolve_Select_callback methods
     $Insert rti_resolve_Select_callback_equates 

     * Register my custom routine with rti_Resolve_select_callback
     * Note that it accepts a cursor number to support use of different cursors for sub selects ( see SELECT BY / READNEXT BY )
     cursor = 0
     myRoutine = "TEST_SELECT_CALLBACK"
     unused = rti_resolve_select_Callback(rtirsc_register_listener$, cursor, myRoutine)
     
       *
     * Initialize the progress info for this process
     *
     continue = rti_resolve_Select_callback(rtirsc_start$, cursor,0, '','','')


     
     * Turn system progress dialog on or off as you desire.
     * By default they are off
     * If your routine has its own gui then turn off system progress dialogs here so that the selects will show MY progress, if desired
     * unused = rti_resolve_select_Callback(rtirsc_disableGui$, cursor)

     * In my case, I want to use the system gui
     cursor = 0
     unused = rti_resolve_select_Callback(rtirsc_enableGui$, cursor)

     table = 'PERSON'
     statement = 'SELECT PERSON WITH CITY STARTING "NEW"'

     * For this example I want to open the table
     * So I can process the records
     Open Table To f_table Else return
     Open 'DICT.':table To @dict Else return

     * Could call rlist or REDUCE, SELECT BY
     Call Rlist(statement , target_activelist$)

     * To estimate the pct complete, use @reccount, or assume entire table
     expected_count = 0
     If @list.active ==  EXTRN.Select$ Then
          expected_Count = @reccount
     End Else
          stat = null$
          expected_Count = Get.RecCount(f_table, stat, 0)
     end

     * I can pass custom information to my callback routine.
     * I think you can roundtrip this, if you want the callback to send information back
     myCustomInfo = "Hello World " :Time()
     
   
     *---
     * Process the records
     *---
     
     * I this example I load some data into a buffer named 'sb'
     sb = null$;sballoc_Size = 0x7FFF;sbPos = 1
     
     rnDone = false$
     readcount = 0

     Loop
     until rnDone Or Not(continue)
          readnext @id using cursor by AT Then
               Read @record From f_table, @id then
                    readcount += 1
                    line = @id:@vm:{CITY}:@vm:{LNAME}:@vm:{FNAME}:@fm

                    * Does it fit?
                    If getbytesize(line) + sbpos gt Blen(sb) Then
                         sb := str(\00\,sballoc_size)
                    End

                    * Add it to buffer
                    putbinaryValue( sb, sbpos,CHAR, line)
                    sbpos += getbytesize(line)

                    * Yield every couple seconds, show some progress
                    * The custom callback routine can cancel the operation if desired
                    If Mod(readcount, 100) Eq 1 Then
                         myCustomInfo = 'Currently processing ' : @id
                         
                         * Update progress, test for continue
                         continue = rti_resolve_select_callback(rtirsc_progress$, cursor,readcount,'', '', myCustomInfo)                         
                         If Not(continue) Then
                              * Discard results, end the loop
                              sb = ''; sbpos = 1
                              rndone = true$
                         End
                    End
               end
          End Else

               * Readnext error
               * normally this is readnext_done$, not a problem )
               rnDone = TRUE$
               if @file_error<FSCODE$> == FS_READNEXT_DONE$ Then
                   * We may not have displayed progress for the last chunk of records
                   * To make user happy, show 100%
                   myCustomInfo = '100% progress'
                   unused = rti_resolve_select_callback(rtirsc_progress$, cursor,expected_Count,'', '', myCustomInfo)
               End Else
                   * Some kind of error
                    ClearSelect cursor
                    sb = ''; sbpos = 1
               End
          End
     Repeat
     
     * Call the complete method to take down any gui display
     myCustomInfo = 'Read count = ' : readcount
     unused = rti_resolve_Select_callback(rtirsc_complete$, cursor ,'', '', '', myCustomInfo)

     * Turn off system progress dialogs here, or subsequent select will display the gui
     cursor = 0
     unused = rti_resolve_select_Callback(rtirsc_disableGui$, cursor)

     * Unregister my progress callback or susequent selects will call it
     unused = rti_resolve_select_Callback(rtirsc_unregister_listener$, cursor, myRoutine)

     * For this example, extract result from the buffer and return it
     If sbpos gt 1 Then
          sbpos -= 1 ; * kill trailing @fm
          result = getBinaryValue(sb,1,CHAR,sbpos-1)
     End Else
          result = null$
     End
Return result
//////////////////
  • guides/programming/programmers_reference_manual/rti_resolve_select_callback_function.txt
  • Last modified: 2025/01/31 22:01
  • by rcarten