Neil Hewitt Posted April 3, 2021 Report Posted April 3, 2021 Hi Paul. Is reading / writing an LVAR a particularly performance-intensive operation? Would reading one or more LVAR values regularly (ie as often per second as possible) be a costly process? The reason I ask is that I'm writing a small utility to monitor the values of specific LVARs and then, if they change, trigger an event that I can subscribe to so that I can send a message to a client program on another PC to set the value of the same LVAR on another instance of P3D. What I've noticed is that if I have a thread constantly polling the values, it does seem to have an impact on FPS in-sim (not huge, but visible) and more particularly, if I start reading (or trying to read) LVAR values while the sim is starting (currently my utility connects and starts polling as soon as FSUIPC is available and a connection opens), it seems to stop the sim from actually getting to the scenario screen, almost as if somehow calling FSUIPC continuously is blocking the main thread. If I close my utility down and stop the polling, the sim will then finish starting within about 2 seconds, so it's clearly being blocked. I can't see any way programmatically to find out when the sim has 'properly' started vs when FSUIPC starts accepting connections. Are you aware of an offset, perhaps, that changes once the sim has started? I want this utility to be able to start at PC start-up, remain resident in the systray, and connect and disconnect across multiple P3D sessions if need be. So I do need to be able to run while the sim is starting. Unless I can find a signal to start/stop polling for LVAR values at the right times (other than just 'can I connect to FSUIPC?'), I'm having a hard time seeing how I can make this work.
Paul Henty Posted April 3, 2021 Report Posted April 3, 2021 Quote Is reading / writing an LVAR a particularly performance-intensive operation? Compared to reading offsets, yes. Every LVAR read or write takes one Process() call. Usually around of 10ms. Whereas you can read many offsets in a single process call. Quote Would reading one or more LVAR values regularly (ie as often per second as possible) be a costly process? There's no problem with a few LVARs per second. Depending on the PC, and what else is running using SimConnect/FSUIPC, I would think you can easily read about 50 per second without problems or running out of time. Quote almost as if somehow calling FSUIPC continuously is blocking the main thread. That's strange. I don't have P3D so I can't test that here. I might be worth asking the John Dowson about this in the main support forum. Quote Are you aware of an offset, perhaps, that changes once the sim has started? Yes there are two offsets you can look at: 0x3364: Ready to Fly. (1 Byte). Look for it to be Zero when the sim has finished loading and the flight has started. 0x3365: In Menu or Dialog. (1 byte). Again, look for this to Zero when not in a menu. These offsets work a little differently in each type of sim (FSX/P3D etc.) so you might need to experiment a bit. Paul
Neil Hewitt Posted April 4, 2021 Author Report Posted April 4, 2021 On 4/3/2021 at 4:00 PM, Paul Henty said: Quote Is reading / writing an LVAR a particularly performance-intensive operation? Compared to reading offsets, yes. Every LVAR read or write takes one Process() call. Usually around of 10ms. Whereas you can read many offsets in a single process call. Is that just an inherent limitation of FSUIPC, or is it the sim itself? SPAD.neXt seems to be faster - I did look at the LVAR bridge that ships with it to see if I could use it, but it's a private library and it's not documented, so while I might be able to bind to the entry points I wouldn't know what I was doing. Plus... COM interop 😞. Going via FSUPIC via your library has a much lower barrier to entry for someone who hasn't used anything other than C# for probably 20 years. 500ms (50 x 10ms) is not the end of the world, though. In fact, for my purposes, I could probably get away with polling at longer intervals to reduce any FPS impact. I need the LVAR sync to be quick but not instant. And I only need about 20 LVARs for my current purpose. But this will be a programmable system that I might make available to the community more generally, so I can't vouch for every use case. But the faster it is, the better. I've got a prototype working now and it's fine so far, bar the issue I mentioned. But I can use the Ready to Fly offset to fix that. Fun for tomorrow! Really enjoying using the library so far. I like the ambient context approach of just using static classes to handle the communication.
Paul Henty Posted April 5, 2021 Report Posted April 5, 2021 Hi Neil, Quote Is that just an inherent limitation of FSUIPC, or is it the sim itself? It's FSUIPC unfortunately. The LVAR support only has a single offset where you can request an LVAR (0x0D70), so that's where the limitation comes from. Internally, FSUIPC6 and previous versions, call into the Flight Sim Panels dll which would be very fast at getting and setting LVARs. I suspect SPAD is doing the same thing. C++ programmers can use this tequnique via SimConnect, but it doubt it can be done from managed code. Sticking with FSUIPC6 and previous, it's possible to read/write LVARs values in LUA plugins. This would be fast as this doesn't need to go through the IPC (offsets) interface. The LUA plugin would then copy the values into user offsets and then your program would read the values from the offsets. For large numbers of LVARs this would be much faster. BUT there are some disadvantages to this method: You or your users would need to maintain the LUA plugin LUA Plugins only work on the registered version of FSUIPC In FSUIPC7 (MSFS 2020) things are slightly different. John has written a plugin for MSFS that allows users to read/write LVARS outside of FSUIPC. At the moment though it's only available to C++ users. I'm hoping John and I can get it working from managed code but there's no guarantee at the moment. Paul 1
Neil Hewitt Posted April 10, 2021 Author Report Posted April 10, 2021 I've got it syncing about 30 LVARs now and it's performing fine... in fact, the 'P3D stuck on startup' issue I mentioned has gone away since I tidied up my thread handling a bit (Web devs should really not try their hands at concurrent programming). The app is working out quite well. I've got conditions being evaluated as C# scripts which lets me do complex conditionals (ie only set an LVAR value if the conditions are met) and I'm adding support for offsets as well. Since offsets can be backed by a wide range of values and types, that got very complex very quickly, so I'm only supporting 2/4/8 byte integers, 4/8 byte floating point, strings, and everything else is a byte array. This may evolve into a wider 'sim sync' program; given that offsets can be read and written very quickly, it's practical to sync up various sim parameters that, for example, Wideview doesn't do. I shall see where the rabbit hole goes 🙂 Anyway, thanks for your help, and for your DLL, without which (and FSUIPC itself, of course) I would have got precisely nowhere since I loathe SimConnect with a passion I can barely put into words!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now