Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Dragonfly is licensed under the terms of the Revised BSD License as follows:

Copyright 2006-2013, University of Pittsburgh
Copyright 2006-2020, University of Pittsburgh
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
Expand All @@ -19,4 +19,4 @@ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2 changes: 1 addition & 1 deletion lang/dot_net/Dragonfly.NET.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ namespace Dragonfly {
mod->InitVariables( ModuleID, 0);
// Convert server name string from .NET to regular C string
int NumChars = ServerName->Length;
array<Char> ^charArray = ServerName->ToCharArray( );
cli::array<Char> ^charArray = ServerName->ToCharArray( );
char server_name[1024];
if( NumChars > 1023) throw gcnew Exception( "ServerName argument is too long, 1023 is max");
for( int i = 0; i < NumChars; i++) {
Expand Down
62 changes: 31 additions & 31 deletions lang/dot_net/Serializer.NET.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ namespace Dragonfly {
TotalDataBytes = NumElements * ElementSize;
} else {
// If data is an array of objects, then get size of each element and add them up
array<Object^> ^objArray = safe_cast<array<Object^>^>( a);
cli::array<Object^> ^objArray = safe_cast<cli::array<Object^>^>( a);
for( i = 0; i < NumElements; i++) {
Element = objArray[i];
NumDataBytes = CountDataBytes( Element);
TotalDataBytes += NumDataBytes;
}
}
} else { // If data is an non-array object, then treat it as a struct and get the size of each field and add them up (non-data fields such as methods and pointers are ignored)
array<FieldInfo^> ^fieldInfo = dataType->GetFields();
cli::array<FieldInfo^> ^fieldInfo = dataType->GetFields();
NumFields = fieldInfo->Length;
for( i = 0; i < NumFields; i++) {
Type ^fieldType = fieldInfo[i]->GetType();
Expand Down Expand Up @@ -197,7 +197,7 @@ namespace Dragonfly {
case TypeCode::String: {
String ^s = safe_cast<String^>( Data);
NumElements = s->Length;
array<Char> ^charArray = s->ToCharArray( );
cli::array<Char> ^charArray = s->ToCharArray( );
char *AsciiString = (char*) pOutput;
for( int i = 0; i < NumElements; i++) {
unsigned short UnicodeChar = charArray[i];
Expand All @@ -219,15 +219,15 @@ namespace Dragonfly {
pEnd = SerializePrimitiveArray( Data, elementType, NumElements, pOutput);
} else {
// If data is an array of objects, then we copy each element by calling this function recursively
array<Object^> ^objArray = safe_cast<array<Object^>^>( a);
cli::array<Object^> ^objArray = safe_cast<cli::array<Object^>^>( a);
pEnd = pOutput;
for( i = 0; i < NumElements; i++) {
Object ^Element = objArray[i];
pEnd = SerializeData( Element, pEnd);
}
}
} else { // If data is an non-array object, then treat it as a struct and copy each field by calling this function recursively (non-data fields such as methods and pointers are ignored)
array<FieldInfo^> ^fieldInfo = dataType->GetFields();
cli::array<FieldInfo^> ^fieldInfo = dataType->GetFields();
NumFields = fieldInfo->Length;
pEnd = pOutput;
for( i = 0; i < NumFields; i++) {
Expand Down Expand Up @@ -285,18 +285,18 @@ namespace Dragonfly {
int numBytes = numElements * elementSize;
TypeCode ^typeCode = Type::GetTypeCode( primitiveType);
switch( *typeCode) {
case TypeCode::Double: {array<Double> ^source = safe_cast<array<Double>^>( Data); pin_ptr<Double> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Single: {array<Single> ^source = safe_cast<array<Single>^>( Data); pin_ptr<Single> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::SByte: {array<SByte> ^source = safe_cast<array<SByte>^>( Data); pin_ptr<SByte> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Int16: {array<Int16> ^source = safe_cast<array<Int16>^>( Data); pin_ptr<Int16> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Int32: {array<Int32> ^source = safe_cast<array<Int32>^>( Data); pin_ptr<Int32> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Int64: {array<Int64> ^source = safe_cast<array<Int64>^>( Data); pin_ptr<Int64> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Byte: {array<Byte> ^source = safe_cast<array<Byte>^>( Data); pin_ptr<Byte> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::UInt16: {array<UInt16> ^source = safe_cast<array<UInt16>^>( Data); pin_ptr<UInt16> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::UInt32: {array<UInt32> ^source = safe_cast<array<UInt32>^>( Data); pin_ptr<UInt32> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::UInt64: {array<UInt64> ^source = safe_cast<array<UInt64>^>( Data); pin_ptr<UInt64> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Boolean: {array<Boolean> ^source = safe_cast<array<Boolean>^>( Data); pin_ptr<Boolean> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Char: {array<Char> ^source = safe_cast<array<Char>^>( Data); pin_ptr<Char> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Double: {cli::array<Double> ^source = safe_cast<cli::array<Double>^>( Data); pin_ptr<Double> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Single: {cli::array<Single> ^source = safe_cast<cli::array<Single>^>( Data); pin_ptr<Single> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::SByte: {cli::array<SByte> ^source = safe_cast<cli::array<SByte>^>( Data); pin_ptr<SByte> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Int16: {cli::array<Int16> ^source = safe_cast<cli::array<Int16>^>( Data); pin_ptr<Int16> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Int32: {cli::array<Int32> ^source = safe_cast<cli::array<Int32>^>( Data); pin_ptr<Int32> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Int64: {cli::array<Int64> ^source = safe_cast<cli::array<Int64>^>( Data); pin_ptr<Int64> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Byte: {cli::array<Byte> ^source = safe_cast<cli::array<Byte>^>( Data); pin_ptr<Byte> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::UInt16: {cli::array<UInt16> ^source = safe_cast<cli::array<UInt16>^>( Data); pin_ptr<UInt16> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::UInt32: {cli::array<UInt32> ^source = safe_cast<cli::array<UInt32>^>( Data); pin_ptr<UInt32> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::UInt64: {cli::array<UInt64> ^source = safe_cast<cli::array<UInt64>^>( Data); pin_ptr<UInt64> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Boolean: {cli::array<Boolean> ^source = safe_cast<cli::array<Boolean>^>( Data); pin_ptr<Boolean> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::Char: {cli::array<Char> ^source = safe_cast<cli::array<Char>^>( Data); pin_ptr<Char> pSource = &source[0]; memcpy( pOutput, pSource, numBytes); break;}
case TypeCode::String: throw gcnew Exception( "Attempting to access array of 'String' objects as primitive array");
case TypeCode::Object: throw gcnew Exception( "Attempting to access array of 'Object' type as primitive array");
default: throw gcnew Exception( "Unsupported data type");
Expand Down Expand Up @@ -349,7 +349,7 @@ namespace Dragonfly {
pEnd = DeserializePrimitiveArray( Output, elementType, NumElements, pInput);
} else {
// If data is an array of objects, then we copy each element by calling this function recursively
array<Object^> ^%objArray = safe_cast<array<Object^>^%>( a);
cli::array<Object^> ^%objArray = safe_cast<cli::array<Object^>^%>( a);
pEnd = pInput;
for( i = 0; i < NumElements; i++) {
Object ^Element = objArray[i];
Expand All @@ -358,7 +358,7 @@ namespace Dragonfly {
}
}
} else { // If data is an non-array object, then treat it as a struct and copy each field by calling this function recursively (non-data fields such as methods and pointers are ignored)
array<FieldInfo^> ^fieldInfo = dataType->GetFields();
cli::array<FieldInfo^> ^fieldInfo = dataType->GetFields();
NumFields = fieldInfo->Length;
pEnd = pInput;
for( i = 0; i < NumFields; i++) {
Expand Down Expand Up @@ -418,18 +418,18 @@ namespace Dragonfly {
int numBytes = numElements * elementSize;
TypeCode ^typeCode = Type::GetTypeCode( primitiveType);
switch( *typeCode) {
case TypeCode::Double: {array<Double> ^output = safe_cast<array<Double>^>( Output); pin_ptr<Double> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Single: {array<Single> ^output = safe_cast<array<Single>^>( Output); pin_ptr<Single> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::SByte: {array<SByte> ^output = safe_cast<array<SByte>^>( Output); pin_ptr<SByte> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Int16: {array<Int16> ^output = safe_cast<array<Int16>^>( Output); pin_ptr<Int16> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Int32: {array<Int32> ^output = safe_cast<array<Int32>^>( Output); pin_ptr<Int32> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Int64: {array<Int64> ^output = safe_cast<array<Int64>^>( Output); pin_ptr<Int64> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Byte: {array<Byte> ^output = safe_cast<array<Byte>^>( Output); pin_ptr<Byte> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::UInt16: {array<UInt16> ^output = safe_cast<array<UInt16>^>( Output); pin_ptr<UInt16> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::UInt32: {array<UInt32> ^output = safe_cast<array<UInt32>^>( Output); pin_ptr<UInt32> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::UInt64: {array<UInt64> ^output = safe_cast<array<UInt64>^>( Output); pin_ptr<UInt64> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Boolean: {array<Boolean> ^output = safe_cast<array<Boolean>^>( Output); pin_ptr<Boolean> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Char: {array<Char> ^output = safe_cast<array<Char>^>( Output); pin_ptr<Char> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Double: {cli::array<Double> ^output = safe_cast<cli::array<Double>^>( Output); pin_ptr<Double> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Single: {cli::array<Single> ^output = safe_cast<cli::array<Single>^>( Output); pin_ptr<Single> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::SByte: {cli::array<SByte> ^output = safe_cast<cli::array<SByte>^>( Output); pin_ptr<SByte> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Int16: {cli::array<Int16> ^output = safe_cast<cli::array<Int16>^>( Output); pin_ptr<Int16> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Int32: {cli::array<Int32> ^output = safe_cast<cli::array<Int32>^>( Output); pin_ptr<Int32> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Int64: {cli::array<Int64> ^output = safe_cast<cli::array<Int64>^>( Output); pin_ptr<Int64> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Byte: {cli::array<Byte> ^output = safe_cast<cli::array<Byte>^>( Output); pin_ptr<Byte> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::UInt16: {cli::array<UInt16> ^output = safe_cast<cli::array<UInt16>^>( Output); pin_ptr<UInt16> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::UInt32: {cli::array<UInt32> ^output = safe_cast<cli::array<UInt32>^>( Output); pin_ptr<UInt32> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::UInt64: {cli::array<UInt64> ^output = safe_cast<cli::array<UInt64>^>( Output); pin_ptr<UInt64> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Boolean: {cli::array<Boolean> ^output = safe_cast<cli::array<Boolean>^>( Output); pin_ptr<Boolean> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::Char: {cli::array<Char> ^output = safe_cast<cli::array<Char>^>( Output); pin_ptr<Char> pOutput = &output[0]; memcpy( pOutput, pInput, numBytes); break;}
case TypeCode::String: throw gcnew Exception( "Attempting to access array of 'String' objects as primitive array");
case TypeCode::Object: throw gcnew Exception( "Attempting to access array of 'Object' type as primitive array");
default: throw gcnew Exception( "Unsupported data type");
Expand Down
19 changes: 19 additions & 0 deletions lang/unity/Dragonfly.Unity.Exception.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

// shared exception
#define MOD_NOT_CONNECTED -100

// Native_ConnectToMMM()
#define MOD_CONNECTED -1
#define MOD_CONNECT_FAILED -2

// Native_DisconnectFromMMM()
#define DISCONNECT_FAILED -1

// Native_ReadMessage()
#define READ_NO_MESSAGE -1
#define READ_MALLOC_FAILED -3

// Native_SendMessage()
#define SEND_MESSAGE_FAILED 0

3 changes: 3 additions & 0 deletions lang/unity/Dragonfly.Unity.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This is the main Unity DLL file.

#include "Dragonfly.Unity.h"
137 changes: 137 additions & 0 deletions lang/unity/Dragonfly.Unity.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Dragonfly.Unity.h
//
// Unity C# wrapper for the Dragonfly API
//
// Ref:
// https://www.mono-project.com/docs/advanced/pinvoke/
// https://answers.unity.com/questions/1200157/nonstatic-extern-functions-from-dll-plugin-import.html
//
// Hongwei Mao 12/21/2018
//
// Copyright (c) 2018 by Hongwei Mao, University of Pittsburgh. All rights reserved.

#pragma once
#define DllExport __declspec( dllexport )

#include "Dragonfly.h"
#include "Dragonfly.Unity.Exception.h"

//--------------------------------------------------------------------------------
// The Module class
//--------------------------------------------------------------------------------
extern "C" DllExport Dragonfly_Module* Native_Module()
{
Dragonfly_Module* mod = new Dragonfly_Module();

return mod;
}

extern "C" DllExport void Native_DestroyModule(Dragonfly_Module* mod)
{
delete mod;
}

// ConnectToMMM - Connect to the Message Manager Module, i.e. initiate communication with the Dragonfly system
// Throws exception if connection unsuccessful or if already connected
extern "C" DllExport int Native_ConnectToMMM(Dragonfly_Module* mod, MODULE_ID ModuleID, char* ServerName)
{
if (mod->IsConnected())
return MOD_CONNECTED; // already connected

mod->InitVariables(ModuleID, (short)0);

int res = mod->ConnectToMMM(ServerName, (int)0, (int)0, (int)0);

if (res == 0)
return MOD_CONNECT_FAILED;
else
return 1;
}

extern "C" DllExport int Native_DisconnectFromMMM(Dragonfly_Module* mod)
{
if (mod->IsConnected())
{
int res = mod->DisconnectFromMMM();

if (res == 0)
return DISCONNECT_FAILED;
else
return 1;
}
else
return MOD_NOT_CONNECTED;
}

// int Dragonfly_Module::IsConnected(void)
extern "C" DllExport int Native_IsConnected(Dragonfly_Module* mod)
{
return mod->IsConnected();
}

// int Dragonfly_Module::Subscribe(MSG_TYPE MessageType)
extern "C" DllExport int Native_Subscribe(Dragonfly_Module* mod, MSG_TYPE MessageType)
{
if (!mod->IsConnected())
return MOD_NOT_CONNECTED;

return mod->Subscribe(MessageType);
}

// Message ReadMessage(double timeout) in Dragonfly.NET.h
extern "C" DllExport int Native_ReadMessage(Dragonfly_Module* mod, double timeout, void*& pData, int& numBytes)
{
pData = NULL;

if (!mod->IsConnected())
return MOD_NOT_CONNECTED;

CMessage* msg = new CMessage();
int msg_type = READ_NO_MESSAGE;

int got_message = mod->ReadMessage(msg, timeout);
if (got_message)
{
// get the number of bytes of the message data
numBytes = msg->num_data_bytes;

// For messages, numBytes > 0
// For signals, numBytes = 0
if (numBytes > 0)
{
// allocate unmanaged memory to copy message data over
pData = malloc(numBytes);
if (pData == NULL)
return READ_MALLOC_FAILED;

msg->GetData(pData);
}

msg_type = msg->msg_type;
}

delete msg;

return msg_type;
}

extern "C" DllExport void Native_FreeMemory(void* pData)
{
free(pData);
}

extern "C" DllExport int Native_SendMessage(Dragonfly_Module* mod, MSG_TYPE MessageType, void* pMsg, int numBytes)
{
if (!mod->IsConnected())
return MOD_NOT_CONNECTED;

CMessage M(MessageType);
M.Set(MessageType, pMsg, numBytes);

// Send the message
if (!mod->SendMessageDF(&M))
return SEND_MESSAGE_FAILED;

return 1;
}

31 changes: 31 additions & 0 deletions lang/unity/Dragonfly.Unity.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28306.52
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dragonfly.Unity", "Dragonfly.Unity.vcxproj", "{48B7DF14-5703-4705-B4F8-44A888734B58}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{48B7DF14-5703-4705-B4F8-44A888734B58}.Debug|x64.ActiveCfg = Debug|x64
{48B7DF14-5703-4705-B4F8-44A888734B58}.Debug|x64.Build.0 = Debug|x64
{48B7DF14-5703-4705-B4F8-44A888734B58}.Debug|x86.ActiveCfg = Debug|Win32
{48B7DF14-5703-4705-B4F8-44A888734B58}.Debug|x86.Build.0 = Debug|Win32
{48B7DF14-5703-4705-B4F8-44A888734B58}.Release|x64.ActiveCfg = Release|x64
{48B7DF14-5703-4705-B4F8-44A888734B58}.Release|x64.Build.0 = Release|x64
{48B7DF14-5703-4705-B4F8-44A888734B58}.Release|x86.ActiveCfg = Release|Win32
{48B7DF14-5703-4705-B4F8-44A888734B58}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8E570514-60F7-4EE2-9E5B-BE30D70AF3F8}
EndGlobalSection
EndGlobal
Loading