Created thread for osc receiver. Created osc message handler (works for int only for now). Many small changes.
This commit is contained in:
parent
c2e3136e92
commit
678b0d09a4
@ -3,79 +3,64 @@
|
|||||||
#include "dllmain.h"
|
#include "dllmain.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
#include "osc/OscReceivedElements.h"
|
#include "osc/OscReceivedElements.h"
|
||||||
#include "osc/OscPacketListener.h"
|
#include "osc/OscPacketListener.h"
|
||||||
#include "ip/UdpSocket.h"
|
#include "ip/UdpSocket.h"
|
||||||
|
|
||||||
class ExamplePacketListener : public osc::OscPacketListener {
|
//Class from OSC library (oscpack). This calls our handleOscMsg() on every new message.
|
||||||
|
class ThePacketListener : public osc::OscPacketListener {
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void ProcessMessage(const osc::ReceivedMessage& m,
|
virtual void ProcessMessage(const osc::ReceivedMessage& m,
|
||||||
const IpEndpointName& remoteEndpoint)
|
const IpEndpointName& remoteEndpoint)
|
||||||
{
|
{
|
||||||
OutputDebugString(L"Got OSC Message!\r\n");
|
|
||||||
(void)remoteEndpoint; // suppress unused parameter warning
|
(void)remoteEndpoint; // suppress unused parameter warning
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// example of parsing single messages. osc::OsckPacketListener
|
handleOscMsg(m);
|
||||||
// handles the bundle traversal.
|
|
||||||
|
|
||||||
if (std::strcmp(m.AddressPattern(), "/test1") == 0) {
|
|
||||||
// example #1 -- argument stream interface
|
|
||||||
osc::ReceivedMessageArgumentStream args = m.ArgumentStream();
|
|
||||||
bool a1;
|
|
||||||
osc::int32 a2;
|
|
||||||
float a3;
|
|
||||||
const char* a4;
|
|
||||||
args >> a1 >> a2 >> a3 >> a4 >> osc::EndMessage;
|
|
||||||
OutputDebugString(L"received '/test1' message with arguments: ... ");
|
|
||||||
//std::cout << "received '/test1' message with arguments: "
|
|
||||||
// << a1 << " " << a2 << " " << a3 << " " << a4 << "\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (std::strcmp(m.AddressPattern(), "/test2") == 0) {
|
|
||||||
// example #2 -- argument iterator interface, supports
|
|
||||||
// reflection for overloaded messages (eg you can call
|
|
||||||
// (*arg)->IsBool() to check if a bool was passed etc).
|
|
||||||
osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
|
|
||||||
//bool a1 = (arg++)->AsBool();
|
|
||||||
//int a2 = (arg++)->AsInt32();
|
|
||||||
//float a3 = (arg++)->AsFloat();
|
|
||||||
const char* a4 = (arg++)->AsString();
|
|
||||||
//if (arg != m.ArgumentsEnd())
|
|
||||||
//throw osc::ExcessArgumentException();
|
|
||||||
|
|
||||||
OutputDebugString(L"received '/test2' message with argument: ");
|
|
||||||
OutputDebugStringA(a4);
|
|
||||||
OutputDebugString(L"\r\n");
|
|
||||||
//std::cout << "received '/test2' message with arguments: "
|
|
||||||
// << a1 << " " << a2 << " " << a3 << " " << a4 << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (osc::Exception& e) {
|
catch (osc::Exception& e) {
|
||||||
// any parsing errors such as unexpected argument types, or
|
// any parsing errors such as unexpected argument types, or
|
||||||
// missing arguments get thrown as exceptions.
|
// missing arguments get thrown as exceptions.
|
||||||
OutputDebugString(L"error while parsing message: ...");
|
OutputDebugString(L"ProcessMessage: Error while parsing message: ...");
|
||||||
//std::cout << "error while parsing message: "
|
|
||||||
// << m.AddressPattern() << ": " << e.what() << "\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Definition and declaration of the OSC Listeners.
|
/* Definition and declaration of the registered OSC Listeners.
|
||||||
* Contains OSC addresses to listen to and OS message ID to send for each
|
* Contains OSC addresses to listen to and OS message ID to send for each
|
||||||
* address */
|
* address. These are populated from the AHK script! */
|
||||||
struct Listener {
|
struct Listener {
|
||||||
std::string address;
|
std::string address;
|
||||||
unsigned int dataType;
|
unsigned int dataType;
|
||||||
unsigned int message;
|
unsigned int message;
|
||||||
};
|
};
|
||||||
std::vector<Listener> listeners;
|
std::vector<Listener> listeners;
|
||||||
/* Handle to the calling window */
|
/* Handle to the calling window, also indicates if this OSC receiver is "opened" by being != NULL*/
|
||||||
HWND hwnd = NULL;
|
HWND hwnd = NULL;
|
||||||
ExamplePacketListener* examplePacketListener;
|
/* OSC receiving objects and thread.
|
||||||
|
* From within these, our handleOscMsg() function is called. */
|
||||||
|
ThePacketListener* thePacketListener;
|
||||||
UdpListeningReceiveSocket* sock;
|
UdpListeningReceiveSocket* sock;
|
||||||
|
std::thread* oscThread;
|
||||||
|
|
||||||
|
/* The OSC Thread. Has to be another thread, because
|
||||||
|
* UdpListeningReceiveSocket runs in a blocking loop. [RunUntilSigInt()]*/
|
||||||
|
void runOscThread(unsigned int port)
|
||||||
|
{
|
||||||
|
thePacketListener = new ThePacketListener;
|
||||||
|
sock = new UdpListeningReceiveSocket(
|
||||||
|
IpEndpointName(IpEndpointName::ANY_ADDRESS, port),
|
||||||
|
thePacketListener);
|
||||||
|
sock->RunUntilSigInt(); //<<--- this is the loop
|
||||||
|
|
||||||
|
//Cleanup after sock exited the loop
|
||||||
|
sock = NULL;
|
||||||
|
thePacketListener = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* DLL was loaded */
|
||||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||||
DWORD ul_reason_for_call,
|
DWORD ul_reason_for_call,
|
||||||
LPVOID lpReserved
|
LPVOID lpReserved
|
||||||
@ -85,7 +70,6 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
|||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
OutputDebugString(L"ATTACH\r\n");
|
|
||||||
break;
|
break;
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
@ -97,39 +81,53 @@ BOOL APIENTRY DllMain( HMODULE hModule,
|
|||||||
|
|
||||||
DLLEXPORT int open(HWND targetWindowHandle, unsigned int port)
|
DLLEXPORT int open(HWND targetWindowHandle, unsigned int port)
|
||||||
{
|
{
|
||||||
|
OutputDebugString(L"open()\r\n");
|
||||||
|
if (!targetWindowHandle || !port) {
|
||||||
|
if (!targetWindowHandle) OutputDebugString(L"open: targetWindowHandle!!\r\n");
|
||||||
|
if (!port) OutputDebugString(L"open: port!!\r\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Store handle to Autohotkey window globally*/
|
||||||
hwnd = targetWindowHandle;
|
hwnd = targetWindowHandle;
|
||||||
examplePacketListener = new ExamplePacketListener;
|
/*Start OSC Thread*/
|
||||||
sock = new UdpListeningReceiveSocket(
|
oscThread = new std::thread(runOscThread, port);
|
||||||
IpEndpointName(IpEndpointName::ANY_ADDRESS, port),
|
|
||||||
examplePacketListener);
|
OutputDebugString(L"open: Opened.\r\n");
|
||||||
sock->RunUntilSigInt();
|
|
||||||
OutputDebugString(L"open\r\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLEXPORT int close()
|
DLLEXPORT int close()
|
||||||
{
|
{
|
||||||
|
if (sock && sock->IsBound())
|
||||||
|
{
|
||||||
|
sock->AsynchronousBreak();
|
||||||
|
}
|
||||||
|
oscThread = NULL;
|
||||||
hwnd = NULL;
|
hwnd = NULL;
|
||||||
listeners.clear();
|
listeners.clear();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLEXPORT int addListener(std::string address_, unsigned int messageID_, unsigned int dataType_)
|
DLLEXPORT int addListener(LPCSTR address_, unsigned int messageID_, unsigned int dataType_)
|
||||||
{
|
{
|
||||||
listeners.push_back(Listener{ address_, dataType_, messageID_ });
|
OutputDebugString(L"addListener: address=");
|
||||||
|
OutputDebugStringA(address_);
|
||||||
|
OutputDebugString(L"\r\n");
|
||||||
|
listeners.push_back(Listener{ std::string(address_), dataType_, messageID_ });
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLLEXPORT int removeListener(std::string address_)
|
DLLEXPORT int removeListener(LPCSTR address_)
|
||||||
{
|
{
|
||||||
UINT result = 1;
|
UINT result = 1;
|
||||||
|
std::string addrStr(address_);
|
||||||
//All OSC addresses have to start with a '/'
|
//All OSC addresses have to start with a '/'
|
||||||
if (address_[0] != '/') address_.insert(0, "/");
|
if (addrStr[0] != '/') addrStr.insert(0, "/");
|
||||||
|
|
||||||
for (UINT i = 0; i < listeners.size(); i++)
|
for (UINT i = 0; i < listeners.size(); i++)
|
||||||
{
|
{
|
||||||
if (listeners[i].address == address_)
|
if (listeners[i].address == addrStr)
|
||||||
{
|
{
|
||||||
listeners.erase(listeners.begin() + i);
|
listeners.erase(listeners.begin() + i);
|
||||||
i--; //one step backward, what previously was i+1 is i after erase().
|
i--; //one step backward, what previously was i+1 is i after erase().
|
||||||
@ -139,11 +137,74 @@ DLLEXPORT int removeListener(std::string address_)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DLLEXPORT int handleOscMsg(const osc::ReceivedMessage& m)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
OutputDebugString(L"handleOscMsg: Address=");
|
||||||
|
OutputDebugStringA(m.AddressPattern());
|
||||||
|
OutputDebugString(L"\r\n");
|
||||||
|
|
||||||
|
if (!hwnd || !sock->IsBound())
|
||||||
|
{
|
||||||
|
OutputDebugString(L"handleOscMsg: Seems open() was not called yet...\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Loop through all registered listener entries
|
||||||
|
for (UINT i = 0; i < listeners.size(); i++)
|
||||||
|
{
|
||||||
|
//Check if incoming OSC address matches current listener entry
|
||||||
|
if (listeners[i].address.compare(m.AddressPattern()) == 0)
|
||||||
|
{
|
||||||
|
//No payload
|
||||||
|
if (m.ArgumentCount() == 0) {
|
||||||
|
if (listeners[i].dataType == OSC_TYPE_NONE || listeners[i].dataType == OSC_TYPE_ALL) {
|
||||||
|
PostMessage(hwnd, listeners[i].message, OSC_TYPE_NONE, 0);
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //Some paylad, only check first one
|
||||||
|
{
|
||||||
|
osc::ReceivedMessage::const_iterator arg = m.ArgumentsBegin();
|
||||||
|
if (arg->IsInt32()) { //Got Int, check if listener is valid for Int or All
|
||||||
|
if (listeners[i].dataType == OSC_TYPE_ALL || listeners[i].dataType == OSC_TYPE_INT) {
|
||||||
|
PostMessage(hwnd, listeners[i].message, OSC_TYPE_INT, arg->AsInt32()); //post to message queue
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (arg->IsFloat()) { //Got Float, check if listener is valid for Float or All
|
||||||
|
if (listeners[i].dataType == OSC_TYPE_ALL || listeners[i].dataType == OSC_TYPE_FLOAT) {
|
||||||
|
float floatarg = arg->AsFloat();
|
||||||
|
LPARAM lParam = *(LPARAM*)&floatarg;
|
||||||
|
PostMessage(hwnd, listeners[i].message, OSC_TYPE_FLOAT, lParam); //post to message queue
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
OutputDebugString(L"handleOscMsg: Unknown datatype\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret > 0) OutputDebugString(L"handleOscMsg: Found and posted at least once.\r\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Debugging function to test messaging. Probably will be removed later. */
|
/* Debugging function to test messaging. Probably will be removed later. */
|
||||||
DLLEXPORT int testMsg(HWND windowHandle, unsigned int messageID)
|
DLLEXPORT int testMsg(HWND windowHandle, unsigned int messageID)
|
||||||
{
|
{
|
||||||
|
OutputDebugString(L"testMsg()\r\n");
|
||||||
|
if (!windowHandle)
|
||||||
|
{
|
||||||
|
OutputDebugString(L"testMsg: windowHandle!!\r\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (PostMessage(windowHandle, messageID, 42, 43))
|
if (PostMessage(windowHandle, messageID, 42, 43))
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,16 +2,19 @@
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <osc/OscReceivedElements.h>
|
||||||
|
|
||||||
#define DLLEXPORT __declspec(dllexport)
|
#define DLLEXPORT __declspec(dllexport)
|
||||||
|
|
||||||
#define OSC_TYPE_ALL 0
|
#define OSC_TYPE_NONE 0
|
||||||
#define OSC_TYPE_INT 1
|
#define OSC_TYPE_INT 1
|
||||||
#define OSC_TYPE_FLOAT 2
|
#define OSC_TYPE_FLOAT 2
|
||||||
#define OSC_TYPE_STRING 4
|
#define OSC_TYPE_STRING 3
|
||||||
|
#define OSC_TYPE_ALL 255
|
||||||
|
|
||||||
extern "C" DLLEXPORT int open(HWND targetWindowHandle, unsigned int port);
|
extern "C" DLLEXPORT int open(HWND targetWindowHandle, unsigned int port);
|
||||||
extern "C" DLLEXPORT int close();
|
extern "C" DLLEXPORT int close();
|
||||||
extern "C" DLLEXPORT int addListener(std::string address, unsigned int messageID, unsigned int dataType = OSC_TYPE_ALL);
|
extern "C" DLLEXPORT int addListener(LPCSTR address, unsigned int messageID, unsigned int dataType = OSC_TYPE_ALL);
|
||||||
extern "C" DLLEXPORT int removeListener(std::string address);
|
extern "C" DLLEXPORT int removeListener(LPCSTR address);
|
||||||
|
extern "C" DLLEXPORT int handleOscMsg(const osc::ReceivedMessage & m);
|
||||||
extern "C" DLLEXPORT int testMsg(HWND windowHandle, unsigned int messageID);
|
extern "C" DLLEXPORT int testMsg(HWND windowHandle, unsigned int messageID);
|
||||||
|
65
msgtest.ahk
65
msgtest.ahk
@ -1,25 +1,49 @@
|
|||||||
#SingleInstance, Force
|
#SingleInstance, Force
|
||||||
SendMode Input
|
SendMode Input
|
||||||
SetWorkingDir, %A_ScriptDir%
|
SetWorkingDir, %A_ScriptDir%
|
||||||
|
Gui +LastFound
|
||||||
hWnd := WinExist()
|
hWnd := WinExist()
|
||||||
|
|
||||||
stdout := FileOpen("tmp.log", "w")
|
stdout := FileOpen("tmp.log", "w")
|
||||||
stdout.WriteLine("START")
|
stdout.WriteLine("START")
|
||||||
|
|
||||||
retOnMsg := OnMessage(0x1000, "msghandler")
|
retOnMsg := OnMessage(0x1000, "msghandler")
|
||||||
stdout.WriteLine("OnMessage:")
|
stdout.Write("OnMessage: ")
|
||||||
stdout.WriteLine(retOnMsg)
|
stdout.WriteLine(retOnMsg)
|
||||||
OnExit("exithandler")
|
OnExit("exithandler")
|
||||||
|
|
||||||
hModule := DllCall("LoadLibrary", "Str", "x64\Debug\OSC2AHK.dll", "Ptr") ; Avoids the need for DllCall() in the loop to load the library.
|
hModule := DllCall("LoadLibrary", "Str", "x64\Debug\OSC2AHK.dll", "Ptr") ; Avoids the need for DllCall() in the loop to load the library.
|
||||||
stdout.WriteLine("DLL handle:")
|
stdout.Write("DLL handle: ")
|
||||||
stdout.WriteLine(hModule)
|
stdout.WriteLine(hModule)
|
||||||
|
|
||||||
ret := DllCall("OSC2AHK.dll\testMsg", UInt,hWnd, UInt,0x1000)
|
; ret := DllCall("OSC2AHK.dll\testMsg", UInt,hWnd, UInt,0x1000)
|
||||||
stdout.WriteLine("DLL call:")
|
; stdout.WriteLine("DLL call:")
|
||||||
stdout.WriteLine(ret)
|
; stdout.WriteLine(ret)
|
||||||
|
|
||||||
DllCall("OSC2AHK.dll\open", UInt, hWnd, UInt, 7002)
|
ret3 := DllCall("OSC2AHK.dll\open", UInt, hWnd, UInt, 7002)
|
||||||
|
stdout.Write("DLL open: ")
|
||||||
|
stdout.WriteLine(ret3)
|
||||||
|
|
||||||
|
ret2 := DllCall("OSC2AHK.dll\addListener", AStr, "/test", UInt, 0x1001, UInt, 1)
|
||||||
|
retOnMsg := OnMessage(0x1001, "msghandler")
|
||||||
|
stdout.Write("DLL addListener: ")
|
||||||
|
stdout.WriteLine(ret2)
|
||||||
|
|
||||||
|
;ret3 := DllCall("OSC2AHK.dll\close")
|
||||||
|
;stdout.Write("DLL close: ")
|
||||||
|
;stdout.WriteLine(ret3)
|
||||||
|
|
||||||
|
; ret3 := DllCall("OSC2AHK.dll\open", UInt, hWnd, UInt, 7002)
|
||||||
|
; stdout.Write("DLL open: ")
|
||||||
|
; stdout.WriteLine(ret3)
|
||||||
|
|
||||||
|
DllCall("OSC2AHK.dll\addListener", AStr, "/test2", UInt, 0x1001, UInt, 1)
|
||||||
|
DllCall("OSC2AHK.dll\addListener", AStr, "/test3", UInt, 0x1002, UInt, 255)
|
||||||
|
OnMessage(0x1002, "msghandlerfloat")
|
||||||
|
DllCall("OSC2AHK.dll\removeListener", AStr, "/test2")
|
||||||
|
; retOnMsg := OnMessage(0x1001, "msghandler")
|
||||||
|
; stdout.Write("DLL addListener: ")
|
||||||
|
; stdout.WriteLine(ret2)
|
||||||
|
|
||||||
stdout.Close()
|
stdout.Close()
|
||||||
|
|
||||||
@ -27,12 +51,37 @@ return
|
|||||||
|
|
||||||
msghandler(wParam, lParam, msg, hwnd) {
|
msghandler(wParam, lParam, msg, hwnd) {
|
||||||
stdout := FileOpen("tmp.log", "a")
|
stdout := FileOpen("tmp.log", "a")
|
||||||
stdout.WriteLine("Received MSG!")
|
stdout.Write("Received MSG: ")
|
||||||
stdout.WriteLine(wParam)
|
stdout.Write(msg)
|
||||||
|
stdout.write(" ")
|
||||||
|
stdout.Write(wParam)
|
||||||
|
stdout.write(" ")
|
||||||
stdout.WriteLine(lParam)
|
stdout.WriteLine(lParam)
|
||||||
stdout.Close()
|
stdout.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msghandlerfloat(wParam, lParam, msg, hwnd) {
|
||||||
|
stdout := FileOpen("tmp.log", "a")
|
||||||
|
thefloat := NumGet(lParam, 0, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 1, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 2, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 3, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 4, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 5, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 6, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 7, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
thefloat := NumGet(lParam, 8, "Float")
|
||||||
|
stdout.WriteLine(thefloat)
|
||||||
|
}
|
||||||
|
|
||||||
exithandler() {
|
exithandler() {
|
||||||
stdout := FileOpen("tmp.log", "a")
|
stdout := FileOpen("tmp.log", "a")
|
||||||
stdout.WriteLine("The End")
|
stdout.WriteLine("The End")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user