Jump to content
The simFlight Network Forums

ipc.reloadWASM() Question


ark1320

Recommended Posts

In XML the first use of an Lvar "creates" it if it does not exist which can be very useful.  In the little test example below, the Lvar (L:AE_FD, Bool) is created by the Lua script -- i.e., it does not exist prior to the script running.  In the third line I try to update the value of (L:AE_FD, Bool) but this does not work and the if statement fails (if I display fd_val it shows as 0). However, if after running the script I open FSUIPC and List the Lvars (without first doing a manual reload,)  the Lvar AE_FD is listed with a value of 1.  So I don't understand why the if statement failed.  If I leave out the ipc.reloadWASM() command the script also does not work. So I assume I don't understand how the ipc.reloadWASM() command works.

Ideas anyone?

Thanks,

Al

 

ipc.execCalcCode("  0  (>L:AE_FD, Bool) ")         -- create Lvar
ipc.reloadWASM()                                             -- make Lvar known
ipc.execCalcCode("  1  (>L:AE_FD, Bool) ")         -- update Lvar
fd_val = ipc.readLvar("L:AE_FD")
if fd_val == 1 then
   ipc.control(66288)                                           -- toggle FD
end

Link to comment
Share on other sites

The problem is here:

Quote

ipc.execCalcCode("  1  (>L:AE_FD, Bool) ")         -- update Lvar
fd_val = ipc.readLvar("L:AE_FD")

The lvar will be updated, but if you read the lvar directly after the update, you will be reading the old value as the new value will not yet have been received back from the WASM.
The lvar gets updated in the FS, but lvar value updates are only sent back to FSUIPC7 6 times per second (by default, can be changed via a WASM ini parameter). So you would need to wait for a short period after updating an lvar before reading, i,e,

    ipc.execCalcCode("  1  (>L:AE_FD, Bool) ")         -- update Lvar
    ipc.sleep(200) -- wait for lvar update to be received

    fd_val = ipc.readLvar("L:AE_FD")

10 hours ago, ark1320 said:

In XML the first use of an Lvar "creates" it if it does not exist which can be very useful. 

Maybe, but better to use the provided function to create the lvar, and then the new lvar will automatically be pushed to any WASM/WAPI client. So, try:

ipc.createLvar("AE_FD", 0)                                  -- create Lvar
while (ipc.getLvarId("AE_FD") == nil)  do ipc.sleep(50) end -- wait for lvar to be received
ipc.execCalcCode("1 (>L:AE_FD, Bool)")                      -- update Lvar
ipc.sleep(200)                                              -- wait for updated value to be received
fd_val = ipc.readLvar("L:AE_FD")
if fd_val == 1 then
   ipc.control(66288)                                       -- toggle FD
end

John
 

Link to comment
Share on other sites

By the way, you also don't actually need to reload the WASM if using calculator code to update the lvar. You only need to do this if using the specific ipc lvar functions. Calculator code will be executed regardless of  whether the lvars are known to FSUIPC or not. So your example could also be re-written as follows:

ipc.execCalcCode("  0  (>L:AE_FD, Bool) ")         -- create Lvar
ipc.execCalcCode("  1  (>L:AE_FD, Bool) ")         -- update Lvar
ipc.reloadWASM()                                   -- make Lvar known
ipc.sleep(200)                                     -- wait for updated lvar list to be received:
                                                   --   can also use while loop and wait for the lvarId to be none-nil
fd_val = ipc.readLvar("L:AE_FD")
if fd_val == 1 then
   ipc.control(66288)                              -- toggle FD
end

John

Link to comment
Share on other sites

2 hours ago, John Dowson said:

By the way, you also don't actually need to reload the WASM if using calculator code to update the lvar. You only need to do this if using the specific ipc lvar functions.

So if I update an Lvar using calculator code, and subsequently only use that Lvar in more calculator code, I don't need to reload WASM.  But if subsequently I will use that updated Lvar in some type of ipc command, I do first need to reload the WASM followed by a suitable delay like 200ms. And this is true whether or not the Lvar was previously  "created" by the code or already existed in the sim code. So the sequence reload WASM followed by a delay may be needed a number of times throughout a Lua script if the Lvar is repeatedly updated in calculator code and then used with ipc commands.

I think I got it.

Thank you very much for the explanations and developing this capability to execute XML within a Lua script.

Al

Link to comment
Share on other sites

25 minutes ago, ark1320 said:

So if I update an Lvar using calculator code, and subsequently only use that Lvar in more calculator code, I don't need to reload WASM.  But if subsequently I will use that updated Lvar in some type of ipc command, I do first need to reload the WASM followed by a suitable delay like 200ms. And this is true whether or not the Lvar was previously  "created" by the code or already existed in the sim code. So the sequence reload WASM followed by a delay may be needed a number of times throughout a Lua script if the Lvar is repeatedly updated in calculator code and then used with ipc commands.

Yes, that is correct. This is because it is a client-server request. The requests are sent to the server and the direct response is 'request sent ok' (hopefully), then the actual update/changes are received once the server has processed the request and any response has been received in the client (FSUIPC7) from the server (MSFS) - and in another thread.

27 minutes ago, ark1320 said:

Thank you very much for the explanations and developing this capability to execute XML within a Lua script.

No problem - a necessary feature with MSFS really....

Cheers,

John

Link to comment
Share on other sites

I did a little more testing. In summary in case others are interested, my understanding is:

If an Lvar is created using ipc.createLvar(), the reload WASM command is not needed.

If an Lvar is created with calculator code you need to reload WASM, but only once for that Lvar within that Lua script. I suppose once FSUIPC "knows" about that Lvar, it knows for the whole script. Follow the WASM reload with a 200MS delay.

If an Lvar is updated with calculator code, that needs to be followed by a delay of about * 200ms (something greater than 166ms) if that Lvar will subsequently be used in an ipc command.

Lvars used only within calculator code commands, or only within calculator presets (I assume), do not need either WASM reloads or 200ms delays.

Thanks again,

Al

* EDIT: See posts below for delay time options.

 

Link to comment
Share on other sites

Yes, that is all correct. However, the times/delays you see are because you are using the default lvar refresh rate of 6Hz. You can speed things up by changing this to VisualFrame or Frame, using the WASM ini parameter LvarUpdateFrequency. See the Advanced User guide (WASM section) for details.

John

Link to comment
Share on other sites

8 hours ago, John Dowson said:

Yes, that is all correct. However, the times/delays you see are because you are using the default lvar refresh rate of 6Hz. You can speed things up by changing this to VisualFrame or Frame, using the WASM ini parameter LvarUpdateFrequency. See the Advanced User guide (WASM section) for details.

John

What are the definitions of Frame and VisualFrame?  I ran some experiments with the little test program above. Could not get consistent results, however, perhaps other issues such as the loading time of the script, etc played a role.

Does Frame refer to the basic rate at which the sim is running-- maybe around 18Hz (55ms), at least that was what P3D ran at I believe. Or does Frame refer to the FPS you happen to be getting at that time?

Does VisualFrame relate to the refresh rate of your monitor, or maybe that is what is related to the FPS?

My sim FPS is locked at 30Hz (33.3ms).

Btw, I assume whatever delay is needed, it is also needed after the ipc.createLvar() command before the value being set by that command is available -- true?

 Thx,

Al

Link to comment
Share on other sites

18 hours ago, ark1320 said:

What are the definitions of Frame and VisualFrame?  I ran some experiments with the little test program above. Could not get consistent results, however, perhaps other issues such as the loading time of the script, etc played a role.

Does Frame refer to the basic rate at which the sim is running-- maybe around 18Hz (55ms), at least that was what P3D ran at I believe. Or does Frame refer to the FPS you happen to be getting at that time?

Does VisualFrame relate to the refresh rate of your monitor, or maybe that is what is related to the FPS?

These are periods defined by the MSFS SIMCONNECT_PERIOD enumeration type:

Quote
Members
Member Description
SIMCONNECT_PERIOD_NEVER Specifies that the data is not to be sent.
SIMCONNECT_PERIOD_ONCE Specifies that the data should be sent once only. Note that this is not an efficient way of receiving data frequently, use one of the other periods if there is a regular frequency to the data request.
SIMCONNECT_PERIOD_VISUAL_FRAME Specifies that the data should be sent every visual (rendered) frame.
SIMCONNECT_PERIOD_SIM_FRAME Specifies that the data should be sent every simulated frame, whether that frame is rendered or not.
SIMCONNECT_PERIOD_SECOND Specifies that the data should be sent once every second.

 

Remarks

Although the period definitions are specific, data is always transmitted at the end of a frame, so even if you have specified that data should be sent every second, the data will actually be transmitted at the end of the frame that comes on or after one second has elapsed.

I know nothing more than that.

18 hours ago, ark1320 said:

Btw, I assume whatever delay is needed, it is also needed after the ipc.createLvar() command before the value being set by that command is available -- true?

Yes, you will need a delay, before you can read the value. However, as I said, rather than inserting a delay you should use the idiom:

ipc.createLvar("AE_FD", 0)                                  -- create Lvar
while (ipc.getLvarId("AE_FD") == nil)  do ipc.sleep(50) end -- wait for lvar to be received

i.e. wait for the lvar to be available after creation.

It is also better to use the event.Lvar function to perform actions when lvar values change rather that changing the value and then waiting for the updated value to be received back - or you could just assume that the value had been updated (depending in the use-case).

John

 

  • Upvote 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.