D3 – Recompiling Code

The following is some great information posted to the Raining Data web forum by Robert Burke, their new Technical Support Director. I’ve posted it here verbatim for your benefit.

There are going to be cases where you want to change and recompile a flashed program and run the new program even though another process is still running the old object. There are 2 tools in D3/NT to accomodate this and although they do not cover all instances, they do help somewhat.

The first is the case where you are changing and recompiling a subroutine that is called from a trigger. Once it has been called, the trigger object code is loaded in shared flash memory and has the distinct property of having run on it’s own port. It is not unloaded until the port is logged off which happens when the original process logs off. Very inconvenient when you are testing! You can set the registry setting "LoadTriggerOnOpen" to 1 so that every time the trigger is called, it will load the latest object into memory.

The second case is when you are doing what Tony refers to, developing and compiling programs while the main program is running. There is a verb called nt_inv-flash which will set the invalid flag on flashed object code in shared flash memory so that the next time it is called, it will be reloaded as a new valid program.

Here is a little more information about that registry entry that Robert noted:

The following is quoted from the topic on triggers in the D3 Ref Manual v7.5 – this "new material" was really just copied from prior versions of the D3NT Books OnLine, so it should apply to all D3NT releases:

By default, when the FlashBASIC code for a trigger is recompiled, it is not immediately used by the application. All files using the trigger must be closed for the new copy of the code to be taken into account. Two registry setting can change this behavior. Change the following value:

  • HKEY_LOCAL_MACHINE\Software\RainingData\
    D3\CurrentVersion\D3Fsi\LoadTriggerOnOpen
  • HKEY_LOCAL_MACHINE\Software\RainingData\
    D3\CurrentVersion\D3Fsi\ObjectReuseProt

Set the value to 0 to have the default behavior (all files must be closed and D3 must be shutdown and rebooted) or to 1 (do not need to shutdown and reboot D3) to have the following features:

  • The new code is picked up when the file is reopened by a user. All users of the same file then use the new version of the trigger immediately, even if they do not log off.
  • If the trigger is used in another file, the users see the change the next time the other file is re-opened.
  • Obsolete versions show a usage of 0 (in the D3 File Manager, Tools > Flash Shared Code) and are destroyed when all users log off.

NOTE- Recompiling a trigger many times while the file is in use can lead to many obsolete copies of the code in the FlashBASIC code section. There is no limit to the size of this section, and as it grows larger, it may consume swap space.

Regarding that information above, it’s my experience that with the default settings D3 does not need to be shutdown in order for object to be removed from cache, but in my development environment I do need to either logoff, or exit and reconnect in order for old object to flush itself out. I honestly haven’t played with this stuff too much (I’ve tended to avoid triggers in the past) so I’m not sure exactly what is required or, as above, just what’s suggested.

The program nt_inv-flash is documented as follows:

The nt_inv-flash command removes a flashed program object in cache and loads the new flash program object.
Syntax: nt_inv-flash file.reference item.name {(options}
option q Suppresses all terminal output.

If you have any interest in seeing what that command does, the source for nt_inv-flash is provided in dm,bp,.

So now we have another solution for those of you who have products that compile code from outside of D3 – and you know who you are.

Let me know if you need assistance implementing the information provided here.

Leave a Reply