Question MFD: How to link to oapi::Module properly?

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,667
Reaction score
3
Points
38
I'm doing some work on Glideslope 2, and I would like to update the opcPreStep to use oapi::Module::clbkPreStep instead. I am looking for a generic how-to on how this is meant to work.

Current implementation code snippet for ... opcDLLInit, opsDLLExit, opcPreStep, opcDeleteVessel, MsgProc:

Code:
DLLCLBK void opcDLLInit (HINSTANCE hDLL) {
  static char *name = "Glideslope 2";   // MFD mode name .. enhancing the original awesome Glideslope into Glideslope 2
  MFDMODESPEC spec;
  spec.name = name;
  spec.key = OAPI_KEY_W;                // MFD mode selection key
  spec.msgproc = Glideslope::MsgProc;  // MFD mode callback function

  // Register the new MFD mode with Orbiter
  g_MFDmode = oapiRegisterMFDMode (spec);
  nGutsUsed=0;
}

DLLCLBK void opcDLLExit (HINSTANCE hDLL) {
  // Unregister the custom MFD mode when the module is unloaded
  oapiUnregisterMFDMode (g_MFDmode);
}


DLLCLBK void opcPreStep(double SimT,double SimDT,double mjd) {
  for(int i=0;i<nGutsUsed;i++) {
    if(GCoreData[i]->isInit)GCoreData[i]->MinorCycle(SimT);
  }
}

DLLCLBK void opcDeleteVessel (OBJHANDLE hVessel) {
  for(int i=0;i<nGutsUsed;i++) {
    if (GCoreVessel[i]==hVessel) {
      delete GCoreData[i];
      for (int j=i; j<nGutsUsed-1; j++) {
        GCoreVessel[j] = GCoreVessel[j+1];
        GCoreData[j] = GCoreData[j+1];
      }
      nGutsUsed--;
      break;
    }
  }
}
int Glideslope::MsgProc (UINT msg, UINT mfd, WPARAM wparam, LPARAM lparam) {
  switch (msg) {

  case OAPI_MSG_MFD_OPENED:
    // Our new MFD mode has been selected, so we create the MFD and
    // return a pointer to it.
    return (int)(new Glideslope (LOWORD(wparam), HIWORD(wparam), (VESSEL*)lparam, mfd));
  }
  return 0;
}


The Glideslope MFD is the ephemeral class that gets destroyed as usual - e.g. on an F8 press. There's a GlideslopeCore instantiated one per vessel, which the opcPreStep() calls. And things work pretty much as you'd expect.

OK - so I figured that I would have a single generic class instantiated from opcDLLInit - say like this:

Code:
header:

class GlideslopeModule : public oapi::Module {
public:
  GlideslopeModule(HINSTANCE hDLL);
  ~GlideslopeModule();
  void clbkSimulationStart(RenderMode mode);
  void clbkSimulationEnd();
};

and code:

//
// ==============================================================
// Orbiter oapi::Module  API interface
// ==============================================================
//
//
GlideslopeModule::GlideslopeModule(HINSTANCE hDLL) : oapi::Module( hDLL ) {
  return;
}
GlideslopeModule::~GlideslopeModule() {
  return;
};
void GlideslopeModule::clbkSimulationStart(RenderMode mode) {
  return;
};
void GlideslopeModule::clbkSimulationEnd() {
  return;
}

.. and then Orbiter would call these callbacks (plus then add more clbk's), and I could remove the opcPreStep deprecated function. Only ... these don't get called, regardless of whether the opcPreStep is also commented out.

So ... what am I doing wrong? Should the oapi::Module inheritance be on the ephemeral MFD class, or the persistent Vessel core class, or as a single root instance linked to the opcDLLInit?

In the meantime ... I'll revert to the old deprecated way.
 

Enjo

Mostly harmless
Addon Developer
Tutorial Publisher
Donator
Joined
Nov 25, 2007
Messages
1,665
Reaction score
13
Points
38
Location
Germany
Website
www.enderspace.de
Preferred Pronouns
Can't you smell my T levels?
Try this:

Code:
header:

class GlideslopeModule : public oapi::Module {
public:
  GlideslopeModule(HINSTANCE hDLL);
  ~GlideslopeModule();
  void clbkSimulationStart(RenderMode mode);
  void clbkSimulationEnd();
 [COLOR=#B00040]void[/COLOR] [COLOR=#0000FF]clbkPreStep[/COLOR] ([COLOR=#B00040]double[/COLOR] simt, [COLOR=#B00040]double[/COLOR] simdt, [COLOR=#B00040]double[/COLOR] mjd);
    [COLOR=#B00040]void[/COLOR] [COLOR=#0000FF]clbkPostStep[/COLOR] ([COLOR=#B00040]double[/COLOR] simt, [COLOR=#B00040]double[/COLOR] simdt, [COLOR=#B00040]double[/COLOR] mjd);

};

and code:

//
// ==============================================================
// Orbiter oapi::Module  API interface
// ==============================================================
//
//
GlideslopeModule::GlideslopeModule(HINSTANCE hDLL) : oapi::Module( hDLL ) {
  return;
}
GlideslopeModule::~GlideslopeModule() {
  return;
};
void GlideslopeModule::clbkSimulationStart(RenderMode mode) {
  return;
};
void GlideslopeModule::clbkSimulationEnd() {
  return;
}
    [COLOR=#B00040]void[/COLOR] [COLOR=#0000FF]GlideslopeModule::clbkPreStep[/COLOR] ([COLOR=#B00040]double[/COLOR] simt, [COLOR=#B00040]double[/COLOR] simdt, [COLOR=#B00040]double[/COLOR] mjd){}  
    [COLOR=#408080][I]/// Time step notification after state update.[/I][/COLOR] 
    [COLOR=#408080][I]/** Refer to OrbiterSDK documentation */[/I][/COLOR] 
    [COLOR=#B00040]void[/COLOR] GlideslopeModule::[COLOR=#0000FF]clbkPostStep[/COLOR] ([COLOR=#B00040]double[/COLOR] simt, [COLOR=#B00040]double[/COLOR] simdt, [COLOR=#B00040]double[/COLOR] mjd){}

Also for persistance + multiple vessels support, you might want to look here:
http://sourceforge.net/p/enjomitchsorbit/codeHG/ci/default/tree/libMFD/multipleVesselsMFD/
 

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,667
Reaction score
3
Points
38
Sorry Enjo - I was using clbkSimulationEnd() as an example. Adding in the clbkPreStep(), clbkPostStep() etc still is not getting called.

It's a generic question really - is the goal to create a core class inheriting oapi::Module like this, or am I meant to make the class implementing MsgProc be inherited from oapi::Module ?
 

Enjo

Mostly harmless
Addon Developer
Tutorial Publisher
Donator
Joined
Nov 25, 2007
Messages
1,665
Reaction score
13
Points
38
Location
Germany
Website
www.enderspace.de
Preferred Pronouns
Can't you smell my T levels?
MsgProc is usually implemented by the MFD itself.

I see the problem. Use InitModule and ExitModule, rather than the deprecated opcDLLInit and opcDLLExit:

PHP:
GlideslopeModule * plugin;

static struct {
  int mode;
} g_GlideslopeMFD;

DLLCLBK void InitModule (HINSTANCE hDLL) {  
static char *name = "GlideslopeMFD";   
MFDMODESPECEX spec;   
spec.name    = name;   
spec.key     = OAPI_KEY_W;   
spec.msgproc = GlideslopeMFD::MsgProc;   
spec.context = NULL;    
g_GlideslopeMFD.mode = oapiRegisterMFDMode (spec);   
plugin = new GlideslopeModule( hDLL );  
oapiRegisterModule (plugin); 
}  

DLLCLBK void ExitModule (HINSTANCE hDLL) {   
oapiUnregisterMFDMode (g_GlideslopeMFD.mode); 
}
 

orb

New member
News Reporter
Joined
Oct 30, 2009
Messages
14,020
Reaction score
4
Points
0
You need to use oapiRegisterModule to register your oapi::Module class in Orbiter (the best in InitModule) for it to by usable by Orbiter.

BTW, why are you using deprecated opcDLLInit, opcDLLExit instead of InitModule, ExitModule?
 

Enjo

Mostly harmless
Addon Developer
Tutorial Publisher
Donator
Joined
Nov 25, 2007
Messages
1,665
Reaction score
13
Points
38
Location
Germany
Website
www.enderspace.de
Preferred Pronouns
Can't you smell my T levels?
Ninja Ninja'd
 

ADSWNJ

Scientist
Addon Developer
Joined
Aug 5, 2011
Messages
1,667
Reaction score
3
Points
38
You need to use oapiRegisterModule to register your oapi::Module class in Orbiter (the best in InitModule) for it to by usable by Orbiter.

BTW, why are you using deprecated opcDLLInit, opcDLLExit instead of InitModule, ExitModule?

I'm renovating old code, that's why! Will try InitModule instead as you and Szymon say.



----------------

EDIT:

This worked. Thanks guys - problem solved.
 
Last edited:
Top