dazz Posted March 12, 2012 Report Posted March 12, 2012 Some ipc calls in Lua threads are explicitly subjected, in FSUIPC, to a "sleep" of 0 or 1 millisecond. This is in order to make sure other threads, and FS's own main thread, gets enough time. In fact the vast majority of the time needs to be spent in the FS executing threads. I'm not sure why you are using ipc.set, which stores values in another (permanent) Lua threads's stack so that they can be retrieved by other threads using ipc.get, but obviously there's a process switch involved each time you do that. Alternatively I would assume that if you are updating FSUIPC offsets from your DLL you'd be doing that directly via the FSUIPC DLL module interface, not via Lua programmed code. There is really no need for FSUIPC to provide Lua plug-ins with ultra-fast execution speeds. The application here is merely the updating of displays or whatever with read-ots from the NGX. FSUIPC + Lua can easily meet the needs of displays at any rate needed smooth to the eye. The prime aim of FSUIPC in these matters is the provision of useful plug-in facilities which don't detract from or impinge upon the performance of FS in any noticeable, or even, hopefully, measurable way. Regards Pete Pete, I was calling ipc.log/ ipc.set, just to test the output of the function call, and the cost in time of the process. It has nothing to do with any implementation decision. Thanks for the clarification on the 1ms thing. The idea was always to transfer / integrate the NGX SDK functionality to the Lua layer in FSUIPC. It's not a client on itself, just an interface. If Lua (or some of the Lua libraries implemented in FSUIPC) has this little performance limitation I still don't think it will be a major issue since like Nico said, only controls that make sense to poll are those belonging to annunciators, lights, displays... and the client can split them in groups that run on their own threads anyway. If something ends ups calling some ipc or any other library with sleeps, it means that it won't be taking up too much CPU time and you can have plenty of those running with no perf issues. I can always mention that in the documentation. One thing I'm not sure about is what you mean by "updating FSUIPC offsets from your DLL directly via the FSUIPC DLL module interface" Would you please mind clarifiying? One of the strong points that I thought my solution had is the flexibility to avoid using offsets, that are a limited to a certain number
dazz Posted March 12, 2012 Report Posted March 12, 2012 I tried something that makes more sense in the Lua implementation for one of the items, which is writing to my VRInsight device display using the com library. That looks to have no sleeps, it completes almost instantly.
Pete Dowson Posted March 12, 2012 Report Posted March 12, 2012 One thing I'm not sure about is what you mean by "updating FSUIPC offsets from your DLL directly via the FSUIPC DLL module interface" Would you please mind clarifiying? One of the strong points that I thought my solution had is the flexibility to avoid using offsets, that are a limited to a certain number That was only a reference back to the alternative idea I suggested, that of providing values to Lua plug-ins (or anything else for that matter) by posting them in offsets, rather than the original idea you had of executing a receiving Lua program. I wouldn't think too much on that side of things though. If we can get a reasonable understanding on the EULA with PMDG then I'm sure Nico and/or I will sort the offset method out fine. We need PMDG to recognise that utility programs providing transparency for the data made available via their SDK do not in any way constitute "End Use" and are therefore not subject to the EULA. As Nico has pointed out over in the MyCockpits thread, one clause in particular is worrying in that regard. I tried something that makes more sense in the Lua implementation for one of the items, which is writing to my VRInsight device display using the com library. That looks to have no sleeps, it completes almost instantly. Yes, that would be the sort of application I would envisage. Regards Pete
dazz Posted March 12, 2012 Report Posted March 12, 2012 That was only a reference back to the alternative idea I suggested, that of providing values to Lua plug-ins (or anything else for that matter) by posting them in offsets, rather than the original idea you had of executing a receiving Lua program. I wouldn't think too much on that side of things though. If we can get a reasonable understanding on the EULA with PMDG then I'm sure Nico and/or I will sort the offset method out fine. We need PMDG to recognise that utility programs providing transparency for the data made available via their SDK do not in any way constitute "End Use" and are therefore not subject to the EULA. As Nico has pointed out over in the MyCockpits thread, one clause in particular is worrying in that regard. Yes, that would be the sort of application I would envisage. Regards Pete Ok, so if I got it right you mean the solution you mentioned of storing the data in predefined FSUIPC offsets right at the dll / C++, so that Lua pluggins or anyone can listen via events or read them or whatever. I guess I need to take a look at the FSUIPC_SDK docs. Anyway, I'll leave that to you guys then.
roarkr Posted March 12, 2012 Report Posted March 12, 2012 Ok, so if I got it right you mean the solution you mentioned of storing the data in predefined FSUIPC offsets right at the dll / C++, so that Lua pluggins or anyone can listen via events or read them or whatever. I guess I need to take a look at the FSUIPC_SDK docs. Anyway, I'll leave that to you guys then. Hi, Here is an example of how to use events to detect offsets changes, both on bit level and whole words. Keep in mind that I'm not a programmer, so it maybe can be done better. rgs Roar -- PMDG 737 NGX LUA code for Opencockpits MCP to be used in FSUIPC -- File: NGXMCP_202 -- December 2011 -- Roar Kristensen --*************************************************************************************** -- ** System initial values set ** --*************************************************************************************** -- ** MCP initial values ** hdg_mode = 1 atarm = -1 crsl = 500 crsr = 500 spd = -1 hdg = -1 alt = -1 vsw = -1 MCP_N1 = -1 MCP_Speed = -1 MCP_LvlChg = -1 MCP_VNav = -1 MCP_LNav = -1 MCP_HdgSel = -1 MCP_AltHold = -1 MCP_CMDA = -1 MCP_CMDB = -1 MCP_CWSA = -1 MCP_CWSB = -1 MCP_VORLock = -1 MCP_App = -1 MCP_VS = -1 ipc.writeUB("66E8", 0) ipc.writeUB("66E9", 0) ipc.writeUB("66EA", 0) ipc.writeUB("66EB", 0) ipc.writeUB("66EC", 0) ipc.writeUB("66ED", 0) if ipc.readUB("66E4") == 1 and ipc.readLvar('ngx_switch_378_a') == 100 then ipc.control(70010, 536870912) ipc.control(70010, 131072) else if ipc.readUB("66E4") == 0 and ipc.readLvar('ngx_switch_378_a') == 0 then ipc.control(70010, 536870912) ipc.control(70010, 131072) end end if ipc.readUB("66E5") == 1 and ipc.readLvar('ngx_switch_380_a') == 100 then ipc.control(70012, 536870912) ipc.control(70012, 131072) else if ipc.readUB("66E5") == 0 and ipc.readLvar('ngx_switch_380_a') == 0 then ipc.control(70012, 536870912) ipc.control(70012, 131072) end end if ipc.readUB("66E6") == 0 and ipc.readLvar('ngx_switch_406_a') == 100 then ipc.control(70038, 536870912) ipc.control(70038, 131072) else if ipc.readUB("66E6") == 1 and ipc.readLvar('ngx_switch_406_a') == 0 then ipc.control(70038, 536870912) ipc.control(70038, 131072) end end if ipc.readUB("66E7") == 1 and ipc.readLvar('ngx_switch_407_a') == 100 then ipc.control(70039, 536870912) ipc.control(70039, 131072) else if ipc.readUB("66E7") == 0 and ipc.readLvar('ngx_switch_407_a') == 0 then ipc.control(70039, 536870912) ipc.control(70039, 131072) end end if crsl ~= ipc.readLvar("L:ngx_CRSwindowL") then crsl = ipc.readLvar("L:ngx_CRSwindowL") ipc.writeUW("66C0", crsl) end if spd ~= ipc.readLvar("L:ngx_SPDwindow") then spd = ipc.readLvar("L:ngx_SPDwindow") ipc.writeUW("66C2", spd) end if hdg ~= ipc.readLvar("L:ngx_HDGwindow") then hdg = ipc.readLvar("L:ngx_HDGwindow") ipc.writeUW("66C4", hdg) end if alt ~= ipc.readLvar("L:ngx_ALTwindow") then alt = ipc.readLvar("L:ngx_ALTwindow") ipc.writeUW("66C6", ipc.readLvar("L:ngx_ALTwindow") / 100) end --if ipc.readLvar("L:ngx_MCP_VS") == 1 then if vsw ~= ipc.readLvar("L:ngx_VSwindow") then vsw = -20000 ipc.writeSW("66D0", -20000) end if crsr ~= ipc.readLvar("L:ngx_CRSwindowR") then crsr = ipc.readLvar("L:ngx_CRSwindowR") ipc.writeUW("66CA", crsr) end --*************************************************************************************** -- ** Procedures for reading MCP windows and sending to SIOC via FSUIPC offsets**** --*************************************************************************************** function CRSL_show () crsl = ipc.readLvar("L:ngx_CRSwindowL") ipc.writeUW("66C0", crsl) end function SPD_show () spd = ipc.readLvar("L:ngx_SPDwindow") if spd > 1 then ipc.writeUW("66C2", spd) else spd = spd *100 ipc.writeUW("66C2", spd) end end function HDG_show () hdg = ipc.readLvar("L:ngx_HDGwindow") ipc.writeUW("66C4", hdg) end function ALT_show () alt = ipc.readLvar("L:ngx_ALTwindow") ipc.writeUW("66C6", alt / 100) end function VS_show () vsw = ipc.readLvar("L:ngx_VSwindow") ipc.writeSW("66C8", vsw) end function CRSR_show () crsr = ipc.readLvar("L:ngx_CRSwindowR") ipc.writeUW("66CA", crsr) end --*************************************************************************************** -- ** Procedures for finding changes in MCP windows and MCP function LEDs**** --*************************************************************************************** function run_update (time) if crsl ~= ipc.readLvar("L:ngx_CRSwindowL") then CRSL_show () end if crsr ~= ipc.readLvar("L:ngx_CRSwindowR") then CRSR_show () end if spd ~= ipc.readLvar("L:ngx_SPDwindow") then SPD_show () end if hdg ~= ipc.readLvar("L:ngx_HDGwindow") then HDG_show () end if alt ~= ipc.readLvar("L:ngx_ALTwindow") then ALT_show () end if vsw ~= ipc.readLvar("L:ngx_VSwindow") then VS_show () end if ipc.readLvar("L:ngx_MCP_ATArm") ~= atarm then atarm = ipc.readLvar("L:ngx_MCP_ATArm") ipc.writeUB("66F0", atarm) end if ipc.readLvar("L:ngx_MCP_N1") ~= MCP_N1 then MCP_N1 = ipc.readLvar("L:ngx_MCP_N1") ipc.writeUB("66F1", MCP_N1) end if ipc.readLvar("L:ngx_MCP_SPEED") ~= MCP_Speed then MCP_Speed = ipc.readLvar("L:ngx_MCP_SPEED") ipc.writeUB("66F2", MCP_Speed) end if ipc.readLvar("L:ngx_MCP_VNav") ~= MCP_VNav then MCP_VNav = ipc.readLvar("L:ngx_MCP_VNav") ipc.writeUB("66F3", MCP_VNav) end if ipc.readLvar("L:ngx_MCP_LvlChg") ~= MCP_LvlChg then MCP_LvlChg = ipc.readLvar("L:ngx_MCP_LvlChg") ipc.writeUB("66F4", MCP_LvlChg) end if ipc.readLvar("L:ngx_MCP_HdgSel") ~= MCP_HdgSel then MCP_HdgSel = ipc.readLvar("L:ngx_MCP_HdgSel") ipc.writeUB("66F5", MCP_HdgSel) end if ipc.readLvar("L:ngx_MCP_LNav") ~= MCP_LNav then MCP_LNav = ipc.readLvar("L:ngx_MCP_LNav") ipc.writeUB("66F6", MCP_LNav) end if ipc.readLvar("L:ngx_MCP_VORLock") ~= MCP_VORLock then MCP_VORLock = ipc.readLvar("L:ngx_MCP_VORLock") ipc.writeUB("66F7", MCP_VORLock) end if ipc.readLvar("L:ngx_MCP_App") ~= MCP_App then MCP_App = ipc.readLvar("L:ngx_MCP_App") ipc.writeUB("66F8", MCP_App) end if ipc.readLvar("L:ngx_MCP_AltHold") ~= MCP_AltHold then MCP_AltHold = ipc.readLvar("L:ngx_MCP_AltHold") ipc.writeUB("66F9", MCP_AltHold) end if ipc.readLvar("L:ngx_MCP_VS") ~= MCP_VS then MCP_VS = ipc.readLvar("L:ngx_MCP_VS") ipc.writeUB("66FA", MCP_VS) end if MCP_CMDA ~= ipc.readLvar("L:ngx_MCP_CMDA") then MCP_CMDA = ipc.readLvar("L:ngx_MCP_CMDA") ipc.writeUB("66FB", MCP_CMDA) end if MCP_CWSA ~= ipc.readLvar("L:ngx_MCP_CWSA") then MCP_CWSA = ipc.readLvar("L:ngx_MCP_CWSA") ipc.writeUB("66FC", MCP_CWSA) end if MCP_CMDB ~= ipc.readLvar("L:ngx_MCP_CMDB") then MCP_CMDB = ipc.readLvar("L:ngx_MCP_CMDB") ipc.writeUB("66FD", MCP_CMDB) end if MCP_CWSB ~= ipc.readLvar("L:ngx_MCP_CWSB") then MCP_CWSB = ipc.readLvar("L:ngx_MCP_CWSB") ipc.writeUB("66FE", MCP_CWSB) end end --*************************************************************************************** -- ** MCP switches ******* --*************************************************************************************** function MCP_FD1(off,val) if ipc.readUB("66EF") == 7 then if val == 1 and ipc.readLvar('ngx_switch_378_a') == 100 then ipc.control(70010, 536870912) ipc.control(70010, 131072) else if val == 0 and ipc.readLvar('ngx_switch_378_a') == 0 then ipc.control(70010, 536870912) ipc.control(70010, 131072) end end end end function MCP_ATARM(off,val) if ipc.readUB("66EF") == 7 then if val == 1 and ipc.readLvar('ngx_switch_380_a') == 100 then ipc.control(70012, 536870912) ipc.control(70012, 131072) else if val == 0 and ipc.readLvar('ngx_switch_380_a') == 0 then ipc.control(70012, 536870912) ipc.control(70012, 131072) end end end end function MCP_DISENGAGE(off,val) if ipc.readUB("66EF") == 7 then if val == 0 and ipc.readLvar('ngx_switch_406_a') == 100 then ipc.control(70038, 536870912) ipc.control(70038, 131072) else if val == 1 and ipc.readLvar('ngx_switch_406_a') == 0 then ipc.control(70038, 536870912) ipc.control(70038, 131072) end end end end function MCP_FD2(off,val) if ipc.readUB("66EF") == 7 then if val == 1 and ipc.readLvar('ngx_switch_407_a') == 100 then ipc.control(70039, 536870912) ipc.control(70039, 131072) else if val == 0 and ipc.readLvar('ngx_switch_407_a') == 0 then ipc.control(70039, 536870912) ipc.control(70039, 131072) end end end end function MCP1(off, val) if logic.And(val, 0x0010) ~= 0 then N1 () elseif logic.And(val, 0x0020) ~= 0 then SPEED () elseif logic.And(val, 0x0040) ~= 0 then CO () elseif logic.And(val, 0x0080) ~= 0 then SPD_INTV () elseif logic.And(val, 0x0100) ~= 0 then VNAV () elseif logic.And(val, 0x0200) ~= 0 then LVLCHG () elseif logic.And(val, 0x0400) ~= 0 then HDGSEL () elseif logic.And(val, 0x0800) ~= 0 then HDG_BANK () elseif logic.And(val, 0x1000) ~= 0 then LNAV () elseif logic.And(val, 0x2000) ~= 0 then VORLOC () elseif logic.And(val, 0x4000) ~= 0 then APP () elseif logic.And(val, 0x8000) ~= 0 then ALT_INTV () end end function MCP2(off, val) if logic.And(val, 0x0001) ~= 0 then ALTHLD () elseif logic.And(val, 0x0002) ~= 0 then VS () elseif logic.And(val, 0x0004) ~= 0 then CMDA () elseif logic.And(val, 0x0008) ~= 0 then CWSA () elseif logic.And(val, 0x0010) ~= 0 then CMDB () elseif logic.And(val, 0x0020) ~= 0 then CWSB () end end --*************************************************************************************** -- ** MCP Dials ******** --*************************************************************************************** function CRSL_chg (off,val) if val == 255 then ipc.sleep(0) else if val > 0 then local i for i = 1, val do ipc.control(70008, 16384) ipc.sleep (5) end ipc.writeUB("66E8", 255) CRSL_show () else if val < 0 then val = val* -1 local i for i = 1, val do ipc.control(70008, 8192) ipc.sleep (5) end ipc.writeUB("66E8", 255) CRSL_show () else if val == 0 then ipc.writeUB("66E8", 0) end end end end end function SPD_chg (off,val) if val == 255 then ipc.sleep(0) else if val > 0 then local i for i = 1, val do ipc.control(70016, 16384) ipc.sleep (5) end ipc.writeUB("66E9", 255) SPD_show () else if val < 0 then val = val* -1 local i for i = 1, val do ipc.control(70016, 8192) ipc.sleep (5) end ipc.writeUB("66E9", 255) SPD_show () else if val == 0 then ipc.writeUB("66E9", 0) end end end end end function HDG_chg (off,val) if hdg_mode == 1 then if val == 255 then ipc.sleep(0) else if val > 0 then local i for i = 1, val do ipc.control(70022, 16384) ipc.sleep (5) end ipc.writeUB("66EA", 255) HDG_show () else if val < 0 then val = val* -1 local i for i = 1, val do ipc.control(70022, 8192) ipc.sleep (5) end ipc.writeUB("66EA", 255) HDG_show () else if val == 0 then ipc.writeUB("66EA", 0) end end end end else BANK_chg (off,val) end end function BANK_chg (off,val) if val == 255 then ipc.sleep(0) else if val > 0 then local i for i = 1, val do ipc.control(70021, -2147483648) ipc.control(70021, 524288) ipc.sleep (5) end ipc.writeUB("66EA", 255) else if val < 0 then val = val* -1 local i for i = 1, val do ipc.control(70021, 536870912) ipc.control(70021, 131072) ipc.sleep (5) end ipc.writeUB("66EA", 255) else if val == 0 then ipc.writeUB("66EA", 0) end end end end end function ALT_chg (off,val) if val == 255 then ipc.sleep(0) else if val > 0 then local i for i = 1, val do ipc.control(70032, 16384) ipc.sleep (5) end ipc.writeUB("66EB", 255) ALT_show () else if val < 0 then val = val* -1 local i for i = 1, val do ipc.control(70032, 8192) ipc.sleep (5) end ipc.writeUB("66EB", 255) ALT_show () else if val == 0 then ipc.writeUB("66EB", 0) end end end end end function VS_chg (off,val) if val == 255 then ipc.sleep(0) else if val > 0 then local i for i = 1, val do ipc.control(70033, 8192) ipc.sleep (5) end ipc.writeUB("66EC", 255) VS_show () else if val < 0 then val = val* -1 local i for i = 1, val do ipc.control(70033, 16384) ipc.sleep (5) end ipc.writeUB("66EC", 255) VS_show () else if val == 0 then ipc.writeUB("66EC", 0) end end end end end function CRSR_chg (off,val) if val == 255 then ipc.sleep(0) else if val > 0 then local i for i = 1, val do ipc.control(70041, 16384) ipc.sleep (5) end ipc.writeUB("66ED", 255) CRSR_show () else if val < 0 then val = val* -1 local i for i = 1, val do ipc.control(70041, 8192) ipc.sleep (5) end ipc.writeUB("66ED", 255) CRSR_show () else if val == 0 then ipc.writeUB("66ED", 0) end end end end end --*************************************************************************************** -- ** MCP buttons ************** --*************************************************************************************** function N1 () ipc.control(70013, 536870912) ipc.control(70013, 131072) end function SPEED () if ipc.readLvar("L:ngx_MCP_VNav") == 1 then -- go to SPD_INTV instead ipc.control(70019, 536870912) ipc.control(70019, 131072) else ipc.control(70014, 536870912) ipc.control(70014, 131072) end end function CO () ipc.control(70015, 536870912) ipc.control(70015, 131072) end function SPD_INTV () ipc.control(70019, 536870912) ipc.control(70019, 131072) end function ALT_INTV () ipc.control(70517, 536870912) ipc.control(70517, 131072) end function HDG_BANK () -- toggling HDG / BANK (1/2) -- HDG = 1, BANK = 2 hdg_mode = 3 - hdg_mode end function VNAV () ipc.control(70018, 536870912) ipc.control(70018, 131072) end function LVLCHG () ipc.control(70023, 536870912) ipc.control(70023, 131072) end function HDGSEL () ipc.control(70024, 536870912) ipc.control(70024, 131072) end function LNAV () ipc.control(70029, 536870912) ipc.control(70029, 131072) end function VORLOC () ipc.control(70028, 536870912) ipc.control(70028, 131072) end function APP () ipc.control(70025, 536870912) ipc.control(70025, 131072) end function ALTHLD () if ipc.readLvar("L:ngx_MCP_VNav") == 1 then -- go to ALT_INTV instead ipc.control(70517, 536870912) ipc.control(70517, 131072) else ipc.control(70026, 536870912) ipc.control(70026, 131072) end end function VS () ipc.control(70027, 536870912) ipc.control(70027, 131072) end function CMDA () ipc.control(70034, 536870912) ipc.control(70034, 131072) end function CMDB () ipc.control(70035, 536870912) ipc.control(70035, 131072) end function CWSA () ipc.control(70036, 536870912) ipc.control(70036, 131072) end function CWSB () ipc.control(70037, 536870912) ipc.control(70037, 131072) end --*************************************************************************************** -- ** Routines to detect MCP buttons and dials changes ** --*************************************************************************************** event.offset(0x66E4, "UB", "MCP_FD1") event.offset(0x66E5, "UB", "MCP_ATARM") event.offset(0x66E6, "UB", "MCP_DISENGAGE") event.offset(0x66E7, "UB", "MCP_FD2") event.offset(0x66E0, "UW", "MCP1") event.offset(0x66E2, "UW", "MCP2") event.intercept(0x66E8, "SB", "CRSL_chg") event.intercept(0x66E9, "SB", "SPD_chg") event.intercept(0x66EA, "SB", "HDG_chg") event.intercept(0x66EB, "SB", "ALT_chg") event.intercept(0x66EC, "SB", "VS_chg") event.intercept(0x66ED, "SB", "CRSR_chg") --*************************************************************************************** -- ** Timer for MCP diplays and LED update --*************************************************************************************** event.timer(100, "run_update")
dazz Posted March 12, 2012 Report Posted March 12, 2012 Hi, Here is an example of how to use events to detect offsets changes, both on bit level and whole words. Keep in mind that I'm not a programmer, so it maybe can be done better. rgs Roar Thanks Roar. Do the rest of the OC devices work in the same way, listening to certain offsets?
dazz Posted March 12, 2012 Report Posted March 12, 2012 I already got the FSUIPC_SDK up and running in my VS project, so I may consider the direct offset writing solution. Question is to define the offset space, it would be from 0x66C0 I guess
roarkr Posted March 12, 2012 Report Posted March 12, 2012 Thanks Roar. Do the rest of the OC devices work in the same way, listening to certain offsets? Hi, The way I have implemented this, yes. The OP sioc software is a event driven program. It does only execute code when a variable change value. Either a variable connected to a specific IOCARD input or a variable linked to a offset. rgs
dazz Posted March 12, 2012 Report Posted March 12, 2012 Hi, The way I have implemented this, yes. The OP sioc software is a event driven program. It does only execute code when a variable change value. Either a variable connected to a specific IOCARD input or a variable linked to a offset. rgs Okay. Obviously keeping the offsets up to date in the dll would mean plug&play for OC devices then (with the corresponding SIOC implementation to listen to the same offset mapping)
dazz Posted March 12, 2012 Report Posted March 12, 2012 I've got an idea. I can register two functions in my dll to read and write an offset very much like ipcread & ipc.write do, but without the 1ms sleep limitation
dazz Posted March 13, 2012 Report Posted March 13, 2012 I'm doing something I think should address the offset "issues", being those 1.- I had no way to set offsets in the dll 2.- setting offsets from lua via ipc lib is too slow. 500 iterations take some 20 seconds, so this module would be colmpletely useless for devices that listen to offsets that are being updated from Lua So I implemented a way to register items to be stored in any offset. An example: ngxSDK2Lua.registerOffset("IRS_DisplaySelector", 0x6CCC, "writeUB")[/CODE]this would instruct the dll to store any new data in the item "IRS_SysDisplay_R" to the offset 0x6CCC as an unsigned byte. Or..[CODE]ngxSDK2Lua.registerOffset("IRS_SysDisplay_R", 0x6DCC, "setbitsUB", 1) -- last param is the mask for setbitsUB[/CODE]to assign the IRS_SysDisplay_R boolean to the first bit (least significant) of the offset 0x6DCCI'll be using a hash map (I think it has direct access to the members) to speed things up[CODE]static std::hash_map<std::string, OffsetCall> offsetMappings;[/CODE]to retrieve a struct for each mapped item[CODE]struct OffsetCall{void (*offsetFunction)(DWORD dwOffset, void* valueOrMask);DWORD dwOffset;DWORD mask;};[/CODE]then call the offsetFunction with the new value of the item (or the mask for functions like setbitsXX or clearbitsXX)should be pretty fast me thinks, and it's 100% configurable
roarkr Posted March 14, 2012 Report Posted March 14, 2012 Actually I did understand WHAT you were doing, just not WHY. It just seems rather complicated. Or maybe it's just me? Yes, that's what I find so complicated. How is this going to work for a user who wants to populate all his hardware displays with indicators and values from the NGX data? If you wanted to do it that way why not simply use a mechanism like my "event" system. Let the Lua program which is doing the "requiring" call an event function in your C DLL which provides it with the name of the function to be called when a specified value changes. You'd need to build a list of those. Then, at the end of that Lua program, instead of exiting back to FSUIPC, it would need call an "execute" function in your DLL which then processes the dispatches, in a loop as now. This way you don't need to execute a separate Lua plug-in, it is nice and tidy all in one Lua and one DLL, both running in the one thread. The only trouble is that because the thread never exits back to FSUIPC, that same Lua can't use the FSUIPC event system. (But that applies to your current method too). The other way is the way I proposed before, which is having a separate thread in the DLL which is maintaining the data copy with functions which supply values on request. The problem with that is how to detect that the Lua plug-in has terminated so that the separate thread can be terminated tidily. I'm starting to wonder if it wouldn't be much tidier to forget the Lua way of doing it altogether, and just have an EXE program which gets the NGX data and posts them to assigned FSUIPC offsets, which can then be read by any Lua plug-ins, and other programs, even on a WideFS client. I would actually consider building this into FSUIPC (it is easy as it already has a working SimConnect interface), but I don't like some sections of PMDG's EULA. I'd need PMDG's blessing first. Maybe I should write to Mr. Randazzo. Regards Pete Hi Pete, I don't know what your plans are about doing something for the PMDG NGX in your FSUIPC4 now that the SDK is available. As Nico don't wanna do a "lekseecon" for the PMDG NGX I have started to make my own " NGXCon" IOCP client to be used for the OpencCockpits SIOC environement. But, as I am not a "prof" programmer this can take some time before I'm ready. So to my question: Are you going to do what you said: "" I'm starting to wonder if it wouldn't be much tidier to forget the Lua way of doing it altogether, and just have an EXE program which gets the NGX data and posts them to assigned FSUIPC offsets, which can then be read by any Lua plug-ins, and other programs, even on a WideFS client. I would actually consider building this into FSUIPC (it is easy as it already has a working SimConnect interface),"" if so what and what is your timeframe? Then I could do the LUA scripting to get what I want and that is maybe the way to go instead of an dedicated IOCP client based on C++ ( which I need to learn better). rgs
Pete Dowson Posted March 14, 2012 Report Posted March 14, 2012 I don't know what your plans are about doing something for the PMDG NGX in your FSUIPC4 now that the SDK is available. I want to provide supporting offsets for at least a significant subset of the data available. I'm not sure if I'll do all of it, but hopefully all those entries which matter to a cockpit builder. As Nico don't wanna do a "lekseecon" for the PMDG NGX I have started to make my own " NGXCon" IOCP client to be used for the OpencCockpits SIOC environement. Yes, I noticed. So to my question:Are you going to do what you said: I need an answer from PMDG about my questions regarding the EULA first. Like Nico, I am greatly concerned over several of the clauses, especially the one which would appear to make me responsible for how the data is used -- even though i'm only providing a window onto it and am not the "End User" but a facilitator, just as the SDK is. I have no direct links with anyone at PMDG these days -- I used to have good relationships with Lefteris but of course he's no longer there. So all I could do is raise the question and request 'permission' through the ticket system, as it says to do in the EULA. That was Sunday morning. There's still no reply now. I've raised it on the NGX support forum too, asking someone from PMDG to email me. Again, nothing. All I can do is wait. :-( if so what and what is your timeframe? Once I am okay to go without fear of legal consequences it can be very quick indeed. The code for interfacing to SimConnect client Data is already implemented in FSUIPC4 in any case, as it's used for other things like the AES status and Squawkbox4 transponder modes. I would just need to work out the offset details and map the data. Maybe make some of them writeable as well, with FSUIPC operating the events, but that wouldn't be the first priority which is to get the data out. Regards Pete
Andydigital Posted March 14, 2012 Report Posted March 14, 2012 I think PMDG have problems with their email server as well, I have never received an email when a reply was made to a support ticket, I have always had to visit the support site again and check to see if a reply had been made, usually they have replied within 24 or so hours. Reading around the forums its seems to be a common problem, maybe there server is blacklisted for some reason.
Pete Dowson Posted March 14, 2012 Report Posted March 14, 2012 I think PMDG have problems with their email server as well, I have never received an email when a reply was made to a support ticket, I have always had to visit the support site again and check to see if a reply had been made, usually they have replied within 24 or so hours. I have been visiting the support site and checking whether there's a reply yet regularly. I didn't know whether to expect an email or not. I have a short-cut taking me straight there, so I check it as often as i check my email. Still no joy. Regards Pete
dazz Posted March 14, 2012 Report Posted March 14, 2012 I also sent a ticket asking them if they would mind checking an installer and giving it the OK. Thay was 4 days ago and still no answer either. My module should be ready for testing in a few days. I think I'll just release it and see what happens
kiek Posted March 14, 2012 Report Posted March 14, 2012 I have been visiting the support site and checking whether there's a reply yet regularly. I didn't know whether to expect an email or not. I have a short-cut taking me straight there, so I check it as often as i check my email. Still no joy. Regards Pete Pete, I guess that they have to consult their lawyers. This may take weeks ;-)
dazz Posted March 15, 2012 Report Posted March 15, 2012 Pete, this is almost ready, but I'm geting random crashes if I run FSUIPC_Process(&dwResult); right after writing an offset: FSUIPC_Write(dwOffset, 1, pSrce, &dwResult); FSUIPC_Process(&dwResult); If I process the read/writes once after the entire dispatch loop is done, it works fine (probably a better way to go about it anyway) Not sure how to debug this
Pete Dowson Posted March 15, 2012 Report Posted March 15, 2012 Pete, this is almost ready, but I'm geting random crashes if I run FSUIPC_Process(&dwResult); right after writing an offset: Crashes in what? Your program or mine? I need more information. If in FS, the crash error code, the module and its offset. If I process the read/writes once after the entire dispatch loop is done, it works fine (probably a better way to go about it anyway) The whole point of a separate "Process" call to the "Read" and "Write" calls is for efficiency. The read/write calls simply add a request to a list, in your own memory. Not sure how to debug this Aren't you using a development system with a debugger? If should tell you exactly where and why a crash is occurring. Regards Pete
johanknol Posted March 15, 2012 Report Posted March 15, 2012 I made a small dll wrapper with just 2 exported methods and an internal SimConnect_CallDispatch thread void *GetPmdgData() and int RaisePMDGEvent(EPmdgEvent event, int parameter) I use it to Marshal it into C# where I emacs-ed PMDG_NGX_SDK.h into C# structs and enums. If someone is interested I could post or upload some code here.
Graham Pollitt Posted March 15, 2012 Report Posted March 15, 2012 I made a small dll wrapper with just 2 exported methods and an internal SimConnect_CallDispatch thread void *GetPmdgData() and int RaisePMDGEvent(EPmdgEvent event, int parameter) I use it to Marshal it into C# where I emacs-ed PMDG_NGX_SDK.h into C# structs and enums. If someone is interested I could post or upload some code here. I'm interested if someone can make dll to interface with vb.net!
NedHamilton Posted March 16, 2012 Report Posted March 16, 2012 I made a small dll wrapper with just 2 exported methods and an internal SimConnect_CallDispatch thread void *GetPmdgData() and int RaisePMDGEvent(EPmdgEvent event, int parameter) I use it to Marshal it into C# where I emacs-ed PMDG_NGX_SDK.h into C# structs and enums. If someone is interested I could post or upload some code here. I'm interested in seeing the code. I program mostly in C# and find it too painful to go back to C++.
johanknol Posted March 16, 2012 Report Posted March 16, 2012 Ok, I wrapped it up as a zipped vs2010 solution in https://docs.google.com/open?id=0B2Rk9ossiH4Hc1NRSFZqYVdRZ1dUM1lMNldpRkxSZw It's the wrapper dll and a very basic C# example that simply dumps all the variables in a grid and toggles the taxi light switch once in a while. Have fun!
dazz Posted March 18, 2012 Report Posted March 18, 2012 I have no idea what's going on. All of a sudden I don't get any PMDG events detected in the dispatch method. I haven't changed anything in the Simconnect initialization and RequestClientData part. I get an event dwID 15, then a 2 and nothing else. Have commented out everything except for what's in the example provided by PMDG and still no go. I know it's not too much info, but maybe it rings a bell... or maybe I could upload the VS project So frustrating cause it's finished I'm sure I'm missing something stupid somewhere
johanknol Posted March 18, 2012 Report Posted March 18, 2012 ... So frustrating cause it's finished I'm sure I'm missing something stupid somewhere I've seen that a couple of times too, most often it's working again after reloading the ac, don't have a real grip on that yet. If i'll find a clue i'll post it, please do so as well. Johan
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