592 lines
18 KiB
C++
592 lines
18 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "SwarmInterface.h"
|
|
|
|
#if PLATFORM_WINDOWS
|
|
|
|
// To avoid compile problems with C++/CLI in VS11
|
|
#pragma warning(disable:4538)
|
|
#pragma warning(disable:4564)
|
|
|
|
#pragma warning(disable:4100) // unreferenced formal parameter
|
|
|
|
#include "Windows/AllowWindowsPlatformTypes.h"
|
|
|
|
// Define WIN32_LEAN_AND_MEAN to exclude rarely-used services from windows headers.
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <assert.h>
|
|
#include <metahost.h>
|
|
|
|
#include <ErrorRep.h>
|
|
#include <Werapi.h>
|
|
#include <DbgHelp.h>
|
|
|
|
#pragma comment(lib, "Faultrep.lib")
|
|
#pragma comment(lib, "wer.lib")
|
|
|
|
#pragma comment(lib, "mscoree.lib")
|
|
|
|
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
|
|
|
|
#include "Windows/HideWindowsPlatformTypes.h"
|
|
|
|
#endif // PLATFORM_WINDOWS
|
|
|
|
|
|
namespace NSwarm
|
|
{
|
|
|
|
/**
|
|
* The C++ implementation of FSwarmInterface
|
|
*/
|
|
class FSwarmInterfaceImpl : public FSwarmInterface
|
|
{
|
|
public:
|
|
FSwarmInterfaceImpl( void );
|
|
virtual ~FSwarmInterfaceImpl( void );
|
|
virtual int32 OpenConnection( FConnectionCallback CallbackFunc, void* CallbackData, TLogFlags LoggingFlags, const TCHAR* OptionsFolder );
|
|
virtual int32 CloseConnection( void );
|
|
virtual int32 SendMessage( const FMessage& Message );
|
|
virtual int32 AddChannel( const TCHAR* FullPath, const TCHAR* ChannelName );
|
|
virtual int32 TestChannel( const TCHAR* ChannelName );
|
|
virtual int32 OpenChannel( const TCHAR* ChannelName, TChannelFlags ChannelFlags );
|
|
virtual int32 CloseChannel( int32 Channel );
|
|
virtual int32 WriteChannel( int32 Channel, const void* Data, int32 DataSize );
|
|
virtual int32 ReadChannel( int32 Channel, void* Data, int32 DataSize );
|
|
virtual int32 OpenJob( const FGuid& JobGuid );
|
|
virtual int32 BeginJobSpecification( const FJobSpecification& Specification32, const FJobSpecification& Specification64 );
|
|
virtual int32 AddTask( const FTaskSpecification& Specification );
|
|
virtual int32 EndJobSpecification( void );
|
|
virtual int32 CloseJob( void );
|
|
virtual int32 Log( TVerbosityLevel Verbosity, TLogColour TextColour, const TCHAR* Message );
|
|
static bool InitSwarmInterfaceManaged(const TCHAR* SwarmInterfacePath);
|
|
};
|
|
|
|
#if !USE_LOCAL_SWARM_INTERFACE
|
|
/**
|
|
* @return The Swarm singleton
|
|
*/
|
|
FSwarmInterface* FSwarmInterface::GInstance = NULL;
|
|
|
|
bool FSwarmInterface::Initialize(const TCHAR* SwarmInterfacePath)
|
|
{
|
|
if (GInstance == NULL)
|
|
{
|
|
if (!FSwarmInterfaceImpl::InitSwarmInterfaceManaged(SwarmInterfacePath))
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
GInstance = new FSwarmInterfaceImpl();
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
FSwarmInterface& FSwarmInterface::Get( void )
|
|
{
|
|
return( *GInstance );
|
|
}
|
|
#endif
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef int32 (*SwarmOpenConnectionProc)(FConnectionCallback CallbackFunc, void* CallbackData, TLogFlags LoggingFlags, const TCHAR* OptionsFolder);
|
|
typedef int32 (*SwarmCloseConnectionProc)(void);
|
|
typedef int32 (*SwarmSendMessageProc)(const FMessage* Message);
|
|
typedef int32 (*SwarmAddChannelProc)(const TCHAR* FullPath, const TCHAR* ChannelName);
|
|
typedef int32 (*SwarmTestChannelProc)(const TCHAR* ChannelName);
|
|
typedef int32 (*SwarmOpenChannelProc)(const TCHAR* ChannelName, TChannelFlags ChannelFlags);
|
|
typedef int32 (*SwarmCloseChannelProc)(int32 Channel);
|
|
typedef int32 (*SwarmWriteChannelProc)(int32 Channel, const void* Data, int32 DataSize);
|
|
typedef int32 (*SwarmReadChannelProc)(int32 Channel, void* Data, int32 DataSize);
|
|
typedef int32 (*SwarmOpenJobProc)(const FGuid* JobGuid);
|
|
typedef int32 (*SwarmBeginJobSpecificationProc)(const FJobSpecification* Specification32, const FJobSpecification* Specification64);
|
|
typedef int32 (*SwarmAddTaskProc)(const FTaskSpecification* Specification);
|
|
typedef int32 (*SwarmEndJobSpecificationProc)(void);
|
|
typedef int32 (*SwarmCloseJobProc)(void);
|
|
typedef int32 (*SwarmLogProc)(TVerbosityLevel Verbosity, TLogColour TextColour, const TCHAR* Message);
|
|
|
|
static SwarmOpenConnectionProc SwarmOpenConnection;
|
|
static SwarmCloseConnectionProc SwarmCloseConnection;
|
|
static SwarmSendMessageProc SwarmSendMessage;
|
|
static SwarmAddChannelProc SwarmAddChannel;
|
|
static SwarmTestChannelProc SwarmTestChannel;
|
|
static SwarmOpenChannelProc SwarmOpenChannel;
|
|
static SwarmCloseChannelProc SwarmCloseChannel;
|
|
static SwarmWriteChannelProc SwarmWriteChannel;
|
|
static SwarmReadChannelProc SwarmReadChannel;
|
|
static SwarmOpenJobProc SwarmOpenJob;
|
|
static SwarmBeginJobSpecificationProc SwarmBeginJobSpecification;
|
|
static SwarmAddTaskProc SwarmAddTask;
|
|
static SwarmEndJobSpecificationProc SwarmEndJobSpecification;
|
|
static SwarmCloseJobProc SwarmCloseJob;
|
|
static SwarmLogProc SwarmLog;
|
|
|
|
extern "C" DLLEXPORT void RegisterSwarmOpenConnectionProc(SwarmOpenConnectionProc Proc) { SwarmOpenConnection = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmCloseConnectionProc(SwarmCloseConnectionProc Proc) { SwarmCloseConnection = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmSendMessageProc(SwarmSendMessageProc Proc) { SwarmSendMessage = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmAddChannelProc(SwarmAddChannelProc Proc) { SwarmAddChannel = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmTestChannelProc(SwarmTestChannelProc Proc) { SwarmTestChannel = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmOpenChannelProc(SwarmOpenChannelProc Proc) { SwarmOpenChannel = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmCloseChannelProc(SwarmCloseChannelProc Proc) { SwarmCloseChannel = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmWriteChannelProc(SwarmWriteChannelProc Proc) { SwarmWriteChannel = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmReadChannelProc(SwarmReadChannelProc Proc) { SwarmReadChannel = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmOpenJobProc(SwarmOpenJobProc Proc) { SwarmOpenJob = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmBeginJobSpecificationProc(SwarmBeginJobSpecificationProc Proc) { SwarmBeginJobSpecification = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmAddTaskProc(SwarmAddTaskProc Proc) { SwarmAddTask = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmEndJobSpecificationProc(SwarmEndJobSpecificationProc Proc) { SwarmEndJobSpecification = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmCloseJobProc(SwarmCloseJobProc Proc) { SwarmCloseJob = Proc; }
|
|
extern "C" DLLEXPORT void RegisterSwarmLogProc(SwarmLogProc Proc) { SwarmLog = Proc; }
|
|
|
|
DECLARE_LOG_CATEGORY_EXTERN(LogSwarmInterface, Verbose, All);
|
|
DEFINE_LOG_CATEGORY(LogSwarmInterface)
|
|
|
|
extern "C" DLLEXPORT void SwarmInterfaceLog(TVerbosityLevel Verbosity, const TCHAR* Message)
|
|
{
|
|
switch (Verbosity)
|
|
{
|
|
case VERBOSITY_Critical:
|
|
UE_LOG_CLINKAGE(LogSwarmInterface, Error, TEXT("%s"), Message);
|
|
break;
|
|
case VERBOSITY_Complex:
|
|
UE_LOG_CLINKAGE(LogSwarmInterface, Warning, TEXT("%s"), Message);
|
|
break;
|
|
default:
|
|
UE_LOG_CLINKAGE(LogSwarmInterface, Log, TEXT("%s"), Message);
|
|
break;
|
|
}
|
|
}
|
|
|
|
FSwarmInterfaceImpl::FSwarmInterfaceImpl( void )
|
|
{
|
|
}
|
|
|
|
FSwarmInterfaceImpl::~FSwarmInterfaceImpl( void )
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Opens a new connection to the Swarm
|
|
*
|
|
* @param CallbackFunc The callback function Swarm will use to communicate back to the Instigator
|
|
*
|
|
* @return An INT containing the error code (if < 0) or the handle (>= 0) which is useful for debugging only
|
|
*/
|
|
int32 FSwarmInterfaceImpl::OpenConnection( FConnectionCallback CallbackFunc, void* CallbackData, TLogFlags LoggingFlags, const TCHAR* OptionsFolder )
|
|
{
|
|
// CallbackFunc can be NULL
|
|
// CallbackData can be NULL
|
|
return SwarmOpenConnection(CallbackFunc, CallbackData, LoggingFlags, OptionsFolder);
|
|
}
|
|
|
|
/**
|
|
* Closes an existing connection to the Swarm
|
|
*
|
|
* @return INT error code (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::CloseConnection( void )
|
|
{
|
|
return SwarmCloseConnection();
|
|
}
|
|
|
|
/**
|
|
* Sends a message to an Agent (return messages are sent via the FConnectionCallback)
|
|
*
|
|
* @param Message The message being sent
|
|
*
|
|
* @return INT error code (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::SendMessage( const FMessage& Message )
|
|
{
|
|
return SwarmSendMessage(&Message);
|
|
}
|
|
|
|
/**
|
|
* Adds an existing file to the cache. Note, any existing channel with the same
|
|
* name will be overwritten.
|
|
*
|
|
* @param FullPath The full path name to the file that should be copied into the cache
|
|
* @param ChannelName The name of the channel once it's in the cache
|
|
*
|
|
* @return INT error code (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::AddChannel( const TCHAR* FullPath, const TCHAR* ChannelName )
|
|
{
|
|
if (FullPath == NULL)
|
|
{
|
|
return SWARM_ERROR_INVALID_ARG1;
|
|
}
|
|
|
|
if (ChannelName == NULL)
|
|
{
|
|
return SWARM_ERROR_INVALID_ARG2;
|
|
}
|
|
|
|
int32 ReturnValue = SwarmAddChannel(FullPath, ChannelName);
|
|
if (ReturnValue < 0)
|
|
{
|
|
SendMessage(FInfoMessage(TEXT("Error, fatal in AddChannel")));
|
|
}
|
|
|
|
return ReturnValue;
|
|
}
|
|
|
|
/**
|
|
* Determines if the named channel is in the cache
|
|
*
|
|
* @param ChannelName The name of the channel to look for
|
|
*
|
|
* @return INT error code (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::TestChannel( const TCHAR* ChannelName )
|
|
{
|
|
if( ChannelName == NULL )
|
|
{
|
|
return SWARM_ERROR_INVALID_ARG1;
|
|
}
|
|
|
|
int32 ReturnValue = SwarmTestChannel( ChannelName );
|
|
// Check for the one, known error code (file not found)
|
|
if( ( ReturnValue < 0 ) &&
|
|
( ReturnValue != SWARM_ERROR_FILE_FOUND_NOT ) )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT( "Error, fatal in TestChannel" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Opens a data channel for streaming data into the cache associated with an Agent
|
|
*
|
|
* @param ChannelName The name of the channel being opened
|
|
* @param ChannelFlags The mode, access, and other attributes of the channel being opened
|
|
*
|
|
* @return A handle to the opened channel (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::OpenChannel( const TCHAR* ChannelName, TChannelFlags ChannelFlags )
|
|
{
|
|
if( ChannelName == NULL )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG1 );
|
|
}
|
|
|
|
int32 ReturnValue = SwarmOpenChannel( ChannelName, ChannelFlags );
|
|
if( ReturnValue < 0 && (ChannelFlags & SWARM_CHANNEL_ACCESS_WRITE) )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT( "Error, fatal in OpenChannel" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Closes an open channel
|
|
*
|
|
* @param Channel An open channel handle, returned by OpenChannel
|
|
*
|
|
* @return INT error code (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::CloseChannel( int32 Channel )
|
|
{
|
|
if( Channel < 0 )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG1 );
|
|
}
|
|
|
|
int32 ReturnValue = SwarmCloseChannel( Channel );
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT( "Error, fatal in CloseChannel" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Writes the provided data to the open channel opened for WRITE
|
|
*
|
|
* @param Channel An open channel handle, returned by OpenChannel
|
|
* @param Data Source buffer for the write
|
|
* @param Data Size of the source buffer
|
|
*
|
|
* @return The number of bytes written (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::WriteChannel( int32 Channel, const void* Data, int32 DataSize )
|
|
{
|
|
if( Channel < 0 )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG1 );
|
|
}
|
|
|
|
if( Data == NULL )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG2 );
|
|
}
|
|
|
|
if( DataSize < 0 )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG3 );
|
|
}
|
|
|
|
int32 ReturnValue = SwarmWriteChannel( Channel, Data, DataSize );
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT( "Error, fatal in WriteChannel" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Reads data from a channel opened for READ into the provided buffer
|
|
*
|
|
* @param Channel An open channel handle, returned by OpenChannel
|
|
* @param Data Destination buffer for the read
|
|
* @param Data Size of the destination buffer
|
|
*
|
|
* @return The number of bytes read (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::ReadChannel( int32 Channel, void* Data, int32 DataSize )
|
|
{
|
|
if( Channel < 0 )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG1 );
|
|
}
|
|
|
|
if( Data == NULL )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG2 );
|
|
}
|
|
|
|
if( DataSize < 0 )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG3 );
|
|
}
|
|
|
|
int32 ReturnValue = SwarmReadChannel( Channel, Data, DataSize );
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT( "Error, fatal in ReadChannel" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Opens a Job session, which allows a Job to be specified, Tasks added, Job
|
|
* channels opened and used, etc. When the Job is complete and no more Job
|
|
* related data is needed from the Swarm, call CloseJob.
|
|
*
|
|
* @param JobGuid A GUID that uniquely identifies this Job, generated by the caller
|
|
*
|
|
* @return INT Error code (< 0 is an error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::OpenJob( const FGuid& JobGuid )
|
|
{
|
|
int32 ReturnValue = SwarmOpenJob( &JobGuid );
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT(" Error, fatal in OpenJob" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Begins a Job specification, which allows a series of Tasks to be specified
|
|
* via AddTask. When Tasks are done being specified, call EndJobSpecification.
|
|
*
|
|
* The default behavior will be to execute the Job executable with the
|
|
* specified parameters. If Tasks are added for the Job, they are expected
|
|
* to be requested by the executable run for the Job. If no Tasks are added
|
|
* for the Job, it is expected that the Job executable will perform its
|
|
* operations without additional Task input from Swarm.
|
|
*
|
|
* @param Specification32 A structure describing a new 32-bit Job
|
|
* @param Specification64 A structure describing a new 64-bit Job
|
|
*
|
|
* @return INT Error code (< 0 is an error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::BeginJobSpecification( const FJobSpecification& Specification32, const FJobSpecification& Specification64 )
|
|
{
|
|
if( Specification32.ExecutableName == NULL && Specification64.ExecutableName == NULL )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG );
|
|
}
|
|
|
|
if( Specification32.Parameters == NULL && Specification64.Parameters == NULL )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG );
|
|
}
|
|
|
|
if( (Specification32.RequiredDependencyCount > 0 && Specification32.RequiredDependencies == NULL) ||
|
|
(Specification32.OptionalDependencyCount > 0 && Specification32.OptionalDependencies == NULL) ||
|
|
(Specification64.RequiredDependencyCount > 0 && Specification64.RequiredDependencies == NULL) ||
|
|
(Specification64.OptionalDependencyCount > 0 && Specification64.OptionalDependencies == NULL) )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG );
|
|
}
|
|
|
|
int32 ReturnValue = SwarmBeginJobSpecification( &Specification32, &Specification64 );
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT("Error, fatal in BeginJobSpecification" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Adds a Task to the current Job
|
|
*
|
|
* @param Specification A structure describing the new Task
|
|
*
|
|
* @return INT Error code (< 0 is an error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::AddTask( const FTaskSpecification& Specification )
|
|
{
|
|
if( Specification.Parameters == NULL )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG );
|
|
}
|
|
|
|
if( ( Specification.DependencyCount > 0 ) &&
|
|
( Specification.Dependencies == NULL ) )
|
|
{
|
|
return( SWARM_ERROR_INVALID_ARG );
|
|
}
|
|
|
|
int32 ReturnValue = SwarmAddTask( &Specification );
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT( "Error, fatal in AddTask" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Ends the Job specification, after which no additional Tasks may be defined. Also,
|
|
* this is generally the point when the Agent will validate and launch the Job executable,
|
|
* potentially distributing the Job to other Agents.
|
|
*
|
|
* @return INT Error code (< 0 is an error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::EndJobSpecification( void )
|
|
{
|
|
int32 ReturnValue = SwarmEndJobSpecification();
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT("Error, fatal in EndJobSpecification" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Ends the definition period of a Job
|
|
*
|
|
* @param JobGuid The GUID of the Job specification
|
|
*
|
|
* @return INT error code (< 0 is error)
|
|
*/
|
|
int32 FSwarmInterfaceImpl::CloseJob( void )
|
|
{
|
|
int32 ReturnValue = SwarmCloseJob();
|
|
if( ReturnValue < 0 )
|
|
{
|
|
SendMessage( FInfoMessage( TEXT("Error, fatal in CloseJob" ) ) );
|
|
}
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
/**
|
|
* Adds a line of text to the Agent log window
|
|
*
|
|
* @param Verbosity the importance of this message
|
|
* @param TextColour the colour of the text
|
|
* @param Message the line of text to add
|
|
*/
|
|
int32 FSwarmInterfaceImpl::Log( TVerbosityLevel Verbosity, TLogColour TextColour, const TCHAR* Message )
|
|
{
|
|
if( Message == NULL )
|
|
{
|
|
return( SWARM_ERROR_NULL_POINTER );
|
|
}
|
|
|
|
int32 ReturnValue = SwarmLog( Verbosity, TextColour, Message );
|
|
|
|
return( ReturnValue );
|
|
}
|
|
|
|
bool FSwarmInterfaceImpl::InitSwarmInterfaceManaged(const TCHAR* SwarmInterfaceDLLPath)
|
|
{
|
|
#if PLATFORM_WINDOWS
|
|
ICLRMetaHost *MetaHost = NULL;
|
|
ICLRRuntimeHost* RuntimeHost = NULL;
|
|
|
|
HRESULT Result = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&MetaHost);
|
|
|
|
if ( ensureMsgf(SUCCEEDED(Result), TEXT("Error creating the Swarm instance.") ))
|
|
{
|
|
TCHAR NetFrameworkVersion[255];
|
|
uint32 VersionLength = 255;
|
|
Result = MetaHost->GetVersionFromFile(SwarmInterfaceDLLPath, NetFrameworkVersion, (unsigned long*)&VersionLength);
|
|
if (FAILED(Result))
|
|
{
|
|
SwarmInterfaceDLLPath = TEXT("SwarmInterface.dll");
|
|
Result = MetaHost->GetVersionFromFile(SwarmInterfaceDLLPath, NetFrameworkVersion, (unsigned long*)&VersionLength);
|
|
}
|
|
|
|
if (ensureMsgf(SUCCEEDED(Result), TEXT("Invalid Swarm version.")))
|
|
{
|
|
ICLRRuntimeInfo *RuntimeInfo = NULL;
|
|
Result = MetaHost->GetRuntime(NetFrameworkVersion, IID_ICLRRuntimeInfo, (LPVOID*)&RuntimeInfo);
|
|
|
|
if (ensureMsgf(SUCCEEDED(Result), TEXT("Error requesting Swarm runtime info.")))
|
|
{
|
|
Result = RuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&RuntimeHost);
|
|
ensureMsgf( SUCCEEDED(Result), TEXT("Error requesting Swarm interface.") );
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(Result))
|
|
{
|
|
Result = RuntimeHost->Start();
|
|
ensureMsgf(SUCCEEDED(Result), TEXT("Cannot start Swarm runtime host."));
|
|
}
|
|
|
|
if (FAILED(Result))
|
|
{
|
|
ensureMsgf( false, TEXT("Error initializing Swarm interface."));
|
|
return false;
|
|
}
|
|
|
|
TCHAR SwarmInterfaceDllName[MAX_PATH];
|
|
GetModuleFileName((HINSTANCE)&__ImageBase, SwarmInterfaceDllName, MAX_PATH);
|
|
|
|
uint32 ReturnValue = 0;
|
|
Result = RuntimeHost->ExecuteInDefaultAppDomain(SwarmInterfaceDLLPath, TEXT("NSwarm.FSwarmInterface"), TEXT("InitCppBridgeCallbacks"), SwarmInterfaceDllName, (unsigned long*)&ReturnValue);
|
|
|
|
if (FAILED(Result))
|
|
{
|
|
ensureMsgf(false, TEXT("Error creating Swarm instance bridge."));
|
|
return false;
|
|
}
|
|
#endif // PLATFORM_WINDOWS
|
|
|
|
return true;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
} // namespace NSwarm
|