Browse Source

Added datatype handling to ahk script (float!, closes #2). Refined OSC message handling in dll, added datatypes with constant byte width.

tags/0.1
Ludwig Frühschütz 3 years ago
parent
commit
606230d1b6
3 changed files with 157 additions and 92 deletions
  1. +78
    -29
      OSC2AHK/dllmain.cpp
  2. +14
    -5
      OSC2AHK/dllmain.h
  3. +65
    -58
      msgtest.ahk

+ 78
- 29
OSC2AHK/dllmain.cpp View File

@ -137,9 +137,30 @@ DLLEXPORT int removeListener(LPCSTR address_)
return result;
}
unsigned int getOscType(osc::ReceivedMessage::const_iterator arg)
{
if (arg->IsBlob()) return OSC_TYPE_BLOB;
if (arg->IsBool()) return OSC_TYPE_BOOL;
if (arg->IsChar()) return OSC_TYPE_CHAR;
if (arg->IsDouble()) return OSC_TYPE_FLOAT64;
if (arg->IsFloat()) return OSC_TYPE_FLOAT;
if (arg->IsInt32()) return OSC_TYPE_INT;
if (arg->IsInt64()) return OSC_TYPE_INT64;
if (arg->IsRgbaColor()) return OSC_TYPE_COLOR;
if (arg->IsString()) return OSC_TYPE_STRING;
if (arg->IsTimeTag()) return OSC_TYPE_TIMETAG;
return 0;
}
bool isMatchingOscType(unsigned int msgType, unsigned int listenerTypeField)
{
return (listenerTypeField & msgType);
}
DLLEXPORT int handleOscMsg(const osc::ReceivedMessage& m)
{
int ret = 0;
unsigned int msgType = 0;
OutputDebugString(L"handleOscMsg: Address=");
OutputDebugStringA(m.AddressPattern());
@ -155,31 +176,65 @@ DLLEXPORT int handleOscMsg(const osc::ReceivedMessage& m)
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)
if (listeners[i].address.compare(m.AddressPattern()) == 0) //TODO: Implement OSC Pattern Wildcards
{
//No payload
//Check payload type
if (m.ArgumentCount() == 0) {
if (listeners[i].dataType == OSC_TYPE_NONE || listeners[i].dataType == OSC_TYPE_ALL) {
msgType = OSC_TYPE_NONE;
}
else {
msgType = getOscType(m.ArgumentsBegin());
}
if (!msgType) return -1; //Something went wrong
//Check if listener is valid for received datatype
if (isMatchingOscType(msgType, listeners[i].dataType))
{
//Post message depending on message datatype
if (msgType == OSC_TYPE_NONE) {
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 (msgType == OSC_TYPE_INT) {
PostMessage(hwnd, listeners[i].message, OSC_TYPE_INT, m.ArgumentsBegin()->AsInt32());
ret++;
}
else if (msgType == OSC_TYPE_FLOAT) {
float floatarg = m.ArgumentsBegin()->AsFloat();
PostMessage(hwnd, listeners[i].message, OSC_TYPE_FLOAT, reinterpret_cast<int&>(floatarg));
ret++;
}
else if (msgType == OSC_TYPE_INT64) {
PostMessage(hwnd, listeners[i].message, OSC_TYPE_INT, m.ArgumentsBegin()->AsInt64());
ret++;
}
else if (msgType == OSC_TYPE_FLOAT64) {
double doublearg = m.ArgumentsBegin()->AsDouble();
PostMessage(hwnd, listeners[i].message, OSC_TYPE_FLOAT, reinterpret_cast<int&>(doublearg));
ret++;
}
else if (msgType == OSC_TYPE_BOOL) {
PostMessage(hwnd, listeners[i].message, OSC_TYPE_FLOAT, m.ArgumentsBegin()->AsBool());
ret++;
}
else if (msgType == OSC_TYPE_CHAR) {
PostMessage(hwnd, listeners[i].message, OSC_TYPE_FLOAT, m.ArgumentsBegin()->AsChar());
ret++;
}
else if (msgType == OSC_TYPE_COLOR) {
PostMessage(hwnd, listeners[i].message, OSC_TYPE_FLOAT, m.ArgumentsBegin()->AsRgbaColor());
ret++;
}
else if (msgType == OSC_TYPE_TIMETAG) {
uint64_t timearg = m.ArgumentsBegin()->AsTimeTag();
PostMessage(hwnd, listeners[i].message, OSC_TYPE_FLOAT, reinterpret_cast<int&>(timearg));
ret++;
}
else if (msgType == OSC_TYPE_STRING) {
OutputDebugString(L"handleOScMsg: String not implemented yet"); //TODO
}
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 if (msgType == OSC_TYPE_BLOB) {
OutputDebugString(L"handleOScMsg: Blob not implemented yet"); //TODO
}
else
OutputDebugString(L"handleOscMsg: Unknown datatype\r\n");
@ -195,16 +250,10 @@ DLLEXPORT int handleOscMsg(const osc::ReceivedMessage& m)
/* Debugging function to test messaging. Probably will be removed later. */
DLLEXPORT int testMsg(HWND windowHandle, unsigned int messageID)
{
OutputDebugString(L"testMsg()\r\n");
if (!windowHandle)
{
OutputDebugString(L"testMsg: windowHandle!!\r\n");
return 1;
}
float theFloat = 1.01;
int lParam = reinterpret_cast<int&>(theFloat);
if (PostMessage(windowHandle, messageID, 42, 43))
return 0;
else
return 1;
PostMessage(hwnd, 0x1002, 0, lParam); //post to message queue
return reinterpret_cast<int&>(theFloat);
}

+ 14
- 5
OSC2AHK/dllmain.h View File

@ -6,11 +6,18 @@
#define DLLEXPORT __declspec(dllexport)
#define OSC_TYPE_NONE 0
#define OSC_TYPE_INT 1
#define OSC_TYPE_FLOAT 2
#define OSC_TYPE_STRING 3
#define OSC_TYPE_ALL 255
#define OSC_TYPE_NONE 1
#define OSC_TYPE_INT 2
#define OSC_TYPE_FLOAT 4
#define OSC_TYPE_STRING 8
#define OSC_TYPE_BLOB 16
#define OSC_TYPE_INT64 32
#define OSC_TYPE_FLOAT64 64
#define OSC_TYPE_BOOL 128
#define OSC_TYPE_CHAR 256
#define OSC_TYPE_TIMETAG 512
#define OSC_TYPE_COLOR 1024
#define OSC_TYPE_ALL UINT_MAX
extern "C" DLLEXPORT int open(HWND targetWindowHandle, unsigned int port);
extern "C" DLLEXPORT int close();
@ -18,3 +25,5 @@ extern "C" DLLEXPORT int addListener(LPCSTR address, unsigned int messageID, uns
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);
bool isMatchingOscType(unsigned int msgType, unsigned int listenerTypeField);
unsigned int getOscType(osc::ReceivedMessage::const_iterator arg);

+ 65
- 58
msgtest.ahk View File

@ -4,82 +4,89 @@ SetWorkingDir, %A_ScriptDir%
Gui +LastFound
hWnd := WinExist()
; OSC datatypes. Just for better readability,
; you also just could use the numbers
global oscTypeNone := 1
global oscTypeInt := 2
global oscTypeFloat := 4
global oscTypeAll := 0xffffffff
stdout := FileOpen("tmp.log", "w")
stdout.WriteLine("START")
retOnMsg := OnMessage(0x1000, "msghandler")
stdout.Write("OnMessage: ")
stdout.WriteLine(retOnMsg)
OnExit("exithandler")
hModule := DllCall("LoadLibrary", "Str", "x64\Debug\OSC2AHK.dll", "Ptr") ; Avoids the need for DllCall() in the loop to load the library.
stdout.Write("DLL handle: ")
stdout.WriteLine(hModule)
DllCall("LoadLibrary", "Str", "x64\Debug\OSC2AHK.dll", "Ptr")
; ret := DllCall("OSC2AHK.dll\testMsg", UInt,hWnd, UInt,0x1000, int)
; ret := DllCall("OSC2AHK.dll\testMsg", UInt,hWnd, UInt,0x1000)
; stdout.WriteLine("DLL call:")
; stdout.WriteLine(ret)
OnMessage(0x1002, "msghandlerFloat")
ret3 := DllCall("OSC2AHK.dll\open", UInt, hWnd, UInt, 7002)
stdout.Write("DLL open: ")
stdout.WriteLine(ret3)
DllCall("OSC2AHK.dll\open", UInt, hWnd, UInt, 7002)
ret2 := DllCall("OSC2AHK.dll\addListener", AStr, "/test", UInt, 0x1001, UInt, 1)
retOnMsg := OnMessage(0x1001, "msghandler")
stdout.Write("DLL addListener: ")
stdout.WriteLine(ret2)
DllCall("OSC2AHK.dll\addListener", AStr, "/test1", UInt, 0x1001, UInt, oscTypeInt)
OnMessage(0x1001, "msghandlerInt")
;ret3 := DllCall("OSC2AHK.dll\close")
;stdout.Write("DLL close: ")
;stdout.WriteLine(ret3)
DllCall("OSC2AHK.dll\addListener", AStr, "/test2", UInt, 0x1002, UInt, oscTypeFloat)
OnMessage(0x1002, "msghandlerFloat")
; 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)
DllCall("OSC2AHK.dll\addListener", AStr, "/test3", UInt, 0x1003, UInt, oscTypeInt+oscTypeFloat)
OnMessage(0x1003, "msghandlerTest3")
stdout.Close()
return
msghandler(wParam, lParam, msg, hwnd) {
msghandlerTest3(wParam, lParam, msg, hwnd) {
stdout := FileOpen("tmp.log", "a")
stdout.Write("Received MSG: ")
stdout.Write("Got /test3 with ")
if (wParam = oscTypeInt)
{
stdout.Write("Int")
stdout.Write(" ")
stdout.WriteLine(lParam)
}
if (wParam = oscTypeFloat)
{
stdout.Write("Float")
stdout.Write(" ")
; Retrieve float from the lParam
VarSetCapacity(buf, 8, 0)
NumPut(lParam, buf)
theFloat := NumGet(buf, "Float")
stdout.WriteLine(theFloat)
}
stdout.Close()
}
msghandlerInt(wParam, lParam, msg, hwnd) {
; Check if we actually got a Integer
if (wParam != 2)
return
; Log to the logfile
stdout := FileOpen("tmp.log", "a")
stdout.Write("Got Int: ")
stdout.Write(msg)
stdout.write(" ")
stdout.Write(wParam)
stdout.write(" ")
stdout.Write(" ")
stdout.WriteLine(lParam)
stdout.Close()
}
msghandlerfloat(wParam, lParam, msg, hwnd) {
msghandlerFloat(wParam, lParam, msg, hwnd) {
; Check if we actually got a float
if (wParam != 4)
return
; Retrieve float from the lParam
VarSetCapacity(buf, 8, 0)
NumPut(lParam, buf)
theFloat := NumGet(buf, "Float")
; Log to the logfile
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)
stdout.Write("Got Float: ")
stdout.Write(msg)
stdout.Write(" ")
stdout.WriteLine(theFloat)
stdout.Close()
}
exithandler() {
@ -89,7 +96,7 @@ exithandler() {
}
do_exit:
ExitApp
return ; unnecessary redundancy?
ExitApp
return
Esc::GoSub, do_exit

Loading…
Cancel
Save