Monthly Archives: August 2013

Promoted Events and the Repository

One of the most powerful programming features of OpenInsight is the “Promoted Event” model, allowing you to write “global” event handing code that can be triggered for a variety of situations, such as for all objects of a certain type, or for all objects in an application, and so on.  This helps to centralize your code-base and restrict unnecessary duplication, thereby making development faster and more robust.

However, promoted events have also been one of the most opaque parts of the system and  their use is somewhat awkward and error-prone because they rely on the dark art of naming conventions and manual record copying between tables.  In an effort to rectify this we’ve integrated them into the OpenInsight Repository so they can be tracked properly and you can see at a glance exactly what is in your system.  

Promoted events fall into one of 5 generic categories:

 Category                         Example SYSREPOSEVENTS key
 ========                         ==========================
 1) EVENT/CLASS/TYPE specific  -> SYSPROG*ACTIVATED.WINDOW.OIWIN*
 2) EVENT/TYPE specific        -> SYSPROG*ACTIVATED..OIWIN*
 3) TYPE specific              -> SYSPROG*..OIWIN*
 4) EVENT/CLASS specific       -> SYSPROG*ACTIVATED.WINDOW*
 5) EVENT specific             -> SYSPROG*ACTIVATED*

So to enable their integration we’ve added three new entity types:

  • PROMOTEDEVENT (source code)
  • PROMOTEDEVENTDBG (debugger symbol table)
  • PROMOTEDEVENTEXE (object code)

Each of these types has a Repository key structure that derives from the actual promoted event key itself like so:

 SYSREPOSEVENTS key                 Repository key 
 ==================                 ==============
 SYSPROG*ACTIVATED.WINDOW.OIWIN* -> SYSPROG*PROMOTEDEVENT*ACTIVATED*WINDOW.OIWIN
 SYSPROG*ACTIVATED..OIWIN*       -> SYSPROG*PROMOTEDEVENT*ACTIVATED*_.OIWIN
 SYSPROG*..OIWIN*                -> SYSPROG*PROMOTEDEVENT*_*.OIWIN
 SYSPROG*ACTIVATED.WINDOW*       -> SYSPROG*PROMOTEDEVENT*ACTIVATED*WINDOW
 SYSPROG*ACTIVATED*              -> SYSPROG*PROMOTEDEVENT*ACTIVATED*_

Some of you may look twice at the use of the “_” character for the CLASSID and ENTID Repository key parts:  This is actually used as a placeholder to denote a null part in the promoted event key itself – their use is necessary because the Repository reacts poorly to a null CLASSID or ENTID.

We’ve also added a new stored procedure called SYNCH_REPOS_PROMOTED_EVENTS which can scan your SYSREPOSEVENTS and SYSREPOSEVENTEXES tables to create any missing  entities so it’s easy to bring your existing promoted events into the Repository,

Of course integration with the Repository isn’t the end of the story – now that promoted events are recognized as first-class citizens we need to provide the tools in the IDE to create and maintain them… but that’s a story for another time…

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

The FILESYSTEM WATCHDIR method

We’ve already taken a look at the new FILESYSTEM object in a previous post, but this time we’re going to focus on a new method we’ve added called WATCHDIR.

This method allows you to monitor the contents of one or more directories on the system and be notified of any changes occurring within them.  It’s API is quite simple and takes up-to three arguments:

  1. The name of the directory to watch (required).
  2. A optional boolean flag denoting if you wish to include sub-directories. (defaults to FALSE$).
  3. An optional set of bit-flags detailing the kind of changes you are interested in.  By default WATCHDIR notifies you of file creation, changes to the name, and changes to the “Last-Write” time.

Example:

$insert msWin_FileNotify_Equates

// Only watch for files being created in the specified dir ...
watchFlags      = FILE_NOTIFY_CHANGE_CREATION$
bIncludeSubDirs = FALSE$
call exec_Method( "FILESYSTEM", "WATCHDIR", "c:\temp\incoming", |
                  bIncludeSubDirs, watchFlags )

When a change occurs the FILESYSTEM object raises a CHANGED event to notify you of the fact,  As with any other OI window or control you can write your own FILESYSTEM CHANGED event handler to respond to this – note that this event is per application, not per window.

Like the standard CHANGED event the relevant change information is passed in the “NewData” argument – in this case “NewData” contains a dynamic array with two fields:

<1> The name and path of the file being changed
<2> A code specifying the type of change

Example FILESYSTEM CHANGED event:

$insert msWin_FileNotify_Equates

changeFile = newData<1>
changeCode = newData<2>

info = ""

begin case
   case ( changeCode = FILE_ACTION_ADDED$ )
      info = "Added"
   case ( changeCode = FILE_ACTION_REMOVED$ )
      info = "Deleted"
   case ( changeCode = FILE_ACTION_MODIFIED$ )
      info = "Modified"
   case ( changeCode = FILE_ACTION_RENAMED_OLD_NAME$ )
      info = "Renamed From"
   case ( changeCode = FILE_ACTION_RENAMED_NEW_NAME$ )
      info = "Renamed To"
end case

call send_Info( info : " " : changeFile )

Technical note: The WATCHDIR method is based on the underlying ReadDirectoryChangesW Windows API function, details of which can be found here.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).

The IDLEPROC Queue

One of the new features added to the SYSTEM object is the “IDLEPROC queue”.  This is an enhancement to the existing IDLEPROC property as it allows you to queue multiple requests via the new SYSTEM ADDIDLEPROC method like so:

* // Run a process in the future 
procID   = "RUN_SOME_PROCESS"
procArg  = "42"
procTime = "12:00:00"  ; * // midday
procDate = oconv( date() + 1, "D4/" ) ; * // tommorrow

call exec_Method( "SYSTEM", "ADDIDLEPROC", procID, procArg, procTime, procDate )

* // Run a process ASAP...
procID = "RUN_SOME_OTHER_PROCESS"
procArg = "X43"
procTime = "" ; * // ASAP
procDate = "" ; * // ASAP

call exec_Method( "SYSTEM", "ADDIDLEPROC", procID, procArg, procTime, procDate )

The contents of the queue can be examined via the new SYSTEM IDLEPROCQUEUE property:

ipQ    = get_Property( "SYSTEM", "IDLEPROCQUEUE" )
xCount = fieldCount ( ipQ, @fm ) 
for x = 1 to xCount
   ip       = ipQ<x>
   procID   = ipQ<0,1>
   procArg  = ipQ<0,2>
   procTime = ipQ<0,3>
   procDate = ipQ<0,4>
next

The normal IDLEPROC property works just as it always has done with the following caveats:

  • Setting the IDLEPROC property will replace the entire contents of the queue (so you can use this to clear the queue if you wish).
  • Getting the IDLEPROC property will only return the first item in the queue if there are multiple items.

(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).