Jump to content
The simFlight Network Forums

Recommended Posts

Posted

I don't think I understand how things work here. In the previous version of our app, we used static classes in a WPF app. Process() was called in the Application class where the rest of the code lived. Now, we are trying to convert it from a procedural based codebase to an object oriented one. In previous posts, I had problems with connections and getting values from offsets. It still happens to be that way, but now with the PMDG aircraft for MSFS. I think it is more with my understanding of things than the FSUIPC connection.

 

* I have a static class as my connection manager class. It connects to MSFS and runs FSUIPCConnection.Process(). Is this global for the entire application, or only the connection manager class?

* Do I have to open the connection and run FSUIPCConnection.Process for each non static class?

* At what point would I call an event after the offset value changes?

 

 

Simple example follows: ConnectionManager.connect() has already been called in the MainWindow, and the connection is verified. FSUIPCConnection.Process() is already running. In a non static class, I have the following:

 

using tfm.Utilities;
using FSUIPC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace tfm.Airplanes
{
   public class PMDG737: Airplane
    {

        private PMDG_737_NGX_Offsets _Offsets = new PMDG_737_NGX_Offsets();
        
        public PMDG737()
        {
            FSUIPCConnection.Process();
            System.Timers.Timer _timer = new()
            {
                Interval = 300,
                AutoReset = true,
            };
            _timer.Elapsed +=  (s, e) =>
            {
                try
                {
                    AudioManager.Output(_Offsets.MAIN_TEFlapsNeedle[0].Value.ToString());
                    FSUIPCConnection.Process();
                    _Offsets.RefreshData();

                }
                catch (FSUIPCException ex)
                {

                }
            };
            _timer.Start();
        }
        
    }
}
 

 

No matter what I try, the value is always 0. Changing the controls in MSFS doesn't give me the right value in this class either. An instance of PMDG737 is created inside a menuitem.click event in the main window, then assigned to a static property in another class. What am I missing?

Posted
34 minutes ago, Andy B. said:

* I have a static class as my connection manager class. It connects to MSFS and runs FSUIPCConnection.Process(). Is this global for the entire application, or only the connection manager class?

The entire application. There is only one connection to FSUIPC and only one pool of offsets. It doesn't matter which class created the offsets; all offsets go into the same application-wide pool. Calling Process() without a group will process every offsets created by your application (by any class) that wasn't assigned to a group. If you want different pools of offsets so you can process them at different times then you need to use the grouping. Note that groups can also be accessed by any class in the application, not just the class that created the group.

Quote

Do I have to open the connection and run FSUIPCConnection.Process for each non static class?

No, you just open it once.

Quote

At what point would I call an event after the offset value changes?

After you call process(). You then check the ValueChanged property or any offsets you want events for. If it has changed you can call an event to notify any other classes that need to know.

 

Looking at your example code:

                   AudioManager.Output(_Offsets.MAIN_TEFlapsNeedle[0].Value.ToString());
                    FSUIPCConnection.Process();
                    _Offsets.RefreshData();

You don't need to call Process() here. That's for the offsets that are not in any group. The PMDG offsets are placed in their own group and processed during RefreshData().

You're getting the value of the MAIN_TEFlapsNeedle offset before you've refreshed the data, so you're always going to be getting the value from the previous RefreshData() not the current one.

catch (FSUIPCException ex)
{

}

It's not a good idea have exceptions just disappear into the void like this, especially during development. If there's an exception it might give you some much needed information about why your application isn't working. You should at least log them in the console during development, even if your app ignores them.

Quote

No matter what I try, the value is always 0. 

Have you confirmed the PMDG offsets are working by using a simple project with no timers, or connection manager classes etc? Just open the connection, create the PMDG offsets class, refresh the data and then try to read something. I keep suggesting this but you've never told me if you've tried it.

Unfortunately it's almost impossible for me to debug your application by looking at single classes. I can't see anything wrong with this class, but I've no idea how it's interacting with everything else in your application.

Paul

Posted
21 minutes ago, Andy B. said:

This still didn't work.

What didn't? You mean the PMDG offsets don't work in a simple testing application? 

Paul

Posted

Hi,

 

Here is what I find with 'testing'.

 

* Offsets work in a simple test app (WPF).

* Offsets work in the previous version of our app.

* In the new design (wpf/dotnet 8.0), offsets work. However, it seems as though they don't receive an initial value until the timer can tick at least once. When the process timer ticks, the initial value doesn't change, so nothing happens. To demonstrate, I will explain what happens.

 

The example is the aircraft title (0x3d00). When the base Aircraft instance is created through inherited classes (the PMDG737/777). The class creates an instance of Offset<string>(0x3d00, 256) and assigns it to a variable _title. In the constructor of base Airplane class, I start a timer that checks for _title.ValueChanged. If it has, perform some logging to track the value. In this example, the _title offset is always empty, so nothing ever happens. Even though process is called elsewhere (connection manager), the offset's initial values are not loaded. On the other hand, calling Process outside a timer while in the constructor seems to load the initial data into the offsets. I'm confused with the entire issue. I am not using DispatcherTimer in any of my non UI classes. Could this be causing the problem?

 

* An instance of Airplane is created.

* Start a process timer.

* In the timer event, check for changes to the title offset.

* Do an action if it changes.

* The title offset is empty because it never arrives at its MSFS provided value.

 

 

 

Posted

 >> Offsets work in a simple test app (WPF).

Great, thanks for checking that.

If you want to PM me the whole project (or a link so I can clone it from github/bitbucket if you're using either) I'll take a look and see if I can see what's going on.

Paul

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.