uid issue

This commit is contained in:
KittenPopo
2021-07-24 21:11:47 -07:00
commit c2130ba4e9
13850 changed files with 6241419 additions and 0 deletions

View 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)];

View 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.
/////////////////////////////////////////////////////////////////////////////

View 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"

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View 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

View 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

View 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) );
}

View 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

View File

@ -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();
}

View File

@ -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

View 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, "{}()':" );
}

View File

@ -0,0 +1,3 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by app.rc

View 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)

View 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

View 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]);
}

View 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

View File

@ -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

View 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
*/

View 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;
};
}

View 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&#x0D;&#x0A;mkdir ..\..\devtools\responseeditor&#x0D;&#x0A;:ValveStart&#x0D;&#x0A;call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetFileName) ..\..&#x0D;&#x0A;copy &quot;$(TargetDir)&quot;$(TargetFileName) ..\..\devtools\responseeditor\.\$(TargetFileName)&#x0D;&#x0A;if ERRORLEVEL 1 goto BuildEventFailed&#x0D;&#x0A;if exist &quot;$(TargetDir)\bin&quot;$(TargetName).map copy &quot;$(TargetDir)&quot;$(TargetName).map ..\..\devtools\responseeditor\.\$(TargetName).map&#x0D;&#x0A;call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetName).pdb ..\..&#x0D;&#x0A;copy &quot;$(TargetDir)&quot;$(TargetName).pdb ..\..\devtools\responseeditor\.\$(TargetName).pdb &#x0D;&#x0A;if ERRORLEVEL 1 goto BuildEventFailed&#x0D;&#x0A;goto BuildEventOK&#x0D;&#x0A;:BuildEventFailed&#x0D;&#x0A;echo *** ERROR! PostBuildStep FAILED for $(ProjectName)! EXE or DLL is probably running. ***&#x0D;&#x0A;del /q &quot;$(TargetDir)&quot;$(TargetFileName)&#x0D;&#x0A;exit 1&#x0D;&#x0A;:BuildEventOK&#x0D;&#x0A;"
/>
</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&#x0D;&#x0A;mkdir ..\..\devtools\responseeditor&#x0D;&#x0A;:ValveStart&#x0D;&#x0A;call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetFileName) ..\..&#x0D;&#x0A;copy &quot;$(TargetDir)&quot;$(TargetFileName) ..\..\devtools\responseeditor\.\$(TargetFileName)&#x0D;&#x0A;if ERRORLEVEL 1 goto BuildEventFailed&#x0D;&#x0A;if exist &quot;$(TargetDir)\bin&quot;$(TargetName).map copy &quot;$(TargetDir)&quot;$(TargetName).map ..\..\devtools\responseeditor\.\$(TargetName).map&#x0D;&#x0A;call ..\..\vpc_scripts\valve_p4_edit.cmd ..\..\devtools\responseeditor\.\$(TargetName).pdb ..\..&#x0D;&#x0A;copy &quot;$(TargetDir)&quot;$(TargetName).pdb ..\..\devtools\responseeditor\.\$(TargetName).pdb &#x0D;&#x0A;if ERRORLEVEL 1 goto BuildEventFailed&#x0D;&#x0A;goto BuildEventOK&#x0D;&#x0A;:BuildEventFailed&#x0D;&#x0A;echo *** ERROR! PostBuildStep FAILED for $(ProjectName)! EXE or DLL is probably running. ***&#x0D;&#x0A;del /q &quot;$(TargetDir)&quot;$(TargetFileName)&#x0D;&#x0A;exit 1&#x0D;&#x0A;:BuildEventOK&#x0D;&#x0A;"
/>
</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 &quot;_UNICODE&quot; /U &quot;UNICODE&quot;"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/U &quot;_UNICODE&quot; /U &quot;UNICODE&quot;"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\public\filesystem_init.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/U &quot;_UNICODE&quot; /U &quot;UNICODE&quot;"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/U &quot;_UNICODE&quot; /U &quot;UNICODE&quot;"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\utils\common\filesystem_tools.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/U &quot;_UNICODE&quot; /U &quot;UNICODE&quot;"
UsePrecompiledHeader="0"
CompileAsManaged="0"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/U &quot;_UNICODE&quot; /U &quot;UNICODE&quot;"
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>

View File

@ -0,0 +1,5 @@
#include "stdafx.h"
#include "utlcontainer_cli.h"
// CCLIUtlDictEnumerable< int, int > foo();

View 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