Added datatype handling to ahk script (float!, closes #2). Refined OSC message handling in dll, added datatypes with constant byte width.
This commit is contained in:
		
							parent
							
								
									678b0d09a4
								
							
						
					
					
						commit
						606230d1b6
					
				| @ -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 (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_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 (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); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
							
								
								
									
										123
									
								
								msgtest.ahk
									
									
									
									
									
								
							
							
						
						
									
										123
									
								
								msgtest.ahk
									
									
									
									
									
								
							| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user