uid issue
This commit is contained in:
40
responserules/responserules_cli/AssemblyInfo.cpp
Normal file
40
responserules/responserules_cli/AssemblyInfo.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
using namespace System;
|
||||
using namespace System::Reflection;
|
||||
using namespace System::Runtime::CompilerServices;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
using namespace System::Security::Permissions;
|
||||
|
||||
//
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
//
|
||||
[assembly:AssemblyTitleAttribute("responserules_cli")];
|
||||
[assembly:AssemblyDescriptionAttribute("")];
|
||||
[assembly:AssemblyConfigurationAttribute("")];
|
||||
[assembly:AssemblyCompanyAttribute("Valve")];
|
||||
[assembly:AssemblyProductAttribute("responserules_cli")];
|
||||
[assembly:AssemblyCopyrightAttribute("Copyright (c) Valve 2009")];
|
||||
[assembly:AssemblyTrademarkAttribute("")];
|
||||
[assembly:AssemblyCultureAttribute("")];
|
||||
|
||||
//
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the value or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly:AssemblyVersionAttribute("1.0.*")];
|
||||
|
||||
[assembly:ComVisible(false)];
|
||||
|
||||
[assembly:CLSCompliantAttribute(true)];
|
||||
|
||||
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
|
31
responserules/responserules_cli/ReadMe.txt
Normal file
31
responserules/responserules_cli/ReadMe.txt
Normal file
@ -0,0 +1,31 @@
|
||||
========================================================================
|
||||
DYNAMIC LINK LIBRARY : responserules_cli Project Overview
|
||||
========================================================================
|
||||
|
||||
AppWizard has created this responserules_cli DLL for you.
|
||||
|
||||
This file contains a summary of what you will find in each of the files that
|
||||
make up your responserules_cli application.
|
||||
|
||||
responserules_cli.vcproj
|
||||
This is the main project file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the version of Visual C++ that generated the file, and
|
||||
information about the platforms, configurations, and project features selected with the
|
||||
Application Wizard.
|
||||
|
||||
responserules_cli.cpp
|
||||
This is the main DLL source file.
|
||||
|
||||
responserules_cli.h
|
||||
This file contains a class declaration.
|
||||
|
||||
AssemblyInfo.cpp
|
||||
Contains custom attributes for modifying assembly metadata.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other notes:
|
||||
|
||||
AppWizard uses "TODO:" to indicate parts of the source code you
|
||||
should add to or customize.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
5
responserules/responserules_cli/Stdafx.cpp
Normal file
5
responserules/responserules_cli/Stdafx.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// responserules_cli.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
56
responserules/responserules_cli/Stdafx.h
Normal file
56
responserules/responserules_cli/Stdafx.h
Normal file
@ -0,0 +1,56 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#pragma once
|
||||
|
||||
// temporarily make unicode go away as we deal with Valve types
|
||||
#ifdef _UNICODE
|
||||
#define PUT_UNICODE_BACK
|
||||
#undef _UNICODE
|
||||
#endif
|
||||
|
||||
#if _MANAGED
|
||||
#pragma unmanaged
|
||||
#undef FASTCALL
|
||||
#define FASTCALL
|
||||
#endif
|
||||
#include "platform.h"
|
||||
#include "wchartypes.h"
|
||||
#include <ctype.h>
|
||||
struct datamap_t;
|
||||
template <typename T> datamap_t *DataMapInit(T *);
|
||||
|
||||
#include "responserules/response_types.h"
|
||||
#include "../../responserules/runtime/response_types_internal.h"
|
||||
#include "response_system.h"
|
||||
|
||||
|
||||
#ifdef PUT_UNICODE_BACK
|
||||
#define _UNICODE
|
||||
#undef PUT_UNICODE_BACK
|
||||
#endif
|
||||
|
||||
#if _MANAGED
|
||||
/// implicitly converts a unicode CLR String^
|
||||
/// to a C string. The pointer returned should
|
||||
/// not be stored; it is valid only so long as
|
||||
/// this class exists.
|
||||
using namespace System;
|
||||
class StrToAnsi
|
||||
{
|
||||
|
||||
public:
|
||||
StrToAnsi( String ^unicodestr );
|
||||
~StrToAnsi( );
|
||||
operator TCHAR *() const;
|
||||
|
||||
private:
|
||||
TCHAR *m_pStr;
|
||||
};
|
||||
#pragma managed
|
||||
#undef FASTCALL
|
||||
#define FASTCALL __fastcall
|
||||
#include "cli_appsystem_thunk.h"
|
||||
#include "responserules_cli.h"
|
||||
#endif
|
BIN
responserules/responserules_cli/app.ico
Normal file
BIN
responserules/responserules_cli/app.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
63
responserules/responserules_cli/app.rc
Normal file
63
responserules/responserules_cli/app.rc
Normal file
@ -0,0 +1,63 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon placed first or with lowest ID value becomes application icon
|
||||
|
||||
LANGUAGE 9, 1
|
||||
#pragma code_page(1252)
|
||||
1 ICON "app.ico"
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
"\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
65
responserules/responserules_cli/cli_appsystem_adapter.h
Normal file
65
responserules/responserules_cli/cli_appsystem_adapter.h
Normal file
@ -0,0 +1,65 @@
|
||||
/// The local implementation of an AppSystem for this project
|
||||
|
||||
#ifndef CLI_APPSYSTEM_ADAPTER_H
|
||||
#define CLI_APPSYSTEM_ADAPTER_H
|
||||
|
||||
#include "appframework/appframework.h"
|
||||
#include "filesystem.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "icommandline.h"
|
||||
|
||||
// if you don't use the proper AppSystem to make a filesystem connection:
|
||||
// #define TIER2_USE_INIT_DEFAULT_FILESYSTEM 1
|
||||
|
||||
/// A singleton class used to set up all the DLL interfaces.
|
||||
/// EXTREMELY IMPORTANT: This class must exist in unmanaged code.
|
||||
//#pragma unmanaged
|
||||
class IFileSystem;
|
||||
class IUniformRandomStream;
|
||||
class ICommandLine;
|
||||
class CCLIAppSystemAdapter : public CAppSystemGroup // , public ResponseRules_CLI::ICLI_AppSystem_Adapter
|
||||
{
|
||||
//// UNMANAGED:
|
||||
private:
|
||||
virtual bool Create();
|
||||
virtual bool PreInit();
|
||||
virtual int Main() { return 0; } ///< never used, cannot be used
|
||||
virtual void PostShutdown() {Wipe(true);} ///< does it leak?
|
||||
virtual void Destroy() {};
|
||||
|
||||
void Wipe( bool bPerformDelete );
|
||||
|
||||
IUniformRandomStream *m_pLocalRandomStream;
|
||||
#if TIER2_USE_INIT_DEFAULT_FILESYSTEM
|
||||
#else
|
||||
IFileSystem *m_pFilesystem;
|
||||
#endif
|
||||
|
||||
// IUniformRandomStream *m_pRandomstream;
|
||||
// ICommandLine *m_pCommandline;
|
||||
|
||||
public:
|
||||
CCLIAppSystemAdapter();
|
||||
virtual ~CCLIAppSystemAdapter();
|
||||
void SetupFileSystem( ) ;
|
||||
/// Make the "LOCAL" filesystem directory point at the given path.
|
||||
void AddFileSystemRoot( const char *pPath ) ;
|
||||
|
||||
IFileSystem * GetFilesytem();
|
||||
IUniformRandomStream * GetRandomStream();
|
||||
ICommandLine * GetCommandLine();
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline IUniformRandomStream * CCLIAppSystemAdapter::GetRandomStream()
|
||||
{
|
||||
return m_pLocalRandomStream;
|
||||
}
|
||||
inline ICommandLine * CCLIAppSystemAdapter::GetCommandLine()
|
||||
{
|
||||
return CommandLine();
|
||||
}
|
||||
|
||||
|
||||
#endif
|
47
responserules/responserules_cli/cli_appsystem_thunk.cpp
Normal file
47
responserules/responserules_cli/cli_appsystem_thunk.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/// These functions define the MANAGED interface. This file has /CLR.
|
||||
///
|
||||
/// Defines an interface which may be called from the MANAGED code's
|
||||
/// main function to start up (connect) and shut down (disconnect)
|
||||
/// the app system interface.
|
||||
|
||||
/// This class is a singleton. It gets manufactured explicitly
|
||||
/// from the Manufacture() call, which is a factory function that
|
||||
/// your app must implement in a non-/CLR file it will presumably
|
||||
/// return your custom type of CCLI_AppSystem_Adapter_Unmanaged).
|
||||
/// Calling Startup() will connect the app system and
|
||||
/// Shutdown() will disconnect it.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#pragma unmanaged
|
||||
#include "cli_appsystem_unmanaged_wrapper.h"
|
||||
#pragma managed
|
||||
|
||||
|
||||
// Allocate the native object on the C++ Heap via a constructor
|
||||
ManagedAppSystem::AppSystemWrapper::AppSystemWrapper()
|
||||
{
|
||||
m_Impl = new AppSystemWrapper_Unmanaged( StrToAnsi(Environment::CommandLine) );
|
||||
}
|
||||
|
||||
ManagedAppSystem::AppSystemWrapper::~AppSystemWrapper()
|
||||
{
|
||||
delete m_Impl;
|
||||
m_Impl = NULL;
|
||||
}
|
||||
|
||||
// Deallocate the native object on the finalizer just in case no destructor is called
|
||||
ManagedAppSystem::AppSystemWrapper::!AppSystemWrapper()
|
||||
{
|
||||
delete m_Impl;
|
||||
m_Impl = NULL;
|
||||
}
|
||||
|
||||
#pragma unmanaged
|
||||
#include "cli_appsystem_adapter.h"
|
||||
#pragma managed
|
||||
|
||||
void ManagedAppSystem::AppSystemWrapper::SetFileSystemSearchRoot( String ^path )
|
||||
{
|
||||
m_Impl->Get()->AddFileSystemRoot( StrToAnsi(path) );
|
||||
}
|
53
responserules/responserules_cli/cli_appsystem_thunk.h
Normal file
53
responserules/responserules_cli/cli_appsystem_thunk.h
Normal file
@ -0,0 +1,53 @@
|
||||
/// Defines an interface which may be called from the MANAGED code's
|
||||
/// main function to start up (connect) and shut down (disconnect)
|
||||
/// the app system interface.
|
||||
|
||||
/// This class is a singleton. It gets manufactured explicitly
|
||||
/// from the Manufacture() call, which is a factory function that
|
||||
/// your app must implement in a non-/CLR file it will presumably
|
||||
/// return your custom type of CCLI_AppSystem_Adapter_Unmanaged).
|
||||
/// Calling Startup() will connect the app system and
|
||||
/// Shutdown() will disconnect it.
|
||||
///
|
||||
/// This shim is necessary to hide the CAppSystemGroup header from the
|
||||
/// CLI compiler, because it'll freak out if it has to include it.
|
||||
///
|
||||
///
|
||||
/// Placed here so that can be instanced from the app's main loop
|
||||
/// after the dll loads; this workaround obviates having to write a
|
||||
/// DLLMain() which might cause a loader-lock.
|
||||
/// see: http://msdn.microsoft.com/en-us/library/ms173266(vs.80).aspx
|
||||
#ifndef CLI_APPSYSTEM_THUNK_H
|
||||
#define CLI_APPSYSTEM_THUNK_H
|
||||
#pragma once
|
||||
|
||||
class AppSystemWrapper_Unmanaged;
|
||||
|
||||
namespace ManagedAppSystem
|
||||
{
|
||||
public ref class AppSystemWrapper
|
||||
{
|
||||
public:
|
||||
// Allocate the native object on the C++ Heap via a constructor
|
||||
AppSystemWrapper() ; // : m_Impl( new UnmanagedClass ) {}
|
||||
|
||||
// Deallocate the native object on a destructor
|
||||
~AppSystemWrapper();
|
||||
|
||||
/// Set the "LOCAL" search path for the file system.
|
||||
void SetFileSystemSearchRoot( String ^path );
|
||||
|
||||
protected:
|
||||
// Deallocate the native object on the finalizer just in case no destructor is called
|
||||
!AppSystemWrapper();
|
||||
|
||||
private:
|
||||
AppSystemWrapper_Unmanaged * m_Impl;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,164 @@
|
||||
/// The unmanaged side of wrapping the app system for CLR
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "cli_appsystem_unmanaged_wrapper.h"
|
||||
#include "cli_appsystem_adapter.h"
|
||||
|
||||
|
||||
// temporarily make unicode go away as we deal with Valve types
|
||||
#ifdef _UNICODE
|
||||
#define PUT_UNICODE_BACK
|
||||
#undef _UNICODE
|
||||
#endif
|
||||
|
||||
#include "filesystem_helpers.h"
|
||||
#include "utils\common\filesystem_tools.h"
|
||||
|
||||
|
||||
#ifdef PUT_UNICODE_BACK
|
||||
#define _UNICODE
|
||||
#undef PUT_UNICODE_BACK
|
||||
#endif
|
||||
|
||||
inline void CCLIAppSystemAdapter::Wipe( bool bPerformDelete )
|
||||
{
|
||||
if ( bPerformDelete )
|
||||
{
|
||||
delete m_pLocalRandomStream;
|
||||
}
|
||||
m_pFilesystem = NULL;
|
||||
m_pLocalRandomStream = NULL;
|
||||
// m_pCommandline = NULL;
|
||||
}
|
||||
|
||||
CCLIAppSystemAdapter::CCLIAppSystemAdapter()
|
||||
{
|
||||
Wipe( false );
|
||||
}
|
||||
|
||||
|
||||
CCLIAppSystemAdapter::~CCLIAppSystemAdapter()
|
||||
{
|
||||
Wipe( true );
|
||||
g_pFullFileSystem = NULL;
|
||||
}
|
||||
|
||||
bool CCLIAppSystemAdapter::Create()
|
||||
{
|
||||
AppSystemInfo_t appSystems[] =
|
||||
{
|
||||
{ "filesystem_stdio.dll", FILESYSTEM_INTERFACE_VERSION },
|
||||
{ "", "" } // Required to terminate the list
|
||||
};
|
||||
return AddSystems( appSystems );
|
||||
}
|
||||
|
||||
bool CCLIAppSystemAdapter::PreInit( )
|
||||
{
|
||||
CreateInterfaceFn factory = GetFactory();
|
||||
#if TIER2_USE_INIT_DEFAULT_FILESYSTEM
|
||||
#else
|
||||
m_pFilesystem = (IFileSystem*)factory(FILESYSTEM_INTERFACE_VERSION,NULL );
|
||||
#endif
|
||||
|
||||
// m_pCommandline = CommandLine();
|
||||
m_pLocalRandomStream = new CUniformRandomStream();
|
||||
// GetCommandLine()->AppendParm("rreditor.exe","");
|
||||
// GetCommandLine()->AppendParm("-noasync","1");
|
||||
|
||||
#if TIER2_USE_INIT_DEFAULT_FILESYSTEM
|
||||
return true;
|
||||
#else
|
||||
return ( m_pFilesystem != NULL );
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void CCLIAppSystemAdapter::SetupFileSystem( )
|
||||
{
|
||||
g_pFullFileSystem = m_pFilesystem;
|
||||
|
||||
g_pFullFileSystem->RemoveAllSearchPaths();
|
||||
g_pFullFileSystem->AddSearchPath( "", "LOCAL", PATH_ADD_TO_HEAD );
|
||||
g_pFullFileSystem->AddSearchPath( "", "DEFAULT_WRITE_PATH", PATH_ADD_TO_HEAD );
|
||||
|
||||
#if TIER2_USE_INIT_DEFAULT_FILESYSTEM
|
||||
InitDefaultFileSystem();
|
||||
#endif
|
||||
FileSystem_Init( "./", 0, FS_INIT_COMPATIBILITY_MODE, true );
|
||||
// m_pFilesystem->AddSearchPath( "./", "GAME", PATH_ADD_TO_HEAD );
|
||||
}
|
||||
|
||||
void CCLIAppSystemAdapter::AddFileSystemRoot( const char *pPath )
|
||||
{
|
||||
g_pFullFileSystem->AddSearchPath( pPath, "LOCAL", PATH_ADD_TO_HEAD );
|
||||
g_pFullFileSystem->AddSearchPath( pPath, "GAME", PATH_ADD_TO_HEAD );
|
||||
}
|
||||
|
||||
|
||||
IFileSystem * CCLIAppSystemAdapter::GetFilesytem()
|
||||
{
|
||||
#if TIER2_USE_INIT_DEFAULT_FILESYSTEM
|
||||
return g_pFullFileSystem;
|
||||
#else
|
||||
return m_pFilesystem;
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// | unmanaged-code implementations for the AppSystemWrapper |
|
||||
// -----------------------------------------------------------
|
||||
|
||||
CCLIAppSystemAdapter * AppSystemWrapper_Unmanaged::sm_pAppSystemSingleton = NULL;
|
||||
int AppSystemWrapper_Unmanaged::sm_nSingletonReferences = 0;
|
||||
|
||||
|
||||
AppSystemWrapper_Unmanaged::AppSystemWrapper_Unmanaged( const char *pCommandLine )
|
||||
{
|
||||
if ( sm_pAppSystemSingleton != NULL )
|
||||
{
|
||||
Assert( sm_nSingletonReferences > 0 );
|
||||
sm_nSingletonReferences++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( sm_nSingletonReferences == 0 );
|
||||
sm_pAppSystemSingleton = new CCLIAppSystemAdapter();
|
||||
sm_nSingletonReferences = 1;
|
||||
InitializeAppSystem( sm_pAppSystemSingleton, pCommandLine );
|
||||
}
|
||||
}
|
||||
|
||||
AppSystemWrapper_Unmanaged::~AppSystemWrapper_Unmanaged()
|
||||
{
|
||||
if ( sm_nSingletonReferences > 1 )
|
||||
{
|
||||
sm_nSingletonReferences--;
|
||||
}
|
||||
else if ( sm_nSingletonReferences == 1 )
|
||||
{
|
||||
TerminateAppSystem( sm_pAppSystemSingleton );
|
||||
delete sm_pAppSystemSingleton;
|
||||
sm_pAppSystemSingleton = NULL;
|
||||
sm_nSingletonReferences = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( sm_pAppSystemSingleton == NULL && sm_nSingletonReferences == 0 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppSystemWrapper_Unmanaged::InitializeAppSystem( CCLIAppSystemAdapter * pAppSys, const char *pCommandLine )
|
||||
{
|
||||
pAppSys->GetCommandLine()->CreateCmdLine( pCommandLine );
|
||||
pAppSys->Startup();
|
||||
pAppSys->SetupFileSystem();
|
||||
}
|
||||
|
||||
void AppSystemWrapper_Unmanaged::TerminateAppSystem( CCLIAppSystemAdapter * pAppSys )
|
||||
{
|
||||
pAppSys->Shutdown();
|
||||
}
|
||||
|
@ -0,0 +1,38 @@
|
||||
/// The unmanaged side of wrapping the app system for CLR
|
||||
|
||||
#ifndef CLI_APPSYSTEM_UNMANAGED_WRAPPER_H
|
||||
#define CLI_APPSYSTEM_UNMANAGED_WRAPPER_H
|
||||
|
||||
|
||||
class CCLIAppSystemAdapter;
|
||||
|
||||
/// This is actually a manually implemented refcounter on
|
||||
/// a singleton instance, so that construction causes it to
|
||||
/// be initialized if necessary and destruction refcounts
|
||||
/// before NULLing the static global.
|
||||
class AppSystemWrapper_Unmanaged
|
||||
{
|
||||
public:
|
||||
AppSystemWrapper_Unmanaged( const char *pCommandLine );
|
||||
virtual ~AppSystemWrapper_Unmanaged();
|
||||
|
||||
|
||||
inline int CountRefs( void ) const { return sm_nSingletonReferences; };
|
||||
inline CCLIAppSystemAdapter *operator *() const { return sm_pAppSystemSingleton; }
|
||||
inline operator CCLIAppSystemAdapter *() const { return sm_pAppSystemSingleton; }
|
||||
inline static CCLIAppSystemAdapter *Get() { return sm_pAppSystemSingleton; }
|
||||
|
||||
protected:
|
||||
void InitializeAppSystem( CCLIAppSystemAdapter * pAppSys, const char *pCommandLine ) ;
|
||||
void TerminateAppSystem( CCLIAppSystemAdapter * pAppSys ) ;
|
||||
|
||||
private:
|
||||
static CCLIAppSystemAdapter *sm_pAppSystemSingleton;
|
||||
static int sm_nSingletonReferences;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
265
responserules/responserules_cli/engine_emulator.cpp
Normal file
265
responserules/responserules_cli/engine_emulator.cpp
Normal file
@ -0,0 +1,265 @@
|
||||
// This contains stubs that emulate the HL2 engine for places where
|
||||
// the response rules expect to find it.
|
||||
|
||||
// temporarily make unicode go away as we deal with Valve types
|
||||
#ifdef _UNICODE
|
||||
#define PUT_UNICODE_BACK
|
||||
#undef _UNICODE
|
||||
#endif
|
||||
|
||||
#include "platform.h"
|
||||
#include "wchartypes.h"
|
||||
#include <ctype.h>
|
||||
struct datamap_t;
|
||||
template <typename T> datamap_t *DataMapInit(T *);
|
||||
|
||||
#include "appframework/appframework.h"
|
||||
#include "filesystem.h"
|
||||
#include "vstdlib/random.h"
|
||||
#include "icommandline.h"
|
||||
|
||||
#include "responserules/response_types.h"
|
||||
#include "../../responserules/runtime/response_types_internal.h"
|
||||
#include "response_system.h"
|
||||
|
||||
#include "cli_appsystem_unmanaged_wrapper.h"
|
||||
#include "cli_appsystem_adapter.h"
|
||||
|
||||
#include "characterset.h"
|
||||
|
||||
#ifdef PUT_UNICODE_BACK
|
||||
#define _UNICODE
|
||||
#undef PUT_UNICODE_BACK
|
||||
#endif
|
||||
|
||||
|
||||
class CLI_SourceEngineEmulator;
|
||||
|
||||
const char *COM_Parse (const char *data);
|
||||
byte *UTIL_LoadFileForMe( const char *filename, int *pLength, IFileSystem *filesystem );
|
||||
|
||||
int TestRandomNumberGeneration( int bottom, int top )
|
||||
{
|
||||
return ResponseRules::IEngineEmulator::Get()->GetRandomStream()->RandomInt(bottom,top);
|
||||
}
|
||||
|
||||
const char *TestFileSystemHook( )
|
||||
{
|
||||
// return ResponseRules::IEngineEmulator::Get()->GetFilesystem() ? "present" : "absent" ;
|
||||
return ResponseRules::IEngineEmulator::Get()->GetFilesystem()->IsSteam() ? "steam" : "not steam";
|
||||
}
|
||||
|
||||
|
||||
class CLI_SourceEngineEmulator : public ResponseRules::IEngineEmulator
|
||||
{
|
||||
public:
|
||||
/// Given an input text buffer data pointer, parses a single token into the variable token and returns the new
|
||||
/// reading position
|
||||
virtual const char *ParseFile( const char *data, char *token, int maxlen );
|
||||
|
||||
/// Return a pointer to an IFileSystem we can use to read and process scripts.
|
||||
virtual IFileSystem *GetFilesystem();
|
||||
|
||||
/// Return a pointer to an instance of an IUniformRandomStream
|
||||
virtual IUniformRandomStream *GetRandomStream() ;
|
||||
|
||||
/// Return a pointer to a tier0 ICommandLine
|
||||
virtual ICommandLine *GetCommandLine();
|
||||
|
||||
/// Emulates the server's UTIL_LoadFileForMe
|
||||
virtual byte *LoadFileForMe( const char *filename, int *pLength );
|
||||
|
||||
/// Emulates the server's UTIL_FreeFile
|
||||
virtual void FreeFile( byte *buffer );
|
||||
|
||||
CLI_SourceEngineEmulator();
|
||||
virtual ~CLI_SourceEngineEmulator();
|
||||
|
||||
void LocalInit();
|
||||
// protected:
|
||||
};
|
||||
|
||||
CLI_SourceEngineEmulator g_EngineEmulator;
|
||||
|
||||
|
||||
CLI_SourceEngineEmulator::CLI_SourceEngineEmulator()
|
||||
{
|
||||
LocalInit();
|
||||
}
|
||||
|
||||
CLI_SourceEngineEmulator::~CLI_SourceEngineEmulator()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ResponseRules::IEngineEmulator *ResponseRules::IEngineEmulator::s_pSingleton = &g_EngineEmulator;
|
||||
|
||||
/// Return a pointer to an IFileSystem we can use to read and process scripts.
|
||||
IFileSystem *CLI_SourceEngineEmulator::GetFilesystem()
|
||||
{
|
||||
return AppSystemWrapper_Unmanaged::Get()->GetFilesytem();
|
||||
}
|
||||
|
||||
/// Return a pointer to an instance of an IUniformRandomStream
|
||||
IUniformRandomStream *CLI_SourceEngineEmulator::GetRandomStream()
|
||||
{
|
||||
return AppSystemWrapper_Unmanaged::Get()->GetRandomStream();
|
||||
}
|
||||
|
||||
/// Return a pointer to a tier0 ICommandLine
|
||||
ICommandLine *CLI_SourceEngineEmulator::GetCommandLine()
|
||||
{
|
||||
return AppSystemWrapper_Unmanaged::Get()->GetCommandLine();
|
||||
}
|
||||
|
||||
|
||||
/// Emulates the server's UTIL_LoadFileForMe
|
||||
byte *CLI_SourceEngineEmulator::LoadFileForMe( const char *filename, int *pLength )
|
||||
{
|
||||
return UTIL_LoadFileForMe( filename, pLength, GetFilesystem() );
|
||||
}
|
||||
|
||||
/// Emulates the server's UTIL_FreeFile
|
||||
void CLI_SourceEngineEmulator::FreeFile( byte *buffer )
|
||||
{
|
||||
GetFilesystem()->FreeOptimalReadBuffer( buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
===================================
|
||||
STUFF COPIED FROM SOURCE ENGINE
|
||||
===================================
|
||||
*/
|
||||
|
||||
|
||||
// wordbreak parsing set
|
||||
static characterset_t g_BreakSet, g_BreakSetIncludingColons;
|
||||
bool com_ignorecolons = false;
|
||||
#define COM_TOKEN_MAX_LENGTH 1024
|
||||
char com_token[COM_TOKEN_MAX_LENGTH] = {0} ;
|
||||
|
||||
|
||||
|
||||
/// Given an input text buffer data pointer, parses a single token into the variable token and returns the new
|
||||
/// reading position
|
||||
const char *CLI_SourceEngineEmulator::ParseFile( const char *data, char *token, int maxlen )
|
||||
{
|
||||
Assert( data );
|
||||
|
||||
const char *return_data = COM_Parse(data);
|
||||
Q_strncpy(token, com_token, maxlen);
|
||||
return return_data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
COM_Parse (from Quake engine)
|
||||
|
||||
Parse a token out of a string
|
||||
==============
|
||||
*/
|
||||
static
|
||||
const char *COM_Parse (const char *data)
|
||||
{
|
||||
unsigned char c;
|
||||
int len;
|
||||
characterset_t *breaks;
|
||||
|
||||
breaks = &g_BreakSetIncludingColons;
|
||||
if ( com_ignorecolons )
|
||||
breaks = &g_BreakSet;
|
||||
|
||||
len = 0;
|
||||
com_token[0] = 0;
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
// skip whitespace
|
||||
skipwhite:
|
||||
while ( (c = *data) <= ' ')
|
||||
{
|
||||
if (c == 0)
|
||||
return NULL; // end of file;
|
||||
data++;
|
||||
}
|
||||
|
||||
// skip // comments
|
||||
if (c=='/' && data[1] == '/')
|
||||
{
|
||||
while (*data && *data != '\n')
|
||||
data++;
|
||||
goto skipwhite;
|
||||
}
|
||||
|
||||
|
||||
// handle quoted strings specially
|
||||
if (c == '\"')
|
||||
{
|
||||
data++;
|
||||
while (1)
|
||||
{
|
||||
c = *data++;
|
||||
if (c=='\"' || !c)
|
||||
{
|
||||
com_token[len] = 0;
|
||||
return data;
|
||||
}
|
||||
com_token[len] = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
// parse single characters
|
||||
if ( IN_CHARACTERSET( *breaks, c ) )
|
||||
{
|
||||
com_token[len] = c;
|
||||
len++;
|
||||
com_token[len] = 0;
|
||||
return data+1;
|
||||
}
|
||||
|
||||
// parse a regular word
|
||||
do
|
||||
{
|
||||
com_token[len] = c;
|
||||
data++;
|
||||
len++;
|
||||
c = *data;
|
||||
if ( IN_CHARACTERSET( *breaks, c ) )
|
||||
break;
|
||||
} while (c>32);
|
||||
|
||||
com_token[len] = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : *filename -
|
||||
// *pLength -
|
||||
// Output : byte
|
||||
//-----------------------------------------------------------------------------
|
||||
static byte *UTIL_LoadFileForMe( const char *filename, int *pLength, IFileSystem *filesystem )
|
||||
{
|
||||
void *buffer = NULL;
|
||||
|
||||
int length = filesystem->ReadFileEx( filename, "GAME", &buffer, true, true );
|
||||
|
||||
if ( pLength )
|
||||
{
|
||||
*pLength = length;
|
||||
}
|
||||
|
||||
return (byte *)buffer;
|
||||
}
|
||||
|
||||
|
||||
void CLI_SourceEngineEmulator::LocalInit()
|
||||
{
|
||||
CharacterSetBuild( &g_BreakSet, "{}()'" );
|
||||
CharacterSetBuild( &g_BreakSetIncludingColons, "{}()':" );
|
||||
}
|
||||
|
3
responserules/responserules_cli/resource.h
Normal file
3
responserules/responserules_cli/resource.h
Normal file
@ -0,0 +1,3 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by app.rc
|
52
responserules/responserules_cli/response_system.cpp
Normal file
52
responserules/responserules_cli/response_system.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/// @file response_system.cpp
|
||||
/// This file contains the unmanaged code implementing the editor's version
|
||||
/// of a response-system.
|
||||
|
||||
#include "stdafx.h"
|
||||
using namespace ResponseRules;
|
||||
|
||||
const char *ResponseSystemImplementationCLI::GetScriptFile( void )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#pragma managed(push, off)
|
||||
|
||||
void ResponseSystemImplementationCLI::PrecacheResponses( bool bEnable )
|
||||
{
|
||||
// precaching is meaningless in the editor
|
||||
Assert(false);
|
||||
}
|
||||
|
||||
void ResponseSystemImplementationCLI::Release( )
|
||||
{
|
||||
// precaching is meaningless in the editor
|
||||
Assert(false);
|
||||
}
|
||||
|
||||
int ResponseSystemImplementationCLI::CountRules()
|
||||
{
|
||||
return m_RulePartitions.Count();
|
||||
}
|
||||
|
||||
/// Resets the output vector and overwrites it entirely.
|
||||
/// <remarks>
|
||||
/// Meant to be the same algorithm as CResponseSystem::FindBestMatchingRule().
|
||||
/// </remarks>
|
||||
void ResponseSystemImplementationCLI::FindAllRulesMatchingCriteria( CUtlSortVector<RuleAndScorePair_t, RuleAndScorePair_t::LessFunc> * RESTRICT outputList, const CriteriaSet& set, IResponseFilter *pFilter /*= NULL */ )
|
||||
{
|
||||
outputList->RemoveAll();
|
||||
outputList->EnsureCapacity(16);
|
||||
|
||||
ResponseRulePartition::tRuleDict &rules = m_RulePartitions.GetDictForCriteria( set );
|
||||
int c = rules.Count();
|
||||
int i;
|
||||
for ( i = 0; i < c; i++ )
|
||||
{
|
||||
float score = ScoreCriteriaAgainstRule( set, rules, i, false );
|
||||
outputList->Insert( RuleAndScorePair_t( m_RulePartitions.IndexFromDictElem( &rules, i ), score ));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#pragma managed(pop)
|
68
responserules/responserules_cli/response_system.h
Normal file
68
responserules/responserules_cli/response_system.h
Normal file
@ -0,0 +1,68 @@
|
||||
/// @file response_system.cpp
|
||||
/// This file defines the editor's version
|
||||
/// of a response-system.
|
||||
|
||||
#ifndef CS_RESPONSE_SYSTEM_H
|
||||
#define CS_RESPONSE_SYSTEM_H
|
||||
|
||||
#include "UtlSortVector.h"
|
||||
|
||||
class ResponseSystemImplementationCLI : public ResponseRules::CResponseSystem
|
||||
{
|
||||
public:
|
||||
|
||||
#pragma region Overrides on CResponseSystem
|
||||
/// From ResponseRules::CResponseSystem.
|
||||
/// There, it returns the filename to load; here
|
||||
/// it is NULL, since the file comes from the editor
|
||||
/// dialog.
|
||||
virtual const char *GetScriptFile( void ) ;
|
||||
|
||||
virtual void PrecacheResponses( bool bEnable );
|
||||
virtual void Release();
|
||||
|
||||
inline void LoadFromFile( const char *filename );
|
||||
#pragma endregion
|
||||
|
||||
int CountRules() ;
|
||||
|
||||
/// USed to return a sorted list of all rules matching the criteria in order of score (not just the best)
|
||||
struct RuleAndScorePair_t
|
||||
{
|
||||
ResponseRules::ResponseRulePartition::tIndex ruleidx;
|
||||
float score;
|
||||
|
||||
RuleAndScorePair_t( const ResponseRules::ResponseRulePartition::tIndex &_idx, float _score ) : ruleidx(_idx), score(_score) {};
|
||||
RuleAndScorePair_t( ) : ruleidx(ResponseRules::ResponseRulePartition::InvalidIdx()) {};
|
||||
|
||||
struct LessFunc
|
||||
{
|
||||
// actually "more" since sort from best to worst score
|
||||
bool Less( const RuleAndScorePair_t & lhs, const RuleAndScorePair_t & rhs, void *pContext )
|
||||
{
|
||||
if ( lhs.score == rhs.score )
|
||||
{
|
||||
return lhs.ruleidx < rhs.ruleidx;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lhs.score > rhs.score;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
typedef CUtlSortVector<RuleAndScorePair_t, RuleAndScorePair_t::LessFunc> FindAllRulesRetval_t;
|
||||
void FindAllRulesMatchingCriteria( FindAllRulesRetval_t* RESTRICT outputList,
|
||||
const ResponseRules::CriteriaSet& set, ResponseRules::IResponseFilter *pFilter = NULL );
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline void ResponseSystemImplementationCLI::LoadFromFile( const char *filename )
|
||||
{
|
||||
Clear();
|
||||
return LoadRuleSet( filename );
|
||||
}
|
||||
|
||||
|
||||
#endif
|
351
responserules/responserules_cli/response_types_marshal.cpp
Normal file
351
responserules/responserules_cli/response_types_marshal.cpp
Normal file
@ -0,0 +1,351 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Marhsalled types for native response-rules data.
|
||||
// Rather than have the CLR try to access the response rules natively,
|
||||
// we copy the data out from the native types to these garbage-collected
|
||||
// CLI types.
|
||||
// This is manually kept in sync with the native types in response_types.h
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "response_types_marshal.h"
|
||||
|
||||
#pragma unmanaged
|
||||
#include "../../responserules/runtime/response_types_internal.h"
|
||||
#pragma managed
|
||||
|
||||
using namespace ResponseRulesCLI;
|
||||
|
||||
|
||||
|
||||
// ============================================================= //
|
||||
// Matcher
|
||||
// ============================================================= //
|
||||
|
||||
|
||||
String^ Matcher::Token::get()
|
||||
{
|
||||
return gcnew String(m_pNative->GetToken());
|
||||
}
|
||||
|
||||
String^ Matcher::RawSource::get()
|
||||
{
|
||||
return gcnew String(m_pNative->GetRaw());
|
||||
}
|
||||
|
||||
// Duped from
|
||||
// ResponseRules::Matcher::Describe
|
||||
|
||||
String^ Matcher::Description::get()
|
||||
{
|
||||
if ( !m_pNative->valid )
|
||||
{
|
||||
return gcnew String("Invalid!");
|
||||
}
|
||||
System::Text::StringBuilder sb("", 128);
|
||||
|
||||
int minmaxcount = 0;
|
||||
if ( m_pNative->usemin )
|
||||
{
|
||||
sb.AppendFormat( ">{0}{1:f3}", m_pNative->minequals ? "=" : "", m_pNative->minval );
|
||||
minmaxcount++;
|
||||
}
|
||||
if ( m_pNative->usemax )
|
||||
{
|
||||
sb.AppendFormat( "{0}<{1}{2:f3}",
|
||||
minmaxcount > 0 ? " and " : "",
|
||||
m_pNative->maxequals ? "=" : "",
|
||||
m_pNative->maxval );
|
||||
|
||||
minmaxcount++;
|
||||
}
|
||||
|
||||
if ( minmaxcount >= 1 )
|
||||
{
|
||||
return sb.ToString();
|
||||
}
|
||||
else if ( m_pNative->notequal )
|
||||
{
|
||||
return (gcnew String("!="))->Concat(Token);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (gcnew String("=="))->Concat(Token);
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================= //
|
||||
// ResponseParams
|
||||
// ============================================================= //
|
||||
|
||||
|
||||
String ^ ResponseRulesCLI::responseparams_interval_t::ToString()
|
||||
{
|
||||
if ( range > 0 )
|
||||
{
|
||||
System::Text::StringBuilder sb("", 16);
|
||||
sb.AppendFormat("[{0:f1}+{1:f1}]", start, range );
|
||||
return sb.ToString();
|
||||
}
|
||||
else if ( start > 0 )
|
||||
{
|
||||
System::Text::StringBuilder sb("", 16);
|
||||
sb.AppendFormat("{0:f1}", start );
|
||||
return sb.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return gcnew String("0");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// unmanaged thunk for below
|
||||
#pragma unmanaged
|
||||
ResponseRules::ResponseParams *CopyResponseParams( ResponseRules::ResponseParams *pSourceNativeParams )
|
||||
{
|
||||
return new ResponseRules::ResponseParams( *pSourceNativeParams );
|
||||
}
|
||||
#pragma managed
|
||||
|
||||
|
||||
responseparams_interval_t::responseparams_interval_t( const ResponseRules::responseparams_interval_t &from )
|
||||
{
|
||||
start = from.start;
|
||||
range = from.range;
|
||||
}
|
||||
|
||||
responseparams_interval_t ResponseParams::delay::get()
|
||||
{
|
||||
return responseparams_interval_t( m_pNative->delay );
|
||||
}
|
||||
|
||||
responseparams_interval_t ResponseParams::respeakdelay::get()
|
||||
{
|
||||
return responseparams_interval_t( m_pNative->respeakdelay );
|
||||
}
|
||||
|
||||
responseparams_interval_t ResponseParams::weapondelay::get()
|
||||
{
|
||||
return responseparams_interval_t( m_pNative->weapondelay );
|
||||
}
|
||||
|
||||
responseparams_interval_t ResponseParams::predelay::get()
|
||||
{
|
||||
return responseparams_interval_t( m_pNative->predelay );
|
||||
}
|
||||
|
||||
|
||||
short ResponseParams::odds::get()
|
||||
{
|
||||
return m_pNative->odds;
|
||||
}
|
||||
|
||||
unsigned short ResponseParams::flags::get()
|
||||
{
|
||||
return m_pNative->flags;
|
||||
}
|
||||
|
||||
byte ResponseParams::soundlevel::get()
|
||||
{
|
||||
return m_pNative->soundlevel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ============================================================= //
|
||||
// Response
|
||||
// ============================================================= //
|
||||
|
||||
/// A string containing the filename of a .vcd, the name of a sound script, etc.
|
||||
String^ Response::value::get()
|
||||
{
|
||||
return gcnew String( m_pNative->value );
|
||||
}
|
||||
|
||||
/// This response's relative weight in a rule.
|
||||
float Response::weight::get()
|
||||
{
|
||||
return m_pNative->weight.GetFloat();
|
||||
}
|
||||
|
||||
/// Used to track how many times a response can get said
|
||||
byte Response::depletioncount::get()
|
||||
{
|
||||
return m_pNative->depletioncount;
|
||||
}
|
||||
|
||||
/// What kind of response this is
|
||||
Response::ResponseType Response::type::get()
|
||||
{
|
||||
return ResponseType(m_pNative->type);
|
||||
}
|
||||
|
||||
/// Special flags that can be specified in the response
|
||||
bool Response::DisplayFirst::get()
|
||||
{
|
||||
return m_pNative->first;
|
||||
}
|
||||
|
||||
bool Response::DisplayLast::get()
|
||||
{
|
||||
return m_pNative->last;
|
||||
}
|
||||
|
||||
|
||||
// ============================================================= //
|
||||
// ResponseGroup
|
||||
// ============================================================= //
|
||||
|
||||
|
||||
// indexer goes into the cutlvector inside the group
|
||||
Response ^ ResponseGroup::default::get( int idx )
|
||||
{
|
||||
// Response ^frotz = gcnew Response(& m_pNative->group[idx] );
|
||||
// return gcnew Response(&m_pNative->group[idx]);
|
||||
return m_shadowResponseArray[idx];
|
||||
}
|
||||
|
||||
#pragma unmanaged
|
||||
static void AssignParserResponse( ResponseRules::ParserResponse *to, const ResponseRules::ParserResponse *from )
|
||||
{
|
||||
*to=*from;
|
||||
}
|
||||
#pragma managed
|
||||
|
||||
void ResponseGroup::default::set( int idx, Response^ from )
|
||||
{
|
||||
AssignParserResponse( &m_pNative->group[idx], from->GetNativePtr() );
|
||||
}
|
||||
|
||||
bool ResponseGroup::Sequential::get()
|
||||
{
|
||||
return m_pNative->IsSequential();
|
||||
}
|
||||
|
||||
bool ResponseGroup::NoRepeat::get()
|
||||
{
|
||||
return m_pNative->IsNoRepeat();
|
||||
}
|
||||
|
||||
bool ResponseGroup::Enabled::get()
|
||||
{
|
||||
return m_pNative->IsEnabled();
|
||||
}
|
||||
|
||||
int ResponseGroup::CurrentIndexInsideGroup::get()
|
||||
{
|
||||
return m_pNative->GetCurrentIndex();
|
||||
}
|
||||
|
||||
int ResponseGroup::Count::get()
|
||||
{
|
||||
return m_pNative->group.Count();
|
||||
}
|
||||
|
||||
|
||||
ResponseGroup::ResponseGroup( ResponseRules::ResponseGroup * RESTRICT ptr, int index )
|
||||
: BaseClass(ptr, false), m_index(index)
|
||||
{
|
||||
int numOfResponses = ptr->group.Count();
|
||||
m_shadowResponseArray = gcnew array<Response ^>(numOfResponses);
|
||||
|
||||
for ( int i = 0 ; i < numOfResponses ; ++i )
|
||||
{
|
||||
m_shadowResponseArray[i] = gcnew Response( &ptr->group[i], i );
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================= //
|
||||
// Criterion
|
||||
// ============================================================= //
|
||||
|
||||
|
||||
String^ Criterion::Key::get()
|
||||
{
|
||||
return gcnew String(m_pNative->name);
|
||||
}
|
||||
|
||||
String^ Criterion::Value::get()
|
||||
{
|
||||
return gcnew String(m_pNative->value);
|
||||
}
|
||||
|
||||
bool Criterion::Required::get()
|
||||
{
|
||||
return m_pNative->required;
|
||||
}
|
||||
|
||||
Matcher^ Criterion::Comparison::get()
|
||||
{
|
||||
return comparison;
|
||||
}
|
||||
|
||||
float Criterion::Weight::get()
|
||||
{
|
||||
return m_pNative->weight.GetFloat();
|
||||
}
|
||||
|
||||
|
||||
// ============================================================= //
|
||||
// Rule
|
||||
// ============================================================= //
|
||||
|
||||
|
||||
String^ Rule::Context::get()
|
||||
{
|
||||
return gcnew String(m_pNative->GetContext());
|
||||
}
|
||||
|
||||
void Rule::Context::set(String ^s)
|
||||
{
|
||||
m_pNative->SetContext( StrToAnsi(s) );
|
||||
}
|
||||
|
||||
bool Rule::Enabled::get()
|
||||
{
|
||||
return m_pNative->IsEnabled();
|
||||
}
|
||||
|
||||
bool Rule::MatchOnce::get()
|
||||
{
|
||||
return m_pNative->IsMatchOnce();
|
||||
}
|
||||
|
||||
bool Rule::IsApplyContextToWorld::get()
|
||||
{
|
||||
return m_pNative->IsApplyContextToWorld();
|
||||
}
|
||||
|
||||
// String^ GetValueForRuleCriterionByName( ResponseSystemCLI^ responsesystem, String^ criterionname );
|
||||
|
||||
unsigned short Rule::ResponseIndices::get( int idx )
|
||||
{
|
||||
return m_pNative->m_Responses[idx] ;
|
||||
}
|
||||
int Rule::NumResponses::get( )
|
||||
{
|
||||
return m_pNative->m_Responses.Count();
|
||||
}
|
||||
|
||||
ResponseGroup ^Rule::ResponseGroups::get( int idx )
|
||||
{
|
||||
return safe_cast<ResponseGroup ^>(SingletonResponseSystem_t::RS::get()->ResponseGroupsDict[idx]);
|
||||
}
|
||||
|
||||
unsigned short Rule::CriteriaIndices::get( int idx )
|
||||
{
|
||||
return m_pNative->m_Criteria[idx];
|
||||
}
|
||||
|
||||
int Rule::NumCriteria::get( )
|
||||
{
|
||||
return m_pNative->m_Criteria.Count();
|
||||
}
|
||||
|
||||
Criterion ^Rule::Criteria::get( int idx )
|
||||
{
|
||||
return safe_cast<Criterion ^>(SingletonResponseSystem_t::RS::get()->CriteriaDict[idx]);
|
||||
}
|
604
responserules/responserules_cli/response_types_marshal.h
Normal file
604
responserules/responserules_cli/response_types_marshal.h
Normal file
@ -0,0 +1,604 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Marhsalled types for native response-rules data.
|
||||
// Rather than have the CLR try to access the response rules natively,
|
||||
// we copy the data out from the native types to these garbage-collected
|
||||
// CLI types.
|
||||
// This is manually kept in sync with the native types in response_types.h
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef RESPONSE_TYPES_MARSHAL_H
|
||||
#define RESPONSE_TYPES_MARSHAL_H
|
||||
#pragma once
|
||||
|
||||
using namespace System;
|
||||
|
||||
|
||||
// forward-declare some classes we wrap
|
||||
namespace ResponseRules
|
||||
{
|
||||
struct ResponseParams;
|
||||
struct ParserResponse;
|
||||
class CRR_Response;
|
||||
|
||||
};
|
||||
|
||||
#include "response_types_marshal_wrappers.h"
|
||||
|
||||
namespace ResponseRulesCLI
|
||||
{
|
||||
ref class ResponseSystemCLI;
|
||||
// try to maintain a singleton pointer to the response system
|
||||
public value class SingletonResponseSystem_t
|
||||
{
|
||||
public:
|
||||
property ResponseSystemCLI ^RS
|
||||
{
|
||||
static ResponseSystemCLI ^get() { return g_RS; }
|
||||
static void set(ResponseSystemCLI ^ r ) { g_RS=r; }
|
||||
}
|
||||
|
||||
private:
|
||||
static ResponseSystemCLI ^g_RS;
|
||||
} SingletonResponseSystem;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// "internal" types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/// Stub for now
|
||||
public ref class ResponseFollowup {};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Encapsulates the comparison of a value against a criterion.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Matcher performs the comparison between the value specified in
|
||||
/// the criterion and the value specified in a context. Eg, a criterion
|
||||
/// with key "foo", value 5 and matcher ">" means that only queries with
|
||||
/// context "foo" greater than 5 will match this criterion.
|
||||
///
|
||||
/// This is a representation only since the actual matching code is all in the
|
||||
/// C++ side.
|
||||
/// </remarks>
|
||||
public ref class Matcher : public NativeTypeCopyWrapper<ResponseRules::Matcher>
|
||||
{
|
||||
typedef NativeTypeCopyWrapper<ResponseRules::Matcher> BaseClass;
|
||||
public:
|
||||
Matcher( ) {};
|
||||
Matcher( ResponseRules::Matcher *ptr ) : BaseClass(ptr, false) {};
|
||||
property String^ Token
|
||||
{
|
||||
String ^get();
|
||||
}
|
||||
|
||||
property String^ RawSource
|
||||
{
|
||||
String ^get();
|
||||
}
|
||||
|
||||
property String^ Description
|
||||
{
|
||||
String ^get();
|
||||
}
|
||||
|
||||
// flag accessors -- from the comparison mechanism
|
||||
// inherited from Yahn's original system of changelist
|
||||
// 59153.
|
||||
property bool FlagValid
|
||||
{
|
||||
inline bool get() { return m_pNative->valid; }
|
||||
}
|
||||
property bool FlagNumeric
|
||||
{
|
||||
inline bool get() { return m_pNative->isnumeric; }
|
||||
}
|
||||
property bool FlagNotEqual
|
||||
{
|
||||
inline bool get() { return m_pNative->notequal; }
|
||||
}
|
||||
property bool FlagUseMin
|
||||
{
|
||||
inline bool get() { return m_pNative->usemin; }
|
||||
}
|
||||
property bool FlagMinEquals
|
||||
{
|
||||
inline bool get() { return m_pNative->minequals; }
|
||||
}
|
||||
property bool FlagUseMax
|
||||
{
|
||||
inline bool get() { return m_pNative->usemax; }
|
||||
}
|
||||
property bool FlagMaxEquals
|
||||
{
|
||||
inline bool get() { return m_pNative->maxequals; }
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Represents a single AI_Criterion inside a rule.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A response rule contains a list of criteria, each of which consists of a key,
|
||||
/// a matcher (comparator), and a value. A query into the response system contains a
|
||||
/// list of key:value pairs. Each of these is tested against all the criteria in a rule.
|
||||
/// Each matching criterion increases that rule's score. The best scoring rule is selected.
|
||||
/// If a criterion is marked as Required, then its failure rejects the rule.
|
||||
/// Otherwise it just doesn't contribute to the score.
|
||||
/// </remarks>
|
||||
public ref class Criterion : public NativeTypeCopyWrapper<ResponseRules::Criteria>
|
||||
{
|
||||
typedef NativeTypeCopyWrapper<ResponseRules::Criteria> BaseClass;
|
||||
public:
|
||||
Criterion() {};
|
||||
Criterion( ResponseRules::Criteria *ptr, int _index ) : BaseClass( ptr, false ), index(_index)
|
||||
{
|
||||
comparison = gcnew Matcher( &ptr->matcher );
|
||||
};
|
||||
property String^ Key
|
||||
{
|
||||
String^ get();
|
||||
}
|
||||
|
||||
property String^ Value
|
||||
{
|
||||
String^ get();
|
||||
}
|
||||
|
||||
property bool Required
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
property Matcher^ Comparison
|
||||
{
|
||||
Matcher^ get();
|
||||
}
|
||||
|
||||
property float Weight
|
||||
{
|
||||
float get();
|
||||
}
|
||||
|
||||
property int Idx
|
||||
{
|
||||
int get() { return index; }
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/// dummy criteria data for testing
|
||||
public static Criterion g_DummyCriteria[] =
|
||||
{
|
||||
new Criterion( "foo", "1", 1, false, new Matcher(">") ),
|
||||
new Criterion( "bar", "soup", 1, false, new Matcher("") ),
|
||||
new Criterion( "Concept", "Talk", 1, true, new Matcher("") )
|
||||
};
|
||||
*/
|
||||
|
||||
private:
|
||||
float weight;
|
||||
bool required;
|
||||
Matcher^ comparison;
|
||||
int index; ///< my ID in the large dictionary of all criteria.
|
||||
};
|
||||
|
||||
|
||||
public value struct responseparams_interval_t
|
||||
{
|
||||
float start;
|
||||
float range;
|
||||
|
||||
responseparams_interval_t( const ResponseRules::responseparams_interval_t &from );
|
||||
virtual String ^ToString() override;
|
||||
/*
|
||||
interval_t &ToInterval( interval_t &dest ) const { dest.start = start; dest.range = range; return dest; }
|
||||
void FromInterval( const interval_t &from ) { start = from.start; range = from.range; }
|
||||
float Random() const { interval_t temp = { start, range }; return RandomInterval( temp ); }
|
||||
*/
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Parameters for a ParserResponse.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
public ref struct ResponseParams : public NativeTypeCopyWrapper<ResponseRules::ResponseParams>
|
||||
{
|
||||
private:
|
||||
typedef NativeTypeCopyWrapper<ResponseRules::ResponseParams> BaseClass;
|
||||
public:
|
||||
// manually match the native version.
|
||||
// there is no way to automatically wrap
|
||||
// a native enum to a managed enum.
|
||||
[Flags]
|
||||
enum class ParamFlags_t
|
||||
{
|
||||
None = (0),
|
||||
RG_DELAYAFTERSPEAK = (1<<0),
|
||||
RG_SPEAKONCE = (1<<1),
|
||||
RG_ODDS = (1<<2),
|
||||
RG_RESPEAKDELAY = (1<<3),
|
||||
RG_SOUNDLEVEL = (1<<4),
|
||||
RG_DONT_USE_SCENE = (1<<5),
|
||||
RG_STOP_ON_NONIDLE = (1<<6),
|
||||
RG_WEAPONDELAY = (1<<7),
|
||||
RG_DELAYBEFORESPEAK = (1<<8),
|
||||
};
|
||||
|
||||
/*
|
||||
ResponseParams()
|
||||
{
|
||||
flags = 0;
|
||||
odds = 100;
|
||||
delay.start = 0;f
|
||||
delay.range = 0;
|
||||
respeakdelay.start = 0;
|
||||
respeakdelay.range = 0;
|
||||
weapondelay.start = 0;
|
||||
weapondelay.range = 0;
|
||||
soundlevel = 0;
|
||||
predelay.start = 0;
|
||||
predelay.range = 0;
|
||||
}
|
||||
*/
|
||||
|
||||
ResponseParams(){};
|
||||
|
||||
ResponseParams( ResponseRules::ResponseParams *pSourceNativeParams ) :
|
||||
BaseClass( pSourceNativeParams, false ) {};
|
||||
|
||||
|
||||
property responseparams_interval_t delay
|
||||
{
|
||||
responseparams_interval_t get();
|
||||
}
|
||||
property responseparams_interval_t respeakdelay
|
||||
{
|
||||
responseparams_interval_t get();
|
||||
}
|
||||
property responseparams_interval_t weapondelay
|
||||
{
|
||||
responseparams_interval_t get();
|
||||
}
|
||||
property responseparams_interval_t predelay
|
||||
{
|
||||
responseparams_interval_t get();
|
||||
}
|
||||
|
||||
property short odds
|
||||
{
|
||||
short get();
|
||||
}
|
||||
property unsigned short flags
|
||||
{
|
||||
unsigned short get();
|
||||
}
|
||||
property bool IsSpeakOnce
|
||||
{
|
||||
bool get() { return ( ((ParamFlags_t)(flags)) & ParamFlags_t::RG_RESPEAKDELAY ) != ParamFlags_t::None ; }
|
||||
}
|
||||
property byte soundlevel
|
||||
{
|
||||
byte get();
|
||||
}
|
||||
|
||||
ResponseFollowup^ m_pFollowup;
|
||||
|
||||
protected:
|
||||
// ResponseRules::ResponseParams *m_pNative;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Response as read from the script file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The action that ensues as a result of a query into the RR system
|
||||
/// is a Response. It may be a .vcd, a sound, or many other things.
|
||||
/// This Response class represents the entry in the source data file,
|
||||
/// not the result of a query into the system. Its analogue in C++
|
||||
/// is the ParserResponse.
|
||||
/// </remarks>
|
||||
public ref class Response : public NativeTypeCopyWrapper<ResponseRules::ParserResponse>
|
||||
{
|
||||
typedef NativeTypeCopyWrapper<ResponseRules::ParserResponse> BaseClass ;
|
||||
public:
|
||||
Response(){};
|
||||
Response( ResponseRules::ParserResponse *x , int index) : BaseClass(x, false),
|
||||
m_index(index)
|
||||
{
|
||||
m_params = gcnew ResponseParams(&x->params);
|
||||
};
|
||||
|
||||
/// The various types of response available.
|
||||
enum class ResponseType
|
||||
{
|
||||
RESPONSE_NONE = 0,
|
||||
RESPONSE_SPEAK,
|
||||
RESPONSE_SENTENCE,
|
||||
RESPONSE_SCENE,
|
||||
RESPONSE_RESPONSE, // A reference to another response by name
|
||||
RESPONSE_PRINT,
|
||||
|
||||
NUM_RESPONSES,
|
||||
};
|
||||
|
||||
property ResponseParams ^params
|
||||
{
|
||||
ResponseParams ^get() { return m_params; }
|
||||
}
|
||||
|
||||
/// A string containing the filename of a .vcd, the name of a sound script, etc.
|
||||
property String^ value
|
||||
{
|
||||
String^ get();
|
||||
}
|
||||
|
||||
/// This response's relative weight in a rule.
|
||||
property float weight
|
||||
{
|
||||
float get();
|
||||
}
|
||||
|
||||
/// Used to track how many times a response can get said
|
||||
property byte depletioncount
|
||||
{
|
||||
byte get();
|
||||
}
|
||||
|
||||
/// What kind of response this is
|
||||
property ResponseType type
|
||||
{
|
||||
ResponseType get();
|
||||
}
|
||||
|
||||
/// Special flags that can be specified in the response
|
||||
property bool DisplayFirst
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
property bool DisplayLast
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
// property ResponseFollowup^ followup;
|
||||
|
||||
|
||||
protected:
|
||||
/// in my owning responsegroup
|
||||
int m_index;
|
||||
ResponseParams ^m_params;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a group of Responses, eg all the ones available
|
||||
/// when a rule is matched.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The ordering of responses in this group isn't innately important.
|
||||
/// However some responses may be marked "first" or "last" in which
|
||||
/// case they are played either at beginning or end for the rule.
|
||||
/// Implements IList, representing a list of the responses it contains.
|
||||
/// </remarks>
|
||||
public ref class ResponseGroup : public NativeTypeCopyWrapper<ResponseRules::ResponseGroup>
|
||||
{
|
||||
typedef public NativeTypeCopyWrapper<ResponseRules::ResponseGroup> BaseClass;
|
||||
public:
|
||||
ResponseGroup() {};
|
||||
ResponseGroup( ResponseRules::ResponseGroup *ptr, int index );
|
||||
property bool Sequential
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
property bool NoRepeat
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
property bool Enabled
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
property int CurrentIndexInsideGroup
|
||||
{
|
||||
int get();
|
||||
}
|
||||
|
||||
property int Count
|
||||
{
|
||||
int get();
|
||||
}
|
||||
|
||||
/// The index of this response group inside the global system's dict
|
||||
property int Index
|
||||
{
|
||||
int get() { return m_index; }
|
||||
}
|
||||
|
||||
/// For WPF views, get the responses as a list.
|
||||
property System::Collections::IList^ ResponsesList
|
||||
{
|
||||
System::Collections::IList^ get() { return m_shadowResponseArray; }
|
||||
}
|
||||
|
||||
|
||||
/// indexer goes into the cutlvector inside the group
|
||||
property Response ^ default[int]
|
||||
{
|
||||
Response ^get( int idx );
|
||||
void set( int idx, Response^ from );
|
||||
}
|
||||
|
||||
protected:
|
||||
/// in the global system dictionary
|
||||
int m_index;
|
||||
|
||||
private:
|
||||
/// we'll preallocate the Response wrapper objects inside here
|
||||
/// to speed up the access in wpf views.
|
||||
array<Response ^>^ m_shadowResponseArray;
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Response Rule
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A rule contains a bunch of criteria and a group of responses.
|
||||
/// A query into the RR system means iterating through the database of
|
||||
/// Rules with a set of contexts; the contexts are matched against the
|
||||
/// criteria and the best match is returned.
|
||||
/// </remarks>
|
||||
public ref class Rule : public NativeTypeCopyWrapper<ResponseRules::Rule>
|
||||
{
|
||||
typedef NativeTypeCopyWrapper<ResponseRules::Rule> BaseClass ;
|
||||
public:
|
||||
typedef IndexPropertyToIListReadOnly<ResponseGroup ^> ResGroupAsIList_t;
|
||||
typedef IndexPropertyToIListReadOnly<Criterion ^> CriteriaAsIList_t;
|
||||
|
||||
public:
|
||||
Rule(){};
|
||||
Rule( ResponseRules::Rule *x, ResponseRules::ResponseRulePartition::tIndex idx, const char *name ) :
|
||||
BaseClass(x, false), m_index(idx), m_name(gcnew String(name)),
|
||||
m_ResponseGroupsAsList( nullptr ), m_CriteriaAsList( nullptr )
|
||||
{
|
||||
m_ResponseGroupsAsList = gcnew ResGroupAsIList_t(
|
||||
gcnew ResGroupAsIList_t::lGetter(this, &ResponseGroups::get),
|
||||
gcnew ResGroupAsIList_t::lCounter(this, &NumResponses::get) ) ;
|
||||
|
||||
m_CriteriaAsList = gcnew CriteriaAsIList_t(
|
||||
gcnew CriteriaAsIList_t::lGetter(this, &Criteria::get),
|
||||
gcnew CriteriaAsIList_t::lCounter(this, &NumCriteria::get) ) ;
|
||||
};
|
||||
|
||||
property String^ Context
|
||||
{
|
||||
String^ get();
|
||||
void set(String ^s);
|
||||
}
|
||||
|
||||
property bool Enabled
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
property bool MatchOnce
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
property bool IsApplyContextToWorld
|
||||
{
|
||||
bool get();
|
||||
}
|
||||
|
||||
// String^ GetValueForRuleCriterionByName( ResponseSystemCLI^ responsesystem, String^ criterionname );
|
||||
|
||||
/// indexes into the response system
|
||||
property unsigned short ResponseIndices[int]
|
||||
{
|
||||
unsigned short get( int idx );
|
||||
}
|
||||
property int NumResponses
|
||||
{
|
||||
int get( );
|
||||
}
|
||||
property ResponseGroup ^ResponseGroups[int]
|
||||
{
|
||||
ResponseGroup ^get( int idx );
|
||||
}
|
||||
property ResGroupAsIList_t ^ResponseGroupsAsIList
|
||||
{
|
||||
ResGroupAsIList_t ^get() { return m_ResponseGroupsAsList; }
|
||||
}
|
||||
|
||||
|
||||
property unsigned short CriteriaIndices[int]
|
||||
{
|
||||
unsigned short get( int idx );
|
||||
}
|
||||
property int NumCriteria
|
||||
{
|
||||
int get( );
|
||||
}
|
||||
property Criterion ^Criteria[int]
|
||||
{
|
||||
Criterion ^get( int idx );
|
||||
}
|
||||
property CriteriaAsIList_t ^CriteriaAsIList
|
||||
{
|
||||
CriteriaAsIList_t ^get() { return m_CriteriaAsList; }
|
||||
}
|
||||
|
||||
property ResponseRules::ResponseRulePartition::tIndex IndexInResponseSystem
|
||||
{
|
||||
ResponseRules::ResponseRulePartition::tIndex get() { return m_index; }
|
||||
}
|
||||
|
||||
property String^ Name
|
||||
{
|
||||
String ^get() { return m_name; }
|
||||
}
|
||||
|
||||
private:
|
||||
/// index inside responsesystem
|
||||
ResponseRules::ResponseRulePartition::tIndex m_index;
|
||||
String ^m_name;
|
||||
ResGroupAsIList_t ^m_ResponseGroupsAsList;
|
||||
CriteriaAsIList_t ^m_CriteriaAsList;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// "public" types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if 0
|
||||
/// Takes ownership of the response object and DELETES IT when finalized.
|
||||
public ref class ResponseQueryResult
|
||||
{
|
||||
public:
|
||||
ResponseQueryResult( ) : m_pNative(NULL) {};
|
||||
ResponseQueryResult( ResponseRules::CRR_Response * source ) : m_pNative(source) {};
|
||||
~ResponseQueryResult() { this->!ResponseQueryResult(); }
|
||||
!ResponseQueryResult()
|
||||
{
|
||||
delete m_pNative;
|
||||
m_pNative = NULL;
|
||||
}
|
||||
|
||||
property String^ RuleName
|
||||
{
|
||||
String^ get();
|
||||
}
|
||||
|
||||
property String^ ResponseName
|
||||
{
|
||||
String^ get();
|
||||
}
|
||||
|
||||
protected:
|
||||
ResponseRules::CRR_Response *m_pNative;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// henceforth contexts shall be called "facts".
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,27 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Templates for use in response_types_marhsal.h
|
||||
// Placed here just to keep code a little bit cleaner.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef RESPONSE_TYPES_MARSHAL_WRAPPERS_H
|
||||
#define RESPONSE_TYPES_MARSHAL_WRAPPERS_H
|
||||
#pragma once
|
||||
|
||||
#include "utlcontainer_cli.h"
|
||||
|
||||
/// Some (unpublished) template specializations for the above.
|
||||
extern ResponseRules::ResponseParams *CopyResponseParams( ResponseRules::ResponseParams *pSourceNativeParams );
|
||||
template < >
|
||||
NativeTypeCopyWrapper< ResponseRules::ResponseParams >::NativeTypeCopyWrapper( ResponseRules::ResponseParams *pSourceNativeParams, bool bCopy )
|
||||
{
|
||||
m_bIsCopy = bCopy;
|
||||
if ( bCopy )
|
||||
m_pNative = CopyResponseParams( pSourceNativeParams );
|
||||
else
|
||||
m_pNative = pSourceNativeParams;
|
||||
}
|
||||
|
||||
#endif
|
247
responserules/responserules_cli/responserules_cli.cpp
Normal file
247
responserules/responserules_cli/responserules_cli.cpp
Normal file
@ -0,0 +1,247 @@
|
||||
// This is the main DLL file.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
extern int TestRandomNumberGeneration( int bottom, int top ) ;
|
||||
extern const char *TestFileSystemHook( ) ;
|
||||
|
||||
using namespace ResponseRulesCLI;
|
||||
|
||||
namespace MikeCTest
|
||||
{
|
||||
public ref class Person
|
||||
{
|
||||
private:
|
||||
String^ _name;
|
||||
public:
|
||||
Person( String^ name )
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
String^ Description()
|
||||
{
|
||||
// this is the big test!
|
||||
int rndNum = TestRandomNumberGeneration( 0, 10 );
|
||||
String^ foo = gcnew String(TestFileSystemHook());
|
||||
|
||||
return ( "My name is " + _name +
|
||||
" filesystem is " + foo
|
||||
// " my ID is " + rndNum.ToString()
|
||||
);
|
||||
}
|
||||
|
||||
static bool HopefullyDontCrash()
|
||||
{
|
||||
TestFileSystemHook( );
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include "response_system.h"
|
||||
|
||||
|
||||
|
||||
StrToAnsi::StrToAnsi( String ^unicodestr )
|
||||
{
|
||||
m_pStr = (char*)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(unicodestr);
|
||||
}
|
||||
|
||||
StrToAnsi::~StrToAnsi( )
|
||||
{
|
||||
System::Runtime::InteropServices::Marshal::FreeHGlobal((System::IntPtr)(void*)m_pStr);
|
||||
}
|
||||
|
||||
StrToAnsi::operator TCHAR *() const
|
||||
{
|
||||
return m_pStr;
|
||||
}
|
||||
|
||||
/*
|
||||
using namespace System::Runtime::InteropServices; // for class Marshal
|
||||
|
||||
void PrintMessage(System::String^ str)
|
||||
{
|
||||
const char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
|
||||
printf(str2);
|
||||
Marshal::FreeHGlobal((System::IntPtr)(void*)str2);
|
||||
}
|
||||
|
||||
PrintMessage("Method 2");
|
||||
*/
|
||||
|
||||
|
||||
using namespace ResponseRulesCLI;
|
||||
|
||||
// Allocate the native object on the C++ Heap via a constructor
|
||||
ResponseSystemCLI::ResponseSystemCLI()
|
||||
{
|
||||
m_pImpl = new ResponseSystemImplementationCLI();
|
||||
m_CriteriaDict = gcnew CriterionDictWrapper_t(&m_pImpl->m_Criteria);
|
||||
m_ResponseGroupsDict = gcnew ResponseGroupDictWrapper_t(&m_pImpl->m_Responses);
|
||||
m_RulesContainer = gcnew RulesAsList(this);
|
||||
}
|
||||
|
||||
// Deallocate the native object on a destructor
|
||||
ResponseSystemCLI::~ResponseSystemCLI()
|
||||
{
|
||||
this->!ResponseSystemCLI();
|
||||
}
|
||||
|
||||
// Deallocate the native object on the finalizer just in case no destructor is called
|
||||
ResponseSystemCLI::!ResponseSystemCLI()
|
||||
{
|
||||
delete m_pImpl;
|
||||
}
|
||||
|
||||
|
||||
void ResponseSystemCLI::LoadFromFile( String^ filename )
|
||||
{
|
||||
return m_pImpl->LoadFromFile( StrToAnsi(filename) );
|
||||
}
|
||||
|
||||
|
||||
int ResponseSystemCLI::CountRules()
|
||||
{
|
||||
return m_pImpl->CountRules();
|
||||
}
|
||||
|
||||
ResponseSystemImplementationCLI *ResponseSystemCLI::GetNativePtr()
|
||||
{
|
||||
return m_pImpl;
|
||||
}
|
||||
|
||||
void ResponseSystemCLI::RulesAsList::RulesIterator::Reset()
|
||||
{
|
||||
m_bIsBefore = true;
|
||||
m_idx = m_System->GetNativePtr()->m_RulePartitions.First();
|
||||
}
|
||||
|
||||
bool ResponseSystemCLI::RulesAsList::RulesIterator::MoveNext()
|
||||
{
|
||||
if (m_bIsBefore)
|
||||
{
|
||||
m_bIsBefore = false;
|
||||
m_idx = m_System->GetNativePtr()->m_RulePartitions.First();
|
||||
return IsValid();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !IsValid() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// stick the index on the stack temporarily so we can pass a reference to it
|
||||
ResponseRules::ResponseRulePartition::tIndex tmp = m_idx;
|
||||
m_idx = m_System->GetNativePtr()->m_RulePartitions.Next(tmp);
|
||||
return IsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ResponseSystemCLI::RulesAsList::RulesIterator::IsValid()
|
||||
{
|
||||
// stick the index on the stack temporarily so we can pass a reference to it
|
||||
ResponseRules::ResponseRulePartition::tIndex tmp = m_idx;
|
||||
return m_System->GetNativePtr()->m_RulePartitions.IsValid( tmp );
|
||||
}
|
||||
|
||||
Object^ ResponseSystemCLI::RulesAsList::RulesIterator::Current::get()
|
||||
{
|
||||
if (IsValid())
|
||||
{
|
||||
ResponseRules::ResponseRulePartition::tIndex i = m_idx;
|
||||
return gcnew Rule(&m_System->GetNativePtr()->m_RulePartitions[i],
|
||||
i,
|
||||
m_System->GetNativePtr()->m_RulePartitions.GetElementName(i) );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew System::InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/// access to the dictionary of index->criteria
|
||||
Criterion ^ ResponseSystemCLI::Criteria::get( short key )
|
||||
{
|
||||
return gcnew Criterion(&m_pImpl->m_Criteria[key], key);
|
||||
}
|
||||
unsigned int ResponseSystemCLI::CriteriaCount::get()
|
||||
{
|
||||
return m_pImpl->m_Criteria.Count();
|
||||
}
|
||||
*/
|
||||
|
||||
Rule ^ ResponseSystemCLI::FindBestMatchingRule( System::Collections::IDictionary ^facts )
|
||||
{
|
||||
ResponseRules::CriteriaSet criteria;
|
||||
TurnIDictIntoCriteriaSet( facts, &criteria );
|
||||
float bestscore; // of matching rule
|
||||
ResponseRules::ResponseRulePartition::tIndex bestRuleIndex = m_pImpl->FindBestMatchingRule( criteria, false, bestscore );
|
||||
|
||||
if ( m_pImpl->m_RulePartitions.IsValid( bestRuleIndex ) )
|
||||
{
|
||||
return RuleFromIdx(bestRuleIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Rule ^ResponseSystemCLI::RuleFromIdx( ResponseRules::ResponseRulePartition::tIndex idx )
|
||||
{
|
||||
return gcnew Rule( &m_pImpl->m_RulePartitions[idx],
|
||||
idx,
|
||||
m_pImpl->m_RulePartitions.GetElementName(idx) );
|
||||
}
|
||||
|
||||
void ResponseSystemCLI::TurnIDictIntoCriteriaSet( System::Collections::IDictionary ^facts, ResponseRules::CriteriaSet *critset )
|
||||
{
|
||||
// for each key and value in the dictionary, add to set.
|
||||
for each ( System::Collections::DictionaryEntry pair in facts )
|
||||
{
|
||||
critset->AppendCriteria( StrToAnsi(pair.Key->ToString()), StrToAnsi(pair.Value->ToString()) );
|
||||
}
|
||||
}
|
||||
|
||||
array< System::Collections::Generic::KeyValuePair<Rule ^,float> >^ ResponseSystemCLI::FindAllRulesMatchingCriteria( System::Collections::IDictionary ^facts )
|
||||
{
|
||||
ResponseRules::CriteriaSet crits;
|
||||
TurnIDictIntoCriteriaSet( facts, &crits );
|
||||
ResponseSystemImplementationCLI::FindAllRulesRetval_t ruleresults;
|
||||
m_pImpl->FindAllRulesMatchingCriteria( &ruleresults, crits );
|
||||
if ( ruleresults.Count() < 1 )
|
||||
{
|
||||
// return empty array.
|
||||
return gcnew array< System::Collections::Generic::KeyValuePair<Rule ^,float> >(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int count = ruleresults.Count();
|
||||
array< System::Collections::Generic::KeyValuePair<Rule ^,float> >^ retval = gcnew array< System::Collections::Generic::KeyValuePair<Rule ^,float> >(count);
|
||||
for (int i = 0 ; i < count ; ++i )
|
||||
{
|
||||
const ResponseSystemImplementationCLI::RuleAndScorePair_t &pair = ruleresults[i];
|
||||
retval[i] = System::Collections::Generic::KeyValuePair<Rule ^,float>(RuleFromIdx(pair.ruleidx),pair.score);
|
||||
|
||||
/*
|
||||
retval[i].Key = RuleFromIdx(pair.ruleidx);
|
||||
retval[i].Value = pair.score;
|
||||
*/
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
#pragma unmanaged
|
||||
#include "../../responserules/runtime/response_types_internal.h"
|
||||
#pragma managed
|
||||
*/
|
155
responserules/responserules_cli/responserules_cli.h
Normal file
155
responserules/responserules_cli/responserules_cli.h
Normal file
@ -0,0 +1,155 @@
|
||||
// responserules_cli.h
|
||||
|
||||
#pragma once
|
||||
|
||||
using namespace System;
|
||||
|
||||
|
||||
#pragma unmanaged
|
||||
namespace ResponseRules
|
||||
{
|
||||
/// forward declare unmanaged implementation
|
||||
class CriteriaSet;
|
||||
}
|
||||
#pragma managed
|
||||
|
||||
|
||||
#include "response_types_marshal.h"
|
||||
|
||||
namespace ResponseRulesCLI {
|
||||
|
||||
typedef CCLIUtlDictEnumerable< ResponseRules::Criteria, short, ResponseRulesCLI::Criterion > CriterionDictWrapper_t;
|
||||
typedef CCLIUtlDictEnumerable< ResponseRules::ResponseGroup, short, ResponseRulesCLI::ResponseGroup > ResponseGroupDictWrapper_t;
|
||||
// enumerations aren't used right now it seems.
|
||||
// typedef CCLIUtlDictEnumerable< ResponseRules::CResponseSystem::Enumeration, short, System::Single > EnumerationDictWrapper_t;
|
||||
|
||||
|
||||
|
||||
/// Encapsulates an entire response system based on a file,
|
||||
/// containing responses, rules, criteria, and other data.
|
||||
public ref class ResponseSystemCLI
|
||||
{
|
||||
public:
|
||||
// Allocate the native object on the C++ Heap via a constructor
|
||||
ResponseSystemCLI();
|
||||
|
||||
// Deallocate the native object on a destructor
|
||||
~ResponseSystemCLI() ;
|
||||
|
||||
/// Load this system from a talker file.
|
||||
virtual void LoadFromFile( String^ filename );
|
||||
int CountRules();
|
||||
|
||||
property ResponseGroupDictWrapper_t ^ResponseGroupsDict
|
||||
{
|
||||
ResponseGroupDictWrapper_t ^get() { return m_ResponseGroupsDict; }
|
||||
}
|
||||
|
||||
property CriterionDictWrapper_t ^CriteriaDict
|
||||
{
|
||||
CriterionDictWrapper_t ^get() { return m_CriteriaDict; }
|
||||
}
|
||||
|
||||
/*
|
||||
property EnumerationDictWrapper_t ^EnumerationsDict
|
||||
{
|
||||
EnumerationDictWrapper_t ^get() { return m_EnumerationsDict; }
|
||||
}
|
||||
*/
|
||||
|
||||
/// interface to enumerate rules.
|
||||
ref class RulesAsList : public System::Collections::IEnumerable, System::Collections::Specialized::INotifyCollectionChanged
|
||||
{
|
||||
public:
|
||||
|
||||
ref struct RulesIterator : System::Collections::IEnumerator
|
||||
{
|
||||
public:
|
||||
RulesIterator( ResponseSystemCLI^ enumerable ) :
|
||||
m_System(enumerable), m_bIsBefore(false), m_idx(ResponseRules::ResponseRulePartition::InvalidIdx()) {Reset();};
|
||||
virtual void Reset();
|
||||
virtual bool MoveNext(); // return false when falling off the end
|
||||
|
||||
property Object^ Current
|
||||
{
|
||||
virtual Object^ get();
|
||||
};
|
||||
|
||||
protected:
|
||||
bool m_bIsBefore; // is "one before" everything in the array, required by iterator interface
|
||||
bool IsValid() ;
|
||||
ResponseSystemCLI ^m_System; ///< the system I iterate
|
||||
ResponseRules::ResponseRulePartition::tIndex m_idx;
|
||||
};
|
||||
|
||||
RulesAsList( ResponseSystemCLI^ owner ) : m_owner(owner) {};
|
||||
|
||||
property int Count
|
||||
{
|
||||
int get() { return m_owner->GetNativePtr()->CountRules(); }
|
||||
}
|
||||
|
||||
virtual System::Collections::IEnumerator^ GetEnumerator()
|
||||
{
|
||||
return gcnew RulesIterator(m_owner);
|
||||
}
|
||||
|
||||
#pragma region INotifyCollectionChanged interface
|
||||
|
||||
System::Collections::Specialized::NotifyCollectionChangedEventHandler ^m_CollectionChanged;
|
||||
virtual event System::Collections::Specialized::NotifyCollectionChangedEventHandler ^CollectionChanged
|
||||
{
|
||||
void add(System::Collections::Specialized::NotifyCollectionChangedEventHandler ^ d) {
|
||||
m_CollectionChanged += d;
|
||||
}
|
||||
void remove(System::Collections::Specialized::NotifyCollectionChangedEventHandler ^ d) {
|
||||
m_CollectionChanged -= d;
|
||||
}
|
||||
}
|
||||
virtual void OnCollectionChanged(System::Collections::Specialized::NotifyCollectionChangedEventArgs ^e)
|
||||
{
|
||||
if (m_CollectionChanged != nullptr)
|
||||
{
|
||||
m_CollectionChanged(this, e);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
private:
|
||||
ResponseSystemCLI^ m_owner;
|
||||
};
|
||||
|
||||
property RulesAsList^ Rules
|
||||
{
|
||||
RulesAsList^ get() { return m_RulesContainer; };
|
||||
}
|
||||
|
||||
#pragma region "Queries Into Response System"
|
||||
|
||||
/// Given a dictionary of key:value pairs (the contexts and their values),
|
||||
/// find the best matching rule.
|
||||
Rule ^FindBestMatchingRule( System::Collections::IDictionary ^facts );
|
||||
|
||||
/// Find *all* rules that match the given criteria, in sorted order of best to worst.
|
||||
array< System::Collections::Generic::KeyValuePair<Rule ^,float> >^ FindAllRulesMatchingCriteria( System::Collections::IDictionary ^facts );
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/// please be careful
|
||||
ResponseSystemImplementationCLI *GetNativePtr();
|
||||
|
||||
protected:
|
||||
// Deallocate the native object on the finalizer just in case no destructor is called
|
||||
!ResponseSystemCLI() ;
|
||||
ResponseSystemImplementationCLI *m_pImpl;
|
||||
|
||||
void TurnIDictIntoCriteriaSet( System::Collections::IDictionary ^facts, ResponseRules::CriteriaSet *critset );
|
||||
Rule ^RuleFromIdx( ResponseRules::ResponseRulePartition::tIndex idx );
|
||||
|
||||
private:
|
||||
CriterionDictWrapper_t ^m_CriteriaDict;
|
||||
ResponseGroupDictWrapper_t ^m_ResponseGroupsDict;
|
||||
// EnumerationDictWrapper_t ^m_EnumerationsDict;
|
||||
RulesAsList ^m_RulesContainer;
|
||||
};
|
||||
}
|
445
responserules/responserules_cli/responserules_cli.vcproj
Normal file
445
responserules/responserules_cli/responserules_cli.vcproj
Normal file
@ -0,0 +1,445 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="responserules_cli"
|
||||
ProjectGUID="{0BA4E446-7651-4CC5-917F-6AC6B8A5C097}"
|
||||
RootNamespace="responserules_cli"
|
||||
Keyword="ManagedCProj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)..\bin"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
ManagedExtensions="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\..\"
|
||||
PreprocessorDefinitions="WIN32;DEBUG;COMPILER_MSVC;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_DLL_EXT=.dll;COMPILER_MSVC32"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="tier0.lib tier1.lib tier2.lib vstdlib.lib interfaces.lib appframework.lib responserules_runtime.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\..\lib\public"
|
||||
IgnoreDefaultLibraryNames="LIBCMT.lib;LIBCMTD.lib"
|
||||
GenerateDebugInformation="true"
|
||||
AssemblyDebug="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="copy to devtools\bin"
|
||||
CommandLine="if exist ..\..\devtools\responseeditor\. goto ValveStart
mkdir ..\..\devtools\responseeditor
:ValveStart
call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetFileName) ..\..
copy "$(TargetDir)"$(TargetFileName) ..\..\devtools\responseeditor\.\$(TargetFileName)
if ERRORLEVEL 1 goto BuildEventFailed
if exist "$(TargetDir)\bin"$(TargetName).map copy "$(TargetDir)"$(TargetName).map ..\..\devtools\responseeditor\.\$(TargetName).map
call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetName).pdb ..\..
copy "$(TargetDir)"$(TargetName).pdb ..\..\devtools\responseeditor\.\$(TargetName).pdb 
if ERRORLEVEL 1 goto BuildEventFailed
goto BuildEventOK
:BuildEventFailed
echo *** ERROR! PostBuildStep FAILED for $(ProjectName)! EXE or DLL is probably running. ***
del /q "$(TargetDir)"$(TargetFileName)
exit 1
:BuildEventOK
"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)..\bin"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="1"
|
||||
ManagedExtensions="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories="..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\..\"
|
||||
PreprocessorDefinitions="WIN32;RELEASE;COMPILER_MSVC;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_DLL_EXT=.dll;COMPILER_MSVC32"
|
||||
RuntimeLibrary="2"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="tier0.lib tier1.lib tier2.lib vstdlib.lib interfaces.lib appframework.lib responserules_runtime.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\..\lib\public"
|
||||
IgnoreDefaultLibraryNames="LIBCMT.lib"
|
||||
GenerateDebugInformation="true"
|
||||
LinkTimeCodeGeneration="0"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
Description="copy to devtools\bin"
|
||||
CommandLine="if exist ..\..\devtools\responseeditor\. goto ValveStart
mkdir ..\..\devtools\responseeditor
:ValveStart
call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetFileName) ..\..
copy "$(TargetDir)"$(TargetFileName) ..\..\devtools\responseeditor\.\$(TargetFileName)
if ERRORLEVEL 1 goto BuildEventFailed
if exist "$(TargetDir)\bin"$(TargetName).map copy "$(TargetDir)"$(TargetName).map ..\..\devtools\responseeditor\.\$(TargetName).map
call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetName).pdb ..\..
copy "$(TargetDir)"$(TargetName).pdb ..\..\devtools\responseeditor\.\$(TargetName).pdb 
if ERRORLEVEL 1 goto BuildEventFailed
goto BuildEventOK
:BuildEventFailed
echo *** ERROR! PostBuildStep FAILED for $(ProjectName)! EXE or DLL is probably running. ***
del /q "$(TargetDir)"$(TargetFileName)
exit 1
:BuildEventOK
"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
<AssemblyReference
|
||||
RelativePath="System.dll"
|
||||
AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
|
||||
MinFrameworkVersion="131072"
|
||||
/>
|
||||
<AssemblyReference
|
||||
RelativePath="System.Data.dll"
|
||||
AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
|
||||
MinFrameworkVersion="131072"
|
||||
/>
|
||||
<AssemblyReference
|
||||
RelativePath="System.XML.dll"
|
||||
AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
|
||||
MinFrameworkVersion="131072"
|
||||
/>
|
||||
<AssemblyReference
|
||||
RelativePath="WindowsBase.dll"
|
||||
AssemblyName="WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"
|
||||
MinFrameworkVersion="196608"
|
||||
/>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AssemblyInfo.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cli_appsystem_thunk.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cli_appsystem_unmanaged_wrapper.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\engine_emulator.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\response_system.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\response_types_marshal.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\responserules_cli.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="2"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Stdafx.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlcontainer_cli.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="public"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\public\filesystem_helpers.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/U "_UNICODE" /U "UNICODE""
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/U "_UNICODE" /U "UNICODE""
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\filesystem_init.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/U "_UNICODE" /U "UNICODE""
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/U "_UNICODE" /U "UNICODE""
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\utils\common\filesystem_tools.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/U "_UNICODE" /U "UNICODE""
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/U "_UNICODE" /U "UNICODE""
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\cli_appsystem_adapter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cli_appsystem_thunk.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\cli_appsystem_unmanaged_wrapper.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\responserules\response_host_interface.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\response_system.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\responserules\response_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\response_types_marshal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\response_types_marshal_wrappers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\responserules_cli.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\public\responserules\rr_speechconcept.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\utlcontainer_cli.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\app.ico"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\app.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
5
responserules/responserules_cli/utlcontainer_cli.cpp
Normal file
5
responserules/responserules_cli/utlcontainer_cli.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "utlcontainer_cli.h"
|
||||
|
||||
|
||||
// CCLIUtlDictEnumerable< int, int > foo();
|
833
responserules/responserules_cli/utlcontainer_cli.h
Normal file
833
responserules/responserules_cli/utlcontainer_cli.h
Normal file
@ -0,0 +1,833 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Wrappers to turn various Source Utl* containers into CLR
|
||||
// enumerables.
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef UTLCONTAINER_CLI_H
|
||||
#define UTLCONTAINER_CLI_H
|
||||
|
||||
#if defined( _WIN32 )
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/// Handy wrapper to turn any indexing property into
|
||||
/// an IList (assuming it is numbered 0..count). You
|
||||
/// need only initialize it with a delegate that yields
|
||||
/// int->type and another that gets the count.
|
||||
generic< typename T >
|
||||
public ref class IndexPropertyToIListReadOnly : public System::Collections::Generic::IList<T>
|
||||
{
|
||||
public:
|
||||
delegate T lGetter( int idx ); // will wrap the indexer
|
||||
delegate int lCounter( ); // will wrap the counter
|
||||
|
||||
IndexPropertyToIListReadOnly( lGetter ^getter, lCounter ^counter )
|
||||
{
|
||||
m_getterFunc = getter;
|
||||
m_counterFunc = counter;
|
||||
}
|
||||
|
||||
/*
|
||||
virtual ~IndexPropertyToIListReadOnly( ) { !IndexPropertyToIListReadOnly( ); }
|
||||
virtual !IndexPropertyToIListReadOnly( ) {}
|
||||
*/
|
||||
|
||||
property int Count
|
||||
{
|
||||
virtual int get() { return m_counterFunc(); }
|
||||
}
|
||||
|
||||
#pragma region IList<T> Members
|
||||
|
||||
virtual int IndexOf(T item)
|
||||
{
|
||||
int count = Count::get();
|
||||
for ( int i = 0 ; i < count ; ++i )
|
||||
{
|
||||
if ( item->Equals( m_getterFunc(i) ) )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual void Insert(int index, T item)
|
||||
{
|
||||
throw gcnew NotSupportedException( "Read-only." );
|
||||
}
|
||||
|
||||
virtual void RemoveAt(int index)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
property T default[int]
|
||||
{
|
||||
virtual T get(int index)
|
||||
{
|
||||
if ( index < 0 || index > Count::get() )
|
||||
{
|
||||
throw gcnew ArgumentOutOfRangeException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_getterFunc(index);
|
||||
}
|
||||
|
||||
}
|
||||
virtual void set(int index, T to)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region ICollection<T> Members
|
||||
|
||||
virtual void Add(T item)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
virtual void Clear()
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
virtual bool Contains(T item)
|
||||
{
|
||||
return IndexOf(item) != -1;
|
||||
}
|
||||
|
||||
virtual void CopyTo( cli::array<T,1> ^arr, int start)
|
||||
{
|
||||
int stop = Count::get();
|
||||
for (int i = 0 ; i < stop ; ++i )
|
||||
{
|
||||
arr->SetValue((*this)[i],start+i);
|
||||
}
|
||||
// throw gcnew NotImplementedException();
|
||||
}
|
||||
|
||||
property bool IsReadOnly
|
||||
{
|
||||
virtual bool get() { return true; }
|
||||
}
|
||||
|
||||
virtual bool Remove(T item)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Enumerator
|
||||
ref class LinearEnumerator : System::Collections::Generic::IEnumerator<T>
|
||||
{
|
||||
// Enumerators are positioned before the first element
|
||||
// until the first MoveNext() call.
|
||||
int position;
|
||||
public:
|
||||
LinearEnumerator(IndexPropertyToIListReadOnly<T> ^owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
position = -1;
|
||||
}
|
||||
~LinearEnumerator(){};
|
||||
!LinearEnumerator(){};
|
||||
|
||||
virtual bool MoveNext()
|
||||
{
|
||||
position++;
|
||||
return ( position < m_owner->Count );
|
||||
}
|
||||
|
||||
virtual void Reset()
|
||||
{
|
||||
position = -1;
|
||||
}
|
||||
|
||||
virtual property T Current
|
||||
{
|
||||
virtual T get() = System::Collections::Generic::IEnumerator<T>::Current::get
|
||||
{
|
||||
if ( position >= 0 && position < m_owner->Count )
|
||||
{
|
||||
return m_owner[position];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual property System::Object^ CurrentAgainBecauseCPP_CLISucks
|
||||
{
|
||||
virtual System::Object^ get() = System::Collections::IEnumerator::Current::get
|
||||
{
|
||||
if ( position >= 0 && position < m_owner->Count )
|
||||
{
|
||||
return m_owner[position];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IndexPropertyToIListReadOnly<T> ^m_owner;
|
||||
};
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IEnumerable<T> Members
|
||||
|
||||
virtual System::Collections::Generic::IEnumerator<T> ^ GetEnumerator()
|
||||
{
|
||||
return gcnew LinearEnumerator(this);
|
||||
}
|
||||
|
||||
virtual System::Collections::IEnumerator^ GetEnumerator2() = System::Collections::IEnumerable::GetEnumerator
|
||||
{
|
||||
return gcnew LinearEnumerator(this);
|
||||
}
|
||||
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
protected:
|
||||
lGetter ^m_getterFunc;
|
||||
lCounter ^m_counterFunc;
|
||||
};
|
||||
|
||||
#if 0
|
||||
/// <summary>
|
||||
/// Tiny class that wraps an indexing property in a class with an IList interface
|
||||
/// so that the WPF databinding can access it.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Assumes that all indexes are from 0..count.
|
||||
/// </remarks>
|
||||
/// <typeparam name="U"> The type of the class whose property we wrap </typeparam>
|
||||
/// <typeparam name="T"> The type of the value returned from the class property </typeparam>
|
||||
public class BindingWrapper<T> : IList<T>, INotifyCollectionChanged
|
||||
{
|
||||
// lambda types. You'll pass in one of each of these with the constructor.
|
||||
/// <summary>
|
||||
/// Given an int, return the i-th element of wrapper property in owning class.
|
||||
/// </summary>
|
||||
public delegate T lGetter( int idx );
|
||||
|
||||
/// <summary>
|
||||
/// Given an int, return the i-th element of wrapper property in owning class.
|
||||
/// </summary>
|
||||
public delegate int lCounter( );
|
||||
|
||||
public BindingWrapper( /*U owner,*/ lGetter getter, lCounter counter )
|
||||
{
|
||||
// m_owner = owner;
|
||||
m_getterFunc = getter;
|
||||
m_counterFunc = counter;
|
||||
}
|
||||
|
||||
#region IList<T> Members
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
/*
|
||||
// hang onto this number
|
||||
int count = Count;
|
||||
for (int i = 0 ; i < count ; ++i )
|
||||
{
|
||||
if (this[i] == item)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
*/
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
throw new NotSupportedException( "Read-only." );
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
throw new NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index < 0 || index > Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_getterFunc(index);
|
||||
}
|
||||
|
||||
}
|
||||
set
|
||||
{
|
||||
throw new NotSupportedException("Read-only.");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ICollection<T> Members
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
throw new NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
throw new NotSupportedException("Noncopyable.");
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return m_counterFunc(); }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
throw new NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Enumerator
|
||||
public class LinearEnumerator : System.Collections.IEnumerator
|
||||
{
|
||||
// Enumerators are positioned before the first element
|
||||
// until the first MoveNext() call.
|
||||
int position = -1;
|
||||
|
||||
public LinearEnumerator(BindingWrapper<T> owner)
|
||||
{
|
||||
m_owner = owner;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
position++;
|
||||
return ( position < m_owner.Count );
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
position = -1;
|
||||
}
|
||||
|
||||
public Object Current
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_owner[position];
|
||||
}
|
||||
catch (IndexOutOfRangeException)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BindingWrapper<T> m_owner;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEnumerable<T> Members
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
throw new NotImplementedException(); // return new LinearEnumerator(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region IEnumerable Members
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return new LinearEnumerator(this);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region INotifyCollectionChanged
|
||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||
public virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (CollectionChanged != null)
|
||||
{
|
||||
CollectionChanged(this, e);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private data
|
||||
// U m_owner;
|
||||
lGetter m_getterFunc;
|
||||
lCounter m_counterFunc;
|
||||
#endregion
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// Common code for classes that wrap native RR
|
||||
/// types. You have the option to make a COPY
|
||||
/// rather than a pointer to the native class:
|
||||
/// in that case, the constructor here new's a copy
|
||||
/// of the given type on the heap, and the finalizer
|
||||
/// deletes it.
|
||||
/// It may be necessary to specialize the constructor
|
||||
/// in certain cases where a managed function is not
|
||||
/// allowed to new the given type.
|
||||
/// Subclass this with a CLI version of the wrapped
|
||||
/// class and create whatever accessor properties you
|
||||
/// would like to expose to the managed side.
|
||||
template< typename T >
|
||||
public ref class NativeTypeCopyWrapper
|
||||
{
|
||||
public:
|
||||
NativeTypeCopyWrapper( ) : m_pNative(NULL), m_bIsCopy(true) {};
|
||||
NativeTypeCopyWrapper( T* from ) // this overload assumes no copy
|
||||
{
|
||||
m_bIsCopy = false;
|
||||
if ( false )
|
||||
{
|
||||
m_pNative = new T( *from );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pNative = from;
|
||||
}
|
||||
}
|
||||
NativeTypeCopyWrapper( T* from, bool bCopy )
|
||||
{
|
||||
m_bIsCopy = bCopy;
|
||||
if ( bCopy )
|
||||
{
|
||||
m_pNative = new T( *from );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pNative = from;
|
||||
}
|
||||
}
|
||||
~NativeTypeCopyWrapper() { this->!NativeTypeCopyWrapper(); }
|
||||
!NativeTypeCopyWrapper()
|
||||
{
|
||||
if ( m_bIsCopy )
|
||||
delete m_pNative;
|
||||
|
||||
m_pNative = NULL;
|
||||
}
|
||||
// copy constructor
|
||||
NativeTypeCopyWrapper(NativeTypeCopyWrapper% r)
|
||||
{
|
||||
m_bIsCopy = r->m_bIsCopy;
|
||||
if (m_bIsCopy)
|
||||
m_pNative = new T( *r->GetNativePtr() );
|
||||
else
|
||||
m_pNative = r->GetNativePtr();
|
||||
}
|
||||
|
||||
inline bool IsValid( ) { return m_pNative != NULL; }
|
||||
|
||||
/// use the assignment operator on the internal native type, copying
|
||||
/// over the one in the given FROM class, and make me point to it.
|
||||
/// So named to be explicit about what's happening, and because I'm
|
||||
/// not sure what happens when you = on a ref.
|
||||
void Assign( NativeTypeCopyWrapper^ from )
|
||||
{
|
||||
*m_pNative = *from.m_pNative;
|
||||
}
|
||||
|
||||
/// please be careful
|
||||
T* GetNativePtr() { return m_pNative; }
|
||||
|
||||
protected:
|
||||
T* m_pNative;
|
||||
bool m_bIsCopy;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// CUtlDict as enumerable.
|
||||
#include "utldict.h"
|
||||
|
||||
/*
|
||||
template <class T, class I>
|
||||
class CUtlDict
|
||||
*/
|
||||
|
||||
namespace Tier1CLI
|
||||
{
|
||||
namespace Containers
|
||||
{
|
||||
public interface class INotifiableList
|
||||
: public System::Collections::IList ,
|
||||
public System::Collections::Specialized::INotifyCollectionChanged
|
||||
{
|
||||
virtual void OnCollectionChanged(System::Collections::Specialized::NotifyCollectionChangedEventArgs ^e) = 0;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// A class that wraps a tier1 CUtlDict in a way that can be iterated over from C#.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The CONVERTOR template parameter below shall be the class
|
||||
/// that wraps the native C++ * type into a CLR reference type.
|
||||
/// It should have a constructor that takes a parameter of type
|
||||
/// T* , which will be called like:
|
||||
/// return gcnew CONVERTOR(T *foo);
|
||||
/// </remarks>
|
||||
template <class T, typename I, class CONVERTOR = NativeTypeCopyWrapper<T> >
|
||||
public ref class CCLIUtlDictEnumerable : // public System::Collections::IEnumerable,
|
||||
public Tier1CLI::Containers::INotifiableList
|
||||
{
|
||||
public:
|
||||
typedef CUtlDict< T,I > dict_t;
|
||||
typedef CONVERTOR value_t;
|
||||
typedef const char * key_t;
|
||||
|
||||
#pragma region Enumeration interface
|
||||
ref struct tuple_t
|
||||
{
|
||||
key_t key;
|
||||
value_t ^val;
|
||||
I index;
|
||||
|
||||
inline tuple_t( const key_t &k, T &v, I i ) : key(k), index(i)
|
||||
{
|
||||
val = gcnew CONVERTOR( &v, i );
|
||||
};
|
||||
|
||||
// conversions to CLR types
|
||||
property System::String^ Name
|
||||
{
|
||||
System::String^ get()
|
||||
{
|
||||
return gcnew String(key);
|
||||
}
|
||||
}
|
||||
property CONVERTOR^ Val
|
||||
{
|
||||
CONVERTOR^ get()
|
||||
{
|
||||
return val;
|
||||
}
|
||||
}
|
||||
property I Index
|
||||
{
|
||||
I get()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
// convenience functions for WPF databindings, which may hand back a
|
||||
// tuple_t object to C#, which can't get at the typedefs above.
|
||||
// this can cause trouble with getting at the properties; rather than
|
||||
// use reflection, you can just use these.
|
||||
System::String^ NameFor( tuple_t ^ tup )
|
||||
{
|
||||
return tup->Name;
|
||||
}
|
||||
value_t^ ValFor( tuple_t ^ tup )
|
||||
{
|
||||
return tup->Val;
|
||||
}
|
||||
*/
|
||||
|
||||
CONVERTOR ^GetValue( I idx )
|
||||
{
|
||||
return gcnew CONVERTOR(m_pInnerDict->Element(idx));
|
||||
}
|
||||
|
||||
CONVERTOR ^GetKey( I idx )
|
||||
{
|
||||
return gcnew String(m_pInnerDict->GetElementName(idx));
|
||||
}
|
||||
|
||||
property int Count
|
||||
{
|
||||
virtual int get() { return m_pInnerDict->Count(); }
|
||||
}
|
||||
|
||||
/// Iterator type. Walks over the UtlDict in the same order as its
|
||||
/// internal iterator. Returns a tuple of <key,value>, where key is
|
||||
/// always a string type (as in the utldict).
|
||||
/// TODO: can I make this a value struct so it doesn't need to be
|
||||
/// boxed/unboxed?
|
||||
ref struct Enumerator : public System::Collections::IEnumerator
|
||||
{
|
||||
typedef CCLIUtlDictEnumerable<T,I> owner_t;
|
||||
|
||||
Enumerator( dict_t *pDict ) : m_pEnumeratedDict(pDict), m_bIsBefore(true)
|
||||
{
|
||||
m_index = dict_t::InvalidIndex();
|
||||
}
|
||||
|
||||
inline bool IsValid()
|
||||
{
|
||||
return m_pEnumeratedDict->IsValidIndex(m_index);
|
||||
}
|
||||
|
||||
// IEnumerator interface
|
||||
virtual void Reset()
|
||||
{
|
||||
m_bIsBefore = true;
|
||||
m_index = m_pEnumeratedDict->First();
|
||||
}
|
||||
|
||||
// return false when falling off the end
|
||||
virtual bool MoveNext()
|
||||
{
|
||||
if (m_bIsBefore)
|
||||
{
|
||||
m_bIsBefore = false;
|
||||
m_index = m_pEnumeratedDict->First();
|
||||
return IsValid();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !IsValid() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_index = m_pEnumeratedDict->Next( m_index );
|
||||
return IsValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property System::Object^ Current
|
||||
{
|
||||
virtual System::Object^ get()
|
||||
{
|
||||
if ( IsValid() )
|
||||
{
|
||||
return gcnew tuple_t( m_pEnumeratedDict->GetElementName(m_index),
|
||||
m_pEnumeratedDict->Element(m_index),
|
||||
m_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew System::InvalidOperationException();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// data:
|
||||
protected:
|
||||
I m_index;
|
||||
dict_t *m_pEnumeratedDict;
|
||||
bool m_bIsBefore;
|
||||
};
|
||||
|
||||
virtual System::Collections::IEnumerator^ GetEnumerator()
|
||||
{
|
||||
return gcnew Enumerator(m_pInnerDict);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
bool IsValidIndex( I idx ) { return m_pInnerDict->IsValidIndex(idx); }
|
||||
tuple_t ^GetElement( I i )
|
||||
{
|
||||
return gcnew tuple_t( m_pInnerDict->GetElementName(i),
|
||||
m_pInnerDict->Element(i),
|
||||
i);
|
||||
}
|
||||
|
||||
#pragma region ILIST interface
|
||||
|
||||
virtual int IndexOf( System::Object ^obj )
|
||||
{
|
||||
tuple_t ^t = dynamic_cast< tuple_t ^>(obj);
|
||||
if (t)
|
||||
{
|
||||
return t->index;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew System::ArrayTypeMismatchException();
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool Contains( System::Object ^obj )
|
||||
{
|
||||
tuple_t ^t = dynamic_cast< tuple_t ^>(obj);
|
||||
if (t)
|
||||
{
|
||||
return IsValidIndex(t->index);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw gcnew System::ArrayTypeMismatchException();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Insert(int index, System::Object ^ item)
|
||||
{
|
||||
throw gcnew NotSupportedException( "Read-only." );
|
||||
}
|
||||
|
||||
virtual void Remove(System::Object ^)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
virtual void RemoveAt(int index)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
virtual int Add(System::Object ^o)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
virtual void Clear()
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
|
||||
virtual property Object ^ SyncRoot
|
||||
{
|
||||
Object ^ get() { return this; }
|
||||
}
|
||||
|
||||
virtual void CopyTo(Array ^arr, int start)
|
||||
{
|
||||
int stop = Count::get();
|
||||
for (int i = 0 ; i < stop ; ++i )
|
||||
{
|
||||
arr->SetValue((*this)[i],start+i);
|
||||
}
|
||||
// throw gcnew NotImplementedException();
|
||||
}
|
||||
|
||||
property System::Object ^ default[int]
|
||||
{
|
||||
virtual System::Object ^get( int index )
|
||||
{
|
||||
if (index < 0 || index > Count)
|
||||
{
|
||||
throw gcnew ArgumentOutOfRangeException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetElement(index);
|
||||
}
|
||||
|
||||
}
|
||||
virtual void set(int idx, System::Object ^s)
|
||||
{
|
||||
throw gcnew NotSupportedException("Read-only.");
|
||||
}
|
||||
}
|
||||
|
||||
property bool IsReadOnly
|
||||
{
|
||||
virtual bool get() { return true; }
|
||||
}
|
||||
|
||||
property bool IsFixedSize
|
||||
{
|
||||
virtual bool get() { return true; }
|
||||
}
|
||||
|
||||
property bool IsSynchronized
|
||||
{
|
||||
virtual bool get() { return true; }
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region INotifyCollectionChanged interface
|
||||
|
||||
System::Collections::Specialized::NotifyCollectionChangedEventHandler ^m_CollectionChanged;
|
||||
virtual event System::Collections::Specialized::NotifyCollectionChangedEventHandler ^CollectionChanged
|
||||
{
|
||||
void add(System::Collections::Specialized::NotifyCollectionChangedEventHandler ^ d) {
|
||||
m_CollectionChanged += d;
|
||||
}
|
||||
void remove(System::Collections::Specialized::NotifyCollectionChangedEventHandler ^ d) {
|
||||
m_CollectionChanged -= d;
|
||||
}
|
||||
}
|
||||
virtual void OnCollectionChanged(System::Collections::Specialized::NotifyCollectionChangedEventArgs ^e)
|
||||
{
|
||||
if (m_CollectionChanged != nullptr)
|
||||
{
|
||||
m_CollectionChanged(this, e);
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
|
||||
/// construct with a pointer at a UtlDict. Does not
|
||||
/// own the pointer; simply stores it internally.
|
||||
CCLIUtlDictEnumerable( dict_t *pInnerDict )
|
||||
//: m_CollectionChanged(gcnew System::Collections::Specialized::NotifyCollectionChangedEventHandler )
|
||||
{
|
||||
Init(pInnerDict);
|
||||
};
|
||||
CCLIUtlDictEnumerable( ) :m_pInnerDict(NULL)//
|
||||
//,m_CollectionChanged(gcnew System::Collections::Specialized::NotifyCollectionChangedEventHandler )
|
||||
{ };
|
||||
|
||||
void Init( dict_t *pInnerDict )
|
||||
{
|
||||
m_pInnerDict = pInnerDict;
|
||||
}
|
||||
|
||||
protected:
|
||||
dict_t *m_pInnerDict;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user