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,14 @@
<Application x:Class="ResponseEditor.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ResponseEditor"
xmlns:as="clr-namespace:ManagedAppSystem;assembly=responserules_cli"
StartupUri="Window1.xaml"
Startup="Application_Startup"
>
<Application.Resources>
<!-- Initialize global app system interface. -->
<as:AppSystemWrapper x:Key="AppSystem" />
<local:ResponseSystemWPF x:Key="ResponseSystem" />
</Application.Resources>
</Application>

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using ResponseRulesCLI;
using ManagedAppSystem;
namespace ResponseEditor
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public App()
{
// m_responseDatabase = new ResponseDatabase();
// Resources["ResponseDatabase"] = m_responseDatabase;
}
private void Application_Startup(object sender, StartupEventArgs e)
{
// This forces initialization of the app system on start up.
Resources["AppSystem"] = new AppSystemWrapper();
}
}
}

View File

@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ResponseEditor
{
/// <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 class DummyCriterion
{
/// <summary>
/// Encapsulates the comparison of a value against this 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.
///
/// Right now this is a complete mockup since the actual matching code is all in the
/// C++ side.
/// </remarks>
public class Matcher
{
public Matcher(string text)
{
this.text = text;
}
/// <summary>
/// Test to see if a given value from a query matches this criterion
/// </summary>
/// <param name="crit">The criterion to be matched (usually contains this matcher)</param>
/// <param name="queryValue">The value to be tested, AKA the context.</param>
bool Test( DummyCriterion crit, string queryValue)
{
throw new System.NotImplementedException("DummyCriterion::Matcher::Test() is not actually implemented.");
}
/// <summary>
/// The actual text of the matcher from the source file. May be null (implies ==)
/// </summary>
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
public override string ToString()
{
return Text;
}
};
public DummyCriterion(string key, string value, float weight, bool required, Matcher comparison)
{
this.key = key;
this.value = value;
this.weight = weight;
this.required = required;
this.comparison = comparison;
}
private string key;
private string value;
private float weight;
private bool required;
private Matcher comparison;
public string Key
{
get { return key; }
// set { key = value; }
}
public string Value
{
get { return this.value; }
// set { this.value = value; }
}
public bool Required
{
get { return required; }
// set { required = value; }
}
public Matcher Comparison
{
get { return comparison; }
// set { comparison = value; }
}
public float Weight
{
get { return weight; }
// set { weight = value; }
}
/// dummy criteria data for testing
public static DummyCriterion[] g_DummyCriteria =
{
new DummyCriterion( "foo", "1", 1, false, new Matcher(">") ),
new DummyCriterion( "bar", "soup", 1, false, new Matcher("") ),
new DummyCriterion( "Concept", "Talk", 1, true, new Matcher("") )
};
}
}

View File

@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// 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: AssemblyTitle("ResponseEditor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Valve")]
[assembly: AssemblyProduct("ResponseEditor")]
[assembly: AssemblyCopyright("Copyright © Valve 2009")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3082
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ResponseEditor.Properties
{
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ResponseEditor.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3082
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ResponseEditor.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{639289AE-64D7-4839-92EE-0A0C495477EC}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ResponseEditor</RootNamespace>
<AssemblyName>ResponseEditor</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>../ResponseEditorFoo/</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\devtools\responseeditor\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\devtools\responseeditor\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="responserules_cli, Version=1.0.3440.21239, Culture=neutral, processorArchitecture=x86">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\bin\responserules_cli.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data.DataSetExtensions">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WPFToolkit, Version=3.5.40128.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Window1.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Window1.xaml.cs">
<DependentUpon>Window1.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<Compile Include="Criterion.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="ResponseSystemWPF.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
<Visible>False</Visible>
<ProductName>.NET Framework 2.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0">
<Visible>False</Visible>
<ProductName>.NET Framework 3.0 %28x86%29</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<PropertyGroup>
<PostBuildEvent>
</PostBuildEvent>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,106 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using ResponseRulesCLI;
using Tier1CLI.Containers;
namespace ResponseEditor
{
/// <summary>
/// Wraps the ResponseSystemCLI with some additional glue that makes the WPF go.
/// </summary>
public class ResponseSystemWPF : ResponseRulesCLI.ResponseSystemCLI
{
#region Interface Wrappers
public Tier1CLI.Containers.INotifiableList ResponseGroupBinding
{
get { return ResponseGroupsDict; }
}
public Tier1CLI.Containers.INotifiableList CriteriaBinding
{
get { return CriteriaDict; }
}
/*
public Tier1CLI.Containers.INotifiableList EnumerationsBinding
{
get { return EnumerationsDict; }
}
*/
public RulesAsList RulesBinding
{
get { return Rules; }
}
public override void LoadFromFile( String filename )
{
base.LoadFromFile(filename);
ResponseGroupBinding.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
CriteriaBinding.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
RulesBinding.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
// EnumerationsBinding.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
RefreshShadowLists();
}
#endregion
public ResponseSystemWPF()
{
ResponseRulesCLI.SingletonResponseSystem_t.RS = this;
CriteriaBinding.CollectionChanged += this.OnCriteriaChanged;
m_concepts = new ObservableCollection<string>();
}
#region Shadow Lists
public ObservableCollection<String> ConceptsShadow
{
get { return m_concepts; }
}
void OnCriteriaChanged( object sender, NotifyCollectionChangedEventArgs args )
{
RefreshShadowLists();
}
void RefreshShadowLists()
{
// Do the concepts
m_concepts.Clear();
List<string> tempconcepts = new List<string>();
// use reflection to fish out the Val prop.
PropertyInfo valprop = CriteriaBinding[0].GetType().GetProperty("Val");
foreach ( Object tupletype in CriteriaBinding )
{
Criterion crit = (Criterion)valprop.GetValue(tupletype, null);
if ( crit.Key.Equals("concept", StringComparison.OrdinalIgnoreCase ) )
{
tempconcepts.Add(crit.Value);
}
}
tempconcepts.Sort();
foreach ( string s in tempconcepts )
{
m_concepts.Add(s);
}
}
#endregion
#region Local private data.
// Here's some local conveniences for making the debugger pane.
ObservableCollection<String> m_concepts;
#endregion
}
}

View File

@ -0,0 +1,239 @@
<Window x:Class="ResponseEditor.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tk="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:local="clr-namespace:ResponseEditor"
xmlns:rr="clr-namespace:ResponseRulesCLI;assembly=responserules_cli"
xmlns:as="clr-namespace:ManagedAppSystem;assembly=responserules_cli"
x:Name="MainAppWindow"
DataContext="{Binding ElementName=MainAppWindow}"
Title="Response Editor" Height="768" Width="1024">
<Window.Resources>
<local:ObservableCollectionOfRules x:Key="RulesMatchingDebuggerCriterion"/>
</Window.Resources>
<!-- ***************************** WINDOW! ********************************* -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TabControl>
<TabItem Header="Criteria">
<!--
<ListBox Name="criteriaListBox" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding Source={StaticResource ResponseSystem}, Path=CriteriaBinding}"
ItemTemplate="{StaticResource CriteriaInListBoxTemplate}" />
-->
<tk:DataGrid x:Name="CriteriaGrid" ItemsSource="{Binding Source={StaticResource ResponseSystem}, Path=CriteriaBinding, Mode=OneWay}" AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=Name, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=Val.Key, Mode=OneWay}" Header="Key" />
<tk:DataGridTextColumn Binding="{Binding Path=Val.Value, Mode=OneWay}" Header="Value" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=Val.Required, Mode=OneWay}" Header="Required?" />
<!--
<tk:DataGridTextColumn Binding="{Binding Path=Val.Comparison.Description, Mode=OneWay}" Header="Comparison" />
-->
<tk:DataGridTextColumn Binding="{Binding Path=Val.Weight, Mode=OneWay}" Header="Weight" />
</tk:DataGrid.Columns>
</tk:DataGrid>
</TabItem>
<TabItem Header="Responses" DataContext="{Binding Source={StaticResource ResponseSystem}, Path=ResponseGroupBinding, Mode=OneWay}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="4" />
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<tk:DataGrid x:Name="ResponseGroupsMaster" IsSynchronizedWithCurrentItem="True" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Mode=OneWay}" AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=Name, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=Val.Count, Mode=OneWay}" Header="Count" />
</tk:DataGrid.Columns>
</tk:DataGrid>
<GridSplitter Grid.Row="1" ResizeDirection="Rows" Width="Auto" Height="4" HorizontalAlignment="Stretch" Margin="0" />
<tk:DataGrid x:Name="ResponseGroupsDetail" Grid.Row="2" ItemsSource="{Binding Path=Val.ResponsesList }" AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=type, Mode=OneWay}" Header="Type" />
<tk:DataGridTextColumn Binding="{Binding Path=value, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=weight, Mode=OneWay}" Header="Weight" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=DisplayFirst, Mode=OneWay}" Header="First" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=DisplayLast, Mode=OneWay}" Header="Last" />
<!-- responseparams -->
<tk:DataGridCheckBoxColumn Binding="{Binding Path=params.IsSpeakOnce, Mode=OneWay}" Header="Last" />
<tk:DataGridTextColumn Binding="{Binding Path=params.delay, Mode=OneWay}" Header="Delay" />
<tk:DataGridTextColumn Binding="{Binding Path=params.respeakdelay, Mode=OneWay}" Header="RespkDelay" />
<tk:DataGridTextColumn Binding="{Binding Path=params.predelay, Mode=OneWay}" Header="PreDelay" />
<tk:DataGridTextColumn Binding="{Binding Path=params.odds, Mode=OneWay}" Header="Odds" />
<tk:DataGridTextColumn Binding="{Binding Path=params.soundlevel, Mode=OneWay}" Header="Sndlevel" />
<!-- <tk:DataGridTextColumn Binding="{Binding Path=Val.Count, Mode=OneWay}" Header="Count" /> -->
</tk:DataGrid.Columns>
</tk:DataGrid>
</Grid>
</TabItem>
<TabItem Header="Rules" Loaded="OnRulesTabLoaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="16"/>
<RowDefinition Height="*"/>
<RowDefinition Height="4" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- ROW 0 -->
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" FontSize="14">RULES</TextBlock>
<!-- ROW 1 -->
<tk:DataGrid x:Name="RulesGrid" Grid.Row="1"
ItemsSource="{Binding Source={StaticResource ResponseSystem}, Path=RulesBinding, Mode=OneWay}" AutoGenerateColumns="False"
SelectionChanged="RulesGrid_SelectionChanged" IsSynchronizedWithCurrentItem="True"
>
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=Name, Mode=OneWay}" Header="Name" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=MatchOnce, Mode=OneWay}" Header="MatchOnce" />
<tk:DataGridTextColumn Binding="{Binding Path=NumResponses, Mode=OneWay}" Header="NumResponses" />
<tk:DataGridTextColumn Binding="{Binding Path=NumCriteria, Mode=OneWay}" Header="NumCriteria" />
<tk:DataGridTextColumn Binding="{Binding Path=Context, Mode=OneWay}" Header="Context" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=IsApplyContextToWorld, Mode=OneWay}" Header="Context Applies&#x0a;To World" />
</tk:DataGrid.Columns>
</tk:DataGrid>
<GridSplitter Grid.Row="2" ResizeDirection="Rows" Width="Auto" Height="4" HorizontalAlignment="Stretch" Margin="0" />
<Grid Grid.Row="3">
<Grid.RowDefinitions>
<RowDefinition Height="16"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- COLUMN 0 -->
<TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" FontSize="14">CRITERIA</TextBlock>
<tk:DataGrid x:Name="CriteriaGridInRulesPane" Grid.Row="1" Grid.Column="0"
AutoGenerateColumns="False" HorizontalAlignment="Stretch" ColumnWidth="Auto" >
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=Name, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=Val.Key, Mode=OneWay}" Header="Key" />
<tk:DataGridTextColumn Binding="{Binding Path=Val.Value, Mode=OneWay}" Header="Value" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=Val.Required, Mode=OneWay}" Header="Required?" />
<!--
<tk:DataGridTextColumn Binding="{Binding Path=Val.Comparison.Description, Mode=OneWay}" Header="Comparison" />
-->
<tk:DataGridTextColumn Binding="{Binding Path=Val.Weight, Mode=OneWay}" Header="Weight" />
</tk:DataGrid.Columns>
</tk:DataGrid>
<!-- COLUMN 1 -->
<GridSplitter Grid.RowSpan="2" Width="4" />
<!-- COLUMN 2 -->
<TextBlock Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" FontSize="14">RESPONSES</TextBlock>
<tk:DataGrid x:Name="ResponseGridInRulesPane" Grid.Row="1" Grid.Column="1"
AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=Name, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=Val.Count, Mode=OneWay}" Header="Count" />
</tk:DataGrid.Columns>
</tk:DataGrid>
</Grid>
</Grid>
</TabItem>
<TabItem Header="Debugger" Loaded="OnDebuggerTabLoaded">
<Grid FlowDirection="LeftToRight">
<Grid.RowDefinitions>
<RowDefinition Height="52"/>
<RowDefinition />
<RowDefinition Height="4" />
<RowDefinition />
</Grid.RowDefinitions>
<!-- ROW 0 -->
<StackPanel Orientation="Horizontal">
<DockPanel Height="Auto" Width="Auto" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Top" >
<TextBlock DockPanel.Dock="Top" Margin="5,5,0,0">
CONCEPT
</TextBlock>
<ComboBox Height="25" Margin="0,0,0,0" Name="DebugTabConceptComboBox" SelectionChanged="DebugTabConceptComboBox_SelectionChanged"
ItemsSource="{Binding Source={StaticResource ResponseSystem}, Path=ConceptsShadow, Mode=OneWay}"
HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" DockPanel.Dock="Top" />
</DockPanel>
<DockPanel Height="Auto" Margin="15,0,0,0" Width="Auto" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Top" >
<TextBlock DockPanel.Dock="Top" Margin="5,5,0,0" >
FACTS (contexts) key1:val1,key2:val2,...
</TextBlock>
<TextBox DockPanel.Dock="Top" Height="25" Name="DebugTabFactsTextBox" Width="340" LostFocus="DebugTabFactsTextBox_LostFocus" KeyDown="DebugTabFactsTextBox_KeyDown" />
</DockPanel>
</StackPanel>
<!-- ROW 1 -->
<tk:DataGrid x:Name="DebuggerRulesGrid" Grid.Row="1"
ItemsSource="{Binding Source={StaticResource RulesMatchingDebuggerCriterion}, Mode=OneWay}" AutoGenerateColumns="False"
SelectionChanged="DebuggerRuleGrid_SelectionChanged" >
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=Key.Name, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=Value, Mode=OneWay}" Header="Score" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=Key.MatchOnce, Mode=OneWay}" Header="MatchOnce" />
<tk:DataGridTextColumn Binding="{Binding Path=Key.NumResponses, Mode=OneWay}" Header="NumResponses" />
<tk:DataGridTextColumn Binding="{Binding Path=Key.NumCriteria, Mode=OneWay}" Header="NumCriteria" />
<tk:DataGridTextColumn Binding="{Binding Path=Key.Context, Mode=OneWay}" Header="Context" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=Key.IsApplyContextToWorld, Mode=OneWay}" Header="Context Applies&#x0a;To World" />
</tk:DataGrid.Columns>
</tk:DataGrid>
<!-- ROW 2 -->
<GridSplitter Grid.Row="2" ResizeDirection="Rows" Width="Auto" Height="4" HorizontalAlignment="Stretch" Margin="0" />
<!-- ROW 3 -->
<Grid Grid.Row="3" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<tk:DataGrid x:Name="ResponseGridInDebuggerPane" Grid.Row="0" Grid.Column="0" AutoGenerateColumns="False"
SelectionChanged="DebuggerResponseGroupGrid_SelectionChanged" >
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=Name, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=Val.Count, Mode=OneWay}" Header="Count" />
<!-- "<tk:DataGridTextColumn Binding="{Binding Path=Val.ResponsesList[0].value, Mode=OneWay}" Header="Example vcd" /> -->
</tk:DataGrid.Columns>
</tk:DataGrid>
<GridSplitter Grid.RowSpan="1" Width="4" />
<tk:DataGrid x:Name="DebuggerResponseGroupsDetail"
Grid.Row="0" Grid.Column="1" AutoGenerateColumns="False">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding Path=type, Mode=OneWay}" Header="Type" />
<tk:DataGridTextColumn Binding="{Binding Path=value, Mode=OneWay}" Header="Name" />
<tk:DataGridTextColumn Binding="{Binding Path=weight, Mode=OneWay}" Header="Weight" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=DisplayFirst, Mode=OneWay}" Header="First" />
<tk:DataGridCheckBoxColumn Binding="{Binding Path=DisplayLast, Mode=OneWay}" Header="Last" />
<!-- responseparams -->
<tk:DataGridCheckBoxColumn Binding="{Binding Path=params.IsSpeakOnce, Mode=OneWay}" Header="Last" />
<tk:DataGridTextColumn Binding="{Binding Path=params.delay, Mode=OneWay}" Header="Delay" />
<tk:DataGridTextColumn Binding="{Binding Path=params.respeakdelay, Mode=OneWay}" Header="RespkDelay" />
<tk:DataGridTextColumn Binding="{Binding Path=params.predelay, Mode=OneWay}" Header="PreDelay" />
<tk:DataGridTextColumn Binding="{Binding Path=params.odds, Mode=OneWay}" Header="Odds" />
<tk:DataGridTextColumn Binding="{Binding Path=params.soundlevel, Mode=OneWay}" Header="Sndlevel" />
<!-- <tk:DataGridTextColumn Binding="{Binding Path=Val.Count, Mode=OneWay}" Header="Count" /> -->
</tk:DataGrid.Columns>
</tk:DataGrid>
</Grid>
</Grid>
</TabItem>
</TabControl>
<Button Grid.Row="1" HorizontalAlignment="Right" Name="button1" Width="Auto" Click="button1_Click" Height="20" VerticalAlignment="Bottom">LOAD</Button>
</Grid>
</Window>

View File

@ -0,0 +1,369 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Win32;
using ResponseRulesCLI;
using ManagedAppSystem;
namespace ResponseEditor
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
// m_RulesMatchingDebuggerCriterion = new ObservableCollection<Rule>();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
// MessageBox.Show("CLICK!");
// MessageBox.Show(Resources["AppSystem"].ToString());
// AppSystemWrapper appSys = new AppSystemWrapper();
// CritGrid.ItemsSource = RRSys.CriteriaBinding;
// Resources["CritGrid"].ItemsSource = RRSys.CriteriaBinding;
// get a filename from the dialog box.
string filename = null;
{
// Configure open file dialog box
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.FileName = "response_rules.txt"; // Default file name
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text (.txt)|*.txt"; // Filter files by extension
string searchdir = System.IO.Path.Combine(Environment.GetEnvironmentVariable("VGAME"),
Environment.GetEnvironmentVariable("VMOD"));
if ( searchdir.Length > 4 )
{
dlg.InitialDirectory = System.IO.Path.Combine(searchdir, "scripts/talker");
}
else
{
dlg.InitialDirectory = Directory.GetCurrentDirectory();
}
// Show open file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process open file dialog box results
if (result == true)
{
// Open document
filename = dlg.FileName;
}
else
{ // cancelled
return;
}
}
if ( System.IO.File.Exists( filename ) )
{
// get the local modpath directory from the given filename.
string basedir = System.IO.Path.GetDirectoryName(filename);
// check to make sure that "scripts/talker" is in there somewhere,
// and if not, bitch.
bool bIsScriptsTalkerDir = (basedir.Contains("scripts/talker") || basedir.Contains("scripts\\talker"));
if ( !bIsScriptsTalkerDir )
{
MessageBox.Show("File is not in a 'scripts/talker' directory; #includes may not work properly.",
"Minor Annoyance");
}
else
{
// walk up two levels in the directory name.
basedir = Directory.GetParent(basedir).Parent.FullName;
}
AppSys.SetFileSystemSearchRoot(basedir);
// load just the bare file name.
RRSys.LoadFromFile(filename);
}
else
{
MessageBox.Show("That was a bad file name; no responses loaded.");
}
/*
foreach ( Object i in (System.Collections.IEnumerable)(RRSys.CriteriaBinding) )
{
Criterion c = (Criterion)i.GetType().GetProperty("Val").GetValue(i, null);
// MessageBox.Show( c.GetType().GetProperty("Key").GetValue(c,null).ToString() );
}
*/
}
#region Member data for all panes
public ResponseSystemWPF RRSys
{
get { return (ResponseSystemWPF)this.FindResource("ResponseSystem"); }
}
public AppSystemWrapper AppSys
{
get { return (AppSystemWrapper)this.FindResource("AppSystem"); }
}
#endregion
#region Criterion Pane
private void CritGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
#endregion
#region Rules pane
public void OnRulesTabLoaded(Object sender, RoutedEventArgs args)
{
ViewForCriteriaPanelInRulesPane = new ListCollectionView(RRSys.CriteriaBinding);
ViewForResponsePanelInRulesPane = new ListCollectionView(RRSys.ResponseGroupBinding);
}
public ListCollectionView ViewForCriteriaPanelInRulesPane;
public ListCollectionView ViewForResponsePanelInRulesPane;
private void RulesGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 1)
{
MessageBox.Show("How can you select more than one rule?");
}
if (e.AddedItems.Count == 0)
{
ViewForCriteriaPanelInRulesPane.Filter = null;
ViewForResponsePanelInRulesPane.Filter = null;
}
else
{
Rule r = e.AddedItems[0] as Rule;
ViewForCriteriaPanelInRulesPane.Filter = MakeCriterionFilterForRule(r);
ViewForResponsePanelInRulesPane.Filter = MakeResponseFilterForRule(r);
}
Binding b = new Binding();
b.Source = ViewForCriteriaPanelInRulesPane;
b.Mode = BindingMode.OneWay;
CriteriaGridInRulesPane.SetBinding(ItemsControl.ItemsSourceProperty, b);
b = new Binding();
b.Source = ViewForResponsePanelInRulesPane;
b.Mode = BindingMode.OneWay;
ResponseGridInRulesPane.SetBinding(ItemsControl.ItemsSourceProperty, b);
}
private Predicate<object> MakeCriterionFilterForRule( Rule r )
{
// make a closure scanning the response dict for just this rule's criteria.
ResponseSystemWPF ResponseRuleSystem = RRSys;
return x =>
{
int idx = ResponseRuleSystem.CriteriaBinding.IndexOf(x); ;
for ( int i = 0 ; i < r.NumCriteria ; i++ )
{
if (r.get_CriteriaIndices(i) == idx)
return true;
}
return false;
};
}
private Predicate<object> MakeResponseFilterForRule(Rule r)
{
// make a closure scanning the response dict for just this rule's responses.
ResponseSystemWPF ResponseRuleSystem = RRSys;
// CLI seems to be having trouble with typedefs, so for now introspect the
// necesasry properties
System.Reflection.PropertyInfo valprop = RRSys.ResponseGroupsDict[0].GetType().GetProperty("Val");
return x =>
{
// clumsy hack to filter out NullResponse
ResponseGroup g = valprop.GetValue(x, null) as ResponseGroup;
if (g.Count < 1)
return false;
int idx = ResponseRuleSystem.ResponseGroupBinding.IndexOf(x);
for (int i = 0; i < r.NumCriteria; i++)
{
if (r.get_ResponseIndices(i) == idx)
return true;
}
return false;
};
}
#endregion
#region Debugger Pane
public void OnDebuggerTabLoaded(Object sender, RoutedEventArgs args)
{
ViewForResponsePanelInDebuggerPane = new ListCollectionView(RRSys.ResponseGroupBinding);
}
public ListCollectionView ViewForResponsePanelInDebuggerPane;
// private Binding BindingForResponseDetailInDebuggerPane;
private void DebugTabConceptComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// need to use event parameter rather than contents of combo box as
// the combo box's text hasn't actually been set yet
if ( e.AddedItems.Count > 0 )
{
DisplayBestRuleForConcept(e.AddedItems[0].ToString(), DebugTabFactsTextBox.Text);
}
else
{
ObservableCollectionOfRules collection = (ObservableCollectionOfRules)this.FindResource("RulesMatchingDebuggerCriterion");
collection.Clear();
}
}
private void DebuggerRuleGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0)
{
ViewForResponsePanelInDebuggerPane.Filter = null;
}
else
{
Rule r = ((KeyValuePair<Rule, float>) e.AddedItems[0]).Key as Rule;
ViewForResponsePanelInDebuggerPane.Filter = MakeResponseFilterForRule(r);
}
Binding b = new Binding();
b.Source = ViewForResponsePanelInDebuggerPane;
b.Mode = BindingMode.OneWay;
ResponseGridInDebuggerPane.SetBinding(ItemsControl.ItemsSourceProperty, b);
}
private void DebuggerResponseGroupGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
/*
if (BindingForResponseDetailInDebuggerPane == null)
{
BindingForResponseDetailInDebuggerPane = new Binding();
BindingForResponseDetailInDebuggerPane.Mode = BindingMode.OneWay;
DebuggerResponseGroupsDetail.SetBinding(ItemsControl.ItemsSourceProperty, BindingForResponseDetailInDebuggerPane);
}
*/
if (e.AddedItems.Count == 0)
{
DebuggerResponseGroupsDetail.SetBinding(ItemsControl.ItemsSourceProperty, (System.Windows.Data.BindingBase)null);
}
else
{
// icky use of metadata
ResponseGroup g = e.AddedItems[0].GetType().GetProperty("Val").GetValue(e.AddedItems[0], null) as ResponseGroup;
Binding b = new Binding();
b.Source = new ListCollectionView(g.ResponsesList);
b.Mode = BindingMode.OneWay;
DebuggerResponseGroupsDetail.SetBinding(ItemsControl.ItemsSourceProperty, b);
}
}
private void DebugTabFactsTextBox_LostFocus(object sender, RoutedEventArgs e)
{
DisplayBestRuleForConcept(DebugTabConceptComboBox.Text, DebugTabFactsTextBox.Text);
}
private void DebugTabFactsTextBox_KeyDown(object sender, KeyEventArgs e)
{
if ( e.Key == Key.Enter )
{
DisplayBestRuleForConcept(DebugTabConceptComboBox.Text, DebugTabFactsTextBox.Text);
}
}
void DisplayBestRuleForConcept( string concept, string factstring )
{
ObservableCollectionOfRules collection = (ObservableCollectionOfRules)this.FindResource("RulesMatchingDebuggerCriterion");
collection.Clear();
System.Collections.Generic.SortedList<string, string> facts = new System.Collections.Generic.SortedList<string, string>();
facts.Add("concept", concept);
AddColumnColonToDictionary(facts, factstring);
foreach ( KeyValuePair<Rule, float> pair in RRSys.FindAllRulesMatchingCriteria(facts) )
{
collection.Add(pair);
}
/*
Rule bestMatchingRule = RRSys.FindBestMatchingRule( facts );
if ( bestMatchingRule != null )
{
collection.Add(bestMatchingRule);
}
*/
}
/// <summary>
/// Temp: turn context1:value1,context2:value2,... into a dict
/// </summary>
static void AddColumnColonToDictionary( System.Collections.Generic.SortedList<string, string> facts,
string input )
{
string[] pairs = input.Split(',');
foreach( string p in pairs )
{
string[] kv = p.Split(':');
if ( kv.Length >= 2 )
facts.Add(kv[0], kv[1]);
}
}
/*
public ObservableCollection<Rule> RulesMatchingDebuggerCriterion
{
get { return m_RulesMatchingDebuggerCriterion; }
}
*/
/// <summary>
/// TODO
/// </summary>
void QueryResponseSystemWithDebuggerData()
{
}
// ObservableCollection<Rule> m_RulesMatchingDebuggerCriterion;
#endregion
}
public class ObservableCollectionOfRules : ObservableCollection<KeyValuePair<Rule,float>> { };
}

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

View File

@ -0,0 +1,52 @@
// ----------------------------------------- //
// File generated by VPC //
// ----------------------------------------- //
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\criteriaset.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\criteriaset.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\criteriaset.cpp
Containing unity file:
PCH file:
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\common\debug_lib_check.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\common\debug_lib_check.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\common\debug_lib_check.cpp
Containing unity file:
PCH file:
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_system.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_system.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_system.cpp
Containing unity file:
PCH file:
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_types.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_types.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_types.cpp
Containing unity file:
PCH file:
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_types_internal.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_types_internal.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\response_types_internal.cpp
Containing unity file:
PCH file:
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rr_response.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rr_response.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rr_response.cpp
Containing unity file:
PCH file:
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rr_speechconcept.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rr_speechconcept.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rr_speechconcept.cpp
Containing unity file:
PCH file:
Source file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rrrlib.cpp
Debug output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rrrlib.cpp
Release output file: D:\Users\berta\Downloads\csgosourcecode\cstrike15_src\responserules\runtime\rrrlib.cpp
Containing unity file:
PCH file:

View File

@ -0,0 +1,470 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#include "rrbase.h"
#include "utlmap.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace ResponseRules;
//-----------------------------------------------------------------------------
// Case-insensitive criteria symbol table
//-----------------------------------------------------------------------------
CUtlSymbolTable CriteriaSet::sm_CriteriaSymbols( 1024, 1024, true );
//-----------------------------------------------------------------------------
// Purpose:
// Input : *raw -
// *key -
// keylen -
// *value -
// valuelen -
// *duration -
// Output : static bool
//-----------------------------------------------------------------------------
const char *SplitContext( const char *raw, char *key, int keylen, char *value, int valuelen, float *duration, const char *entireContext )
{
char *colon1 = Q_strstr( raw, ":" );
if ( !colon1 )
{
DevMsg( "SplitContext: warning, ignoring context '%s', missing colon separator!\n", raw );
*key = *value = 0;
return NULL;
}
int len = colon1 - raw;
Q_strncpy( key, raw, MIN( len + 1, keylen ) );
key[ MIN( len, keylen - 1 ) ] = 0;
bool last = false;
char *end = Q_strstr( colon1 + 1, "," );
if ( !end )
{
int remaining = Q_strlen( colon1 + 1 );
end = colon1 + 1 + remaining;
last = true;
}
char *colon2 = Q_strstr( colon1 + 1, ":" );
if ( colon2 && ( colon2 < end ) )
{
if ( duration )
*duration = atof( colon2 + 1 );
char durationStartChar = *(colon2 + 1);
if ( durationStartChar < '0' || durationStartChar > '9' )
{
DevMsg( "SplitContext: warning, ignoring context '%s', missing comma separator! Entire context was '%s'.\n", raw, entireContext );
*key = *value = 0;
return NULL;
}
len = MIN( colon2 - ( colon1 + 1 ), valuelen - 1 );
Q_strncpy( value, colon1 + 1, len + 1 );
value[ len ] = 0;
}
else
{
if ( duration )
*duration = 0.0;
len = MIN( end - ( colon1 + 1 ), valuelen - 1 );
Q_strncpy( value, colon1 + 1, len + 1 );
value[ len ] = 0;
}
return last ? NULL : end + 1;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CriteriaSet::CriteriaSet() : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_bOverrideOnAppend(true),
m_nNumPrefixedContexts(0)
{
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CriteriaSet::CriteriaSet( const CriteriaSet& src ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_nNumPrefixedContexts(src.m_nNumPrefixedContexts)
{
m_Lookup.EnsureCapacity( src.m_Lookup.Count() );
for ( short i = src.m_Lookup.FirstInorder();
i != src.m_Lookup.InvalidIndex();
i = src.m_Lookup.NextInorder( i ) )
{
m_Lookup.Insert( src.m_Lookup[ i ] );
}
}
CriteriaSet::CriteriaSet( const char *criteria, const char *value ) : m_Lookup( 0, 0, CritEntry_t::LessFunc ), m_bOverrideOnAppend(true)
{
AppendCriteria(criteria,value);
}
//-----------------------------------------------------------------------------
// Computes a symbol for the criteria
//-----------------------------------------------------------------------------
CriteriaSet::CritSymbol_t CriteriaSet::ComputeCriteriaSymbol( const char *criteria )
{
return sm_CriteriaSymbols.AddString( criteria );
}
//-----------------------------------------------------------------------------
// Computes a symbol for the criteria
//-----------------------------------------------------------------------------
void CriteriaSet::AppendCriteria( CriteriaSet::CritSymbol_t criteria, const char *value, float weight )
{
int idx = FindCriterionIndex( criteria );
if ( idx == -1 )
{
CritEntry_t entry;
entry.criterianame = criteria;
MEM_ALLOC_CREDIT();
idx = m_Lookup.Insert( entry );
if ( sm_CriteriaSymbols.String(criteria)[0] == kAPPLYTOWORLDPREFIX )
{
m_nNumPrefixedContexts += 1;
}
}
else // criteria already existed
{
// bail out if override existing criteria is not allowed
if ( !m_bOverrideOnAppend )
return;
}
CritEntry_t *entry = &m_Lookup[ idx ];
entry->SetValue( value );
entry->weight = weight;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *criteria -
// "" -
// 1.0f -
//-----------------------------------------------------------------------------
void CriteriaSet::AppendCriteria( const char *pCriteriaName, const char *value /*= ""*/, float weight /*= 1.0f*/ )
{
CUtlSymbol criteria = ComputeCriteriaSymbol( pCriteriaName );
AppendCriteria( criteria, value, weight );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *criteria -
// "" -
// 1.0f -
//-----------------------------------------------------------------------------
void CriteriaSet::AppendCriteria( const char *criteria, float value, float weight /*= 1.0f*/ )
{
char buf[32];
V_snprintf( buf, 32, "%f", value );
AppendCriteria( criteria, buf, weight );
}
//-----------------------------------------------------------------------------
// Removes criteria in a set
//-----------------------------------------------------------------------------
void CriteriaSet::RemoveCriteria( const char *criteria )
{
const int idx = FindCriterionIndex( criteria );
if ( idx == -1 )
return;
if ( criteria[0] == kAPPLYTOWORLDPREFIX )
{
Assert( m_nNumPrefixedContexts > 0 );
m_nNumPrefixedContexts = isel( m_nNumPrefixedContexts - 1, m_nNumPrefixedContexts - 1, 0 );
}
RemoveCriteria( idx, false );
}
// bTestForIndex tells us whether the calling function has already checked for a
// $ prefix and decremented m_nNumPrefixedContexts appropriately (false),
// or if this function should do that (true).
void CriteriaSet::RemoveCriteria( int idx, bool bTestForPrefix )
{
Assert( m_Lookup.IsValidIndex(idx) );
if ( bTestForPrefix )
{
if ( sm_CriteriaSymbols.String( m_Lookup[idx].criterianame )[0] == kAPPLYTOWORLDPREFIX )
{
Assert( m_nNumPrefixedContexts > 0 );
m_nNumPrefixedContexts = isel( m_nNumPrefixedContexts - 1, m_nNumPrefixedContexts - 1, 0 );
}
}
m_Lookup.RemoveAt( idx );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : int
//-----------------------------------------------------------------------------
int CriteriaSet::GetCount() const
{
return m_Lookup.Count();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *name -
// Output : int
//-----------------------------------------------------------------------------
int CriteriaSet::FindCriterionIndex( CritSymbol_t criteria ) const
{
CritEntry_t search;
search.criterianame = criteria;
int idx = m_Lookup.Find( search );
return ( idx == m_Lookup.InvalidIndex() ) ? -1 : idx;
}
int CriteriaSet::FindCriterionIndex( const char *name ) const
{
CUtlSymbol criteria = ComputeCriteriaSymbol( name );
return FindCriterionIndex( criteria );
}
//-----------------------------------------------------------------------------
// Returns the name symbol
//-----------------------------------------------------------------------------
CriteriaSet::CritSymbol_t CriteriaSet::GetNameSymbol( int nIndex ) const
{
if ( nIndex < 0 || nIndex >= (int)m_Lookup.Count() )
return UTL_INVAL_SYMBOL;
const CritEntry_t *entry = &m_Lookup[ nIndex ];
return entry->criterianame;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : index -
// Output : char const
//-----------------------------------------------------------------------------
const char *CriteriaSet::GetName( int index ) const
{
if ( index < 0 || index >= (int)m_Lookup.Count() )
return "";
else
{
const char *pCriteriaName = sm_CriteriaSymbols.String( m_Lookup[ index ].criterianame );
return pCriteriaName ? pCriteriaName : "";
}
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : index -
// Output : char const
//-----------------------------------------------------------------------------
const char *CriteriaSet::GetValue( int index ) const
{
if ( index < 0 || index >= (int)m_Lookup.Count() )
return "";
const CritEntry_t *entry = &m_Lookup[ index ];
return entry->value ? entry->value : "";
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : index -
// Output : float
//-----------------------------------------------------------------------------
float CriteriaSet::GetWeight( int index ) const
{
if ( index < 0 || index >= (int)m_Lookup.Count() )
return 1.0f;
const CritEntry_t *entry = &m_Lookup[ index ];
return entry->weight;
}
//-----------------------------------------------------------------------------
// Purpose: Merge another criteria set into this one.
//-----------------------------------------------------------------------------
void CriteriaSet::Merge( const CriteriaSet * RESTRICT otherCriteria )
{
Assert(otherCriteria);
if (!otherCriteria)
return;
// for now, just duplicate everything.
int count = otherCriteria->GetCount();
EnsureCapacity( count + GetCount() );
for ( int i = 0 ; i < count ; ++i )
{
AppendCriteria( otherCriteria->GetNameSymbol(i), otherCriteria->GetValue(i), otherCriteria->GetWeight(i) );
}
}
void CriteriaSet::Merge( const char *modifiers ) // add criteria parsed from a text string
{
// Always include any optional modifiers
if ( modifiers == NULL )
return;
char copy_modifiers[ 255 ];
const char *pCopy;
char key[ 128 ] = { 0 };
char value[ 128 ] = { 0 };
Q_strncpy( copy_modifiers, modifiers, sizeof( copy_modifiers ) );
pCopy = copy_modifiers;
while( pCopy )
{
pCopy = SplitContext( pCopy, key, sizeof( key ), value, sizeof( value ), NULL, modifiers );
if( *key && *value )
{
AppendCriteria( key, value, 1 );
}
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CriteriaSet::Describe() const
{
// build an alphabetized representation of the set for printing
typedef CUtlMap<const char *, const CritEntry_t *> tMap;
tMap m_TempMap( 0, m_Lookup.Count(), CaselessStringLessThan );
for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) )
{
const CritEntry_t *entry = &m_Lookup[ i ];
m_TempMap.Insert( sm_CriteriaSymbols.String( entry->criterianame ), entry );
}
for ( tMap::IndexType_t i = m_TempMap.FirstInorder(); i != m_TempMap.InvalidIndex(); i = m_TempMap.NextInorder( i ) )
{
// const CritEntry_t *entry = &m_TempMap[ i ];
// const char *pCriteriaName = sm_CriteriaSymbols.String( entry->criterianame );
const char *name;
name = m_TempMap.Key( i );
const CritEntry_t *entry = m_TempMap.Element( i );
if ( entry->weight != 1.0f )
{
DevMsg( " %20s = '%s' (weight %f)\n", name, entry->value ? entry->value : "", entry->weight );
}
else
{
DevMsg( " %20s = '%s'\n", name, entry->value ? entry->value : "" );
}
}
/*
for ( short i = m_Lookup.FirstInorder(); i != m_Lookup.InvalidIndex(); i = m_Lookup.NextInorder( i ) )
{
const CritEntry_t *entry = &m_Lookup[ i ];
const char *pCriteriaName = sm_CriteriaSymbols.String( entry->criterianame );
if ( entry->weight != 1.0f )
{
DevMsg( " %20s = '%s' (weight %f)\n", pCriteriaName, entry->value ? entry->value : "", entry->weight );
}
else
{
DevMsg( " %20s = '%s'\n", pCriteriaName, entry->value ? entry->value : "" );
}
}
*/
}
void CriteriaSet::Reset()
{
m_Lookup.Purge();
}
void CriteriaSet::WriteToEntity( CBaseEntity *pEntity )
{
#if 0
if ( GetCount() < 1 )
return;
for ( int i = Head() ; IsValidIndex(i); i = Next(i) )
{
pEntity->AddContext( GetName(i), GetValue(i), 0 );
}
#else
AssertMsg( false, "CriteriaSet::WriteToEntity has not been ported from l4d2.\n" );
#endif
}
int CriteriaSet::InterceptWorldSetContexts( CriteriaSet * RESTRICT pFrom, CriteriaSet * RESTRICT pSetOnWorld )
{
// Assert( pFrom ); Assert( pTo ); Assert( pSetOnWorld );
Assert( pSetOnWorld != pFrom );
Assert( pSetOnWorld->GetCount() == 0 );
if ( pFrom->m_nNumPrefixedContexts == 0 )
{
// nothing needs to be done to it.
return 0;
}
#ifdef DEBUG
// save this off for later error checking.
const int nPrefixedContexts = pFrom->m_nNumPrefixedContexts;
#endif
// make enough space for the expected output quantity.
pSetOnWorld->EnsureCapacity( pFrom->m_nNumPrefixedContexts );
// initialize a buffer with the "world" prefix (so we can use strncpy instead of snprintf and be much faster)
char buf[80] = { 'w', 'o', 'r', 'l', 'd', '\0' };
const unsigned int PREFIXLEN = 5; // strlen("world")
// create a second tree that has the appropriately renamed criteria,
// then swap it into pFrom
CriteriaSet rewrite;
rewrite.EnsureCapacity( pFrom->GetCount() + 1 );
for ( int i = pFrom->Head(); pFrom->IsValidIndex(i); i = pFrom->Next(i) )
{
const char *pszName = pFrom->GetName( i );
if ( pszName[0] == CriteriaSet::kAPPLYTOWORLDPREFIX )
{ // redirect to the world contexts
V_strncpy( buf+PREFIXLEN, pszName+1, sizeof(buf) - PREFIXLEN );
rewrite.AppendCriteria( buf, pFrom->GetValue(i), pFrom->GetWeight(i) );
pSetOnWorld->AppendCriteria( pszName+1, pFrom->GetValue(i), pFrom->GetWeight(i) );
buf[PREFIXLEN] = 0;
}
else
{ // does not need to be fiddled; do not write back to world
rewrite.AppendCriteria( pFrom->GetNameSymbol(i), pFrom->GetValue(i), pFrom->GetWeight(i) );
}
}
AssertMsg2( pSetOnWorld->GetCount() == nPrefixedContexts, "Count of $ persistent RR contexts is inconsistent (%d vs %d)! Call Elan.",
pSetOnWorld->GetCount(), nPrefixedContexts );
pFrom->m_nNumPrefixedContexts = 0;
pFrom->m_Lookup.Swap(rewrite.m_Lookup);
return pSetOnWorld->GetCount();
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,260 @@
//========= Copyright <20> 1996-2010, Valve Corporation, All rights reserved. ============//
//
// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers.
//
// $NoKeywords: $
//=============================================================================//
#include "rrbase.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace ResponseRules;
// bizarre function handed down from the misty days of yore
// and the original response system. a lot of stuff uses it
// and I can't be arsed to replace everything with the c stdlib
// stuff
namespace ResponseRules
{
extern const char *ResponseCopyString( const char *in );
};
//-------------------- MATCHER ----------------------------------------------
Matcher::Matcher()
{
valid = false;
isnumeric = false;
notequal = false;
usemin = false;
minequals = false;
usemax = false;
maxequals = false;
maxval = 0.0f;
minval = 0.0f;
token = UTL_INVAL_SYMBOL;
rawtoken = UTL_INVAL_SYMBOL;
}
void Matcher::Describe( void )
{
if ( !valid )
{
DevMsg( " invalid!\n" );
return;
}
char sz[ 128 ];
sz[ 0] = 0;
int minmaxcount = 0;
if ( usemin )
{
Q_snprintf( sz, sizeof( sz ), ">%s%.3f", minequals ? "=" : "", minval );
minmaxcount++;
}
if ( usemax )
{
char sz2[ 128 ];
Q_snprintf( sz2, sizeof( sz2 ), "<%s%.3f", maxequals ? "=" : "", maxval );
if ( minmaxcount > 0 )
{
Q_strncat( sz, " and ", sizeof( sz ), COPY_ALL_CHARACTERS );
}
Q_strncat( sz, sz2, sizeof( sz ), COPY_ALL_CHARACTERS );
minmaxcount++;
}
if ( minmaxcount >= 1 )
{
DevMsg( " matcher: %s\n", sz );
return;
}
if ( notequal )
{
DevMsg( " matcher: !=%s\n", GetToken() );
return;
}
DevMsg( " matcher: ==%s\n", GetToken() );
}
void Matcher::SetToken( char const *s )
{
token = g_RS.AddString( s );
}
void Matcher::SetRaw( char const *raw )
{
rawtoken = g_RS.AddString( raw );
}
char const *Matcher::GetToken()
{
if ( token.IsValid() )
{
return g_RS.String( token );
}
return "";
}
char const *Matcher::GetRaw()
{
if ( rawtoken.IsValid() )
{
return g_RS.String( rawtoken );
}
return "";
}
//-------------------- CRITERIA ----------------------------------------------
Criteria::Criteria()
{
value = NULL;
weight.SetFloat( 1.0f );
required = false;
}
Criteria::Criteria(const Criteria& src )
{
operator=( src );
}
Criteria::~Criteria()
{
// do nothing because we don't own name and value anymore
}
Criteria& Criteria::operator =(const Criteria& src )
{
if ( this == &src )
return *this;
nameSym = src.nameSym;
value = ResponseCopyString( src.value );
weight = src.weight;
required = src.required;
matcher = src.matcher;
int c = src.subcriteria.Count();
subcriteria.EnsureCapacity( c );
for ( int i = 0; i < c; i++ )
{
subcriteria.AddToTail( src.subcriteria[ i ] );
}
return *this;
}
//-------------------- RESPONSE ----------------------------------------------
ParserResponse::ParserResponse() : m_followup()
{
type = RESPONSE_NONE;
value = NULL;
weight.SetFloat( 1.0f );
depletioncount = 0;
first = false;
last = false;
}
ParserResponse& ParserResponse::operator =( const ParserResponse& src )
{
if ( this == &src )
return *this;
weight = src.weight;
type = src.type;
value = ResponseCopyString( src.value );
depletioncount = src.depletioncount;
first = src.first;
last = src.last;
params = src.params;
m_followup.followup_concept = ResponseCopyString(src.m_followup.followup_concept);
m_followup.followup_contexts = ResponseCopyString(src.m_followup.followup_contexts);
m_followup.followup_target = ResponseCopyString(src.m_followup.followup_target);
m_followup.followup_entityioinput = ResponseCopyString(src.m_followup.followup_entityioinput);
m_followup.followup_entityiotarget = ResponseCopyString(src.m_followup.followup_entityiotarget);
m_followup.followup_delay = src.m_followup.followup_delay;
m_followup.followup_entityiodelay = src.m_followup.followup_entityiodelay;
return *this;
}
ParserResponse::ParserResponse( const ParserResponse& src )
{
operator=( src );
}
ParserResponse::~ParserResponse()
{
// nothing to do, since we don't own
// the strings anymore
}
// ------------ RULE ---------------
Rule::Rule() : m_nForceWeight(0)
{
m_bMatchOnce = false;
m_bEnabled = true;
m_szContext = NULL;
m_bApplyContextToWorld = false;
}
Rule& Rule::operator =( const Rule& src )
{
if ( this == &src )
return *this;
int i;
int c;
c = src.m_Criteria.Count();
m_Criteria.EnsureCapacity( c );
for ( i = 0; i < c; i++ )
{
m_Criteria.AddToTail( src.m_Criteria[ i ] );
}
c = src.m_Responses.Count();
m_Responses.EnsureCapacity( c );
for ( i = 0; i < c; i++ )
{
m_Responses.AddToTail( src.m_Responses[ i ] );
}
SetContext( src.m_szContext );
m_bMatchOnce = src.m_bMatchOnce;
m_bEnabled = src.m_bEnabled;
m_bApplyContextToWorld = src.m_bApplyContextToWorld;
m_nForceWeight = src.m_nForceWeight;
return *this;
}
Rule::Rule( const Rule& src )
{
operator=(src);
}
Rule::~Rule()
{
}
void Rule::SetContext( const char *context )
{
// we don't own the data we point to, so just update pointer
m_szContext = ResponseCopyString( context );
}

View File

@ -0,0 +1,120 @@
//========= Copyright <20> 1996-2010, Valve Corporation, All rights reserved. ============//
//
// Purpose: Core types for the response rules -- criteria, responses, rules, and matchers.
//
// $NoKeywords: $
//=============================================================================//
#include "rrbase.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
using namespace ResponseRules;
ResponseRulePartition::ResponseRulePartition()
{
Assert(true);
COMPILE_TIME_ASSERT( kIDX_ELEM_MASK < (1 << 16) );
COMPILE_TIME_ASSERT( (kIDX_ELEM_MASK & (kIDX_ELEM_MASK + 1)) == 0 ); /// assert is power of two minus one
}
ResponseRulePartition::~ResponseRulePartition()
{
RemoveAll();
}
ResponseRulePartition::tIndex ResponseRulePartition::IndexFromDictElem( tRuleDict* pDict, int elem )
{
Assert( pDict );
// If this fails, you've tried to build an index for a rule that's not stored
// in this partition
Assert( pDict >= m_RuleParts && pDict < m_RuleParts + N_RESPONSE_PARTITIONS );
AssertMsg1( elem <= kIDX_ELEM_MASK, "A rule dictionary has %d elements; this exceeds the 255 that can be packed into an index.\n", elem );
int bucket = pDict - m_RuleParts;
return ( bucket << 16 ) | ( elem & kIDX_ELEM_MASK ); // this is a native op on PPC
}
char const *ResponseRulePartition::GetElementName( const tIndex &i ) const
{
Assert( IsValid(i) );
return m_RuleParts[ BucketFromIdx(i) ].GetElementName( PartFromIdx(i) );
}
int ResponseRulePartition::Count( void )
{
int count = 0 ;
for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit )
{
count += m_RuleParts[bukkit].Count();
}
return count;
}
void ResponseRulePartition::RemoveAll( void )
{
for ( int bukkit = 0 ; bukkit < N_RESPONSE_PARTITIONS ; ++bukkit )
{
for ( int i = m_RuleParts[bukkit].FirstInorder(); i != m_RuleParts[bukkit].InvalidIndex(); i = m_RuleParts[bukkit].NextInorder( i ) )
{
delete m_RuleParts[bukkit][ i ];
}
m_RuleParts[bukkit].RemoveAll();
}
}
// don't bucket "subject" criteria that prefix with operators, since stripping all that out again would
// be a big pain, and the most important rules that need subjects are tlk_remarks anyway.
static inline bool CanBucketBySubject( const char * RESTRICT pszSubject )
{
return pszSubject &&
( ( pszSubject[0] >= 'A' && pszSubject[0] <= 'Z' ) ||
( pszSubject[0] >= 'a' && pszSubject[0] <= 'z' ) );
}
ResponseRulePartition::tRuleDict &ResponseRulePartition::GetDictForRule( CResponseSystem *pSystem, Rule *pRule )
{
const static CUtlSymbol kWHO = CriteriaSet::ComputeCriteriaSymbol("Who");
const static CUtlSymbol kCONCEPT = CriteriaSet::ComputeCriteriaSymbol("Concept");
const static CUtlSymbol kSUBJECT = CriteriaSet::ComputeCriteriaSymbol("Subject");
const char *pszSpeaker = pRule->GetValueForRuleCriterionByName( pSystem, kWHO );
const char *pszConcept = pRule->GetValueForRuleCriterionByName( pSystem, kCONCEPT );
const Criteria *pSubjCrit = pRule->GetPointerForRuleCriterionByName( pSystem, kSUBJECT );
return m_RuleParts[
GetBucketForSpeakerAndConcept( pszSpeaker, pszConcept,
( pSubjCrit && pSubjCrit->required && CanBucketBySubject(pSubjCrit->value) ) ?
pSubjCrit->value :
NULL )
];
}
void ResponseRulePartition::GetDictsForCriteria( CUtlVectorFixed< ResponseRulePartition::tRuleDict *, 2 > *pResult, const CriteriaSet &criteria )
{
pResult->RemoveAll();
pResult->EnsureCapacity( 2 );
// get the values for Who and Concept, which are what we bucket on
int speakerIdx = criteria.FindCriterionIndex( "Who" );
const char *pszSpeaker = speakerIdx != -1 ? criteria.GetValue( speakerIdx ) : NULL ;
int conceptIdx = criteria.FindCriterionIndex( "Concept" );
const char *pszConcept = conceptIdx != -1 ? criteria.GetValue( conceptIdx ) : NULL ;
int subjectIdx = criteria.FindCriterionIndex( "Subject" );
const char *pszSubject = subjectIdx != -1 ? criteria.GetValue( subjectIdx ) : NULL ;
pResult->AddToTail( &m_RuleParts[ GetBucketForSpeakerAndConcept(pszSpeaker, pszConcept, pszSubject) ] );
// also try the rules not specifying subject
pResult->AddToTail( &m_RuleParts[ GetBucketForSpeakerAndConcept(pszSpeaker, pszConcept, NULL) ] );
}

View File

@ -0,0 +1,48 @@
//-----------------------------------------------------------------------------
// RESPONSERULES_RUNTIME.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR "..\.."
$include "$SRCDIR\vpc_scripts\source_lib_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE;$SRCDIR\public"
}
}
$Project "responserules_runtime"
{
$Folder "Header Files"
{
$file "$SRCDIR\public\responserules\response_types.h"
$file "$SRCDIR\public\responserules\response_host_interface.h"
$file "$SRCDIR\public\responserules\rr_speechconcept.h"
$file "$SRCDIR\common\responserules\response_types_internal.h"
$file "$SRCDIR\responserules\responserules_cli\response_system.h"
$file "rrbase.h"
}
$Folder "Source Files"
{
$file "rrrlib.cpp"
$file "response_types.cpp"
$file "response_types_internal.cpp"
$file "response_system.cpp"
$file "rr_speechconcept.cpp"
$file "rr_response.cpp"
$file "criteriaset.cpp"
}
$Folder "Public Header Files"
{
$File "$SRCDIR\public\tier2\interval.h"
}
}

View File

@ -0,0 +1,13 @@
"vpc_cache"
{
"CacheVersion" "1"
"win32"
{
"CRCFile" "responserules_runtime.vcxproj.vpc_crc"
"OutputFiles"
{
"0" "responserules_runtime.vcxproj"
"1" "responserules_runtime.vcxproj.filters"
}
}
}

View File

@ -0,0 +1,14 @@
//========= Copyright <20> 1996-2010, Valve Corporation, All rights reserved. ============//
//
// Purpose: Convars used by the response rule system.
//
// $NoKeywords: $
//=============================================================================//
#include "rrbase.h"
#include <convar.h>
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

View File

@ -0,0 +1,311 @@
//===== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// $NoKeywords: $
//
//===========================================================================//
#include "rrbase.h"
#include <tier2/interval.h>
/*
#include "AI_Criteria.h"
#include "ai_speech.h"
#include <keyvalues.h>
#include "engine/IEngineSound.h"
*/
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace ResponseRules;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CRR_Response::CRR_Response() : m_fMatchScore(0)
{
m_Type = ResponseRules::RESPONSE_NONE;
m_szResponseName[0] = 0;
m_szMatchingRule[0]=0;
m_szContext = NULL;
m_bApplyContextToWorld = false;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CRR_Response::CRR_Response( const CRR_Response &from ) : m_fMatchScore(0)
{
// Assert( (void*)(&m_Type) == (void*)this );
Invalidate();
memcpy( this, &from, sizeof(*this) );
m_szContext = NULL;
SetContext( from.m_szContext );
m_bApplyContextToWorld = from.m_bApplyContextToWorld;
}
//-----------------------------------------------------------------------------
CRR_Response &CRR_Response::operator=( const CRR_Response &from )
{
// Assert( (void*)(&m_Type) == (void*)this );
Invalidate();
memcpy( this, &from, sizeof(*this) );
m_szContext = NULL;
SetContext( from.m_szContext );
m_bApplyContextToWorld = from.m_bApplyContextToWorld;
return *this;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CRR_Response::~CRR_Response()
{
if (m_szContext)
delete[] m_szContext;
}
void CRR_Response::Invalidate()
{
if (m_szContext)
{
delete[] m_szContext;
m_szContext = NULL;
}
m_Type = ResponseRules::RESPONSE_NONE;
m_szResponseName[0] = 0;
// not really necessary:
/*
m_szMatchingRule[0]=0;
m_szContext = NULL;
m_bApplyContextToWorld = false;
*/
}
// please do not new or delete CRR_Responses.
void CRR_Response::operator delete(void* p)
{
AssertMsg(false, "DO NOT new or delete CRR_Response s.");
free(p);
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *response -
// *criteria -
//-----------------------------------------------------------------------------
void CRR_Response::Init( ResponseType_t type, const char *responseName, const ResponseParams& responseparams, const char *ruleName, const char *applyContext, bool bApplyContextToWorld )
{
m_Type = type;
Q_strncpy( m_szResponseName, responseName, sizeof( m_szResponseName ) );
// Copy underlying criteria
Q_strncpy( m_szMatchingRule, ruleName ? ruleName : "NULL", sizeof( m_szMatchingRule ) );
m_Params = responseparams;
SetContext( applyContext );
m_bApplyContextToWorld = bApplyContextToWorld;
}
//-----------------------------------------------------------------------------
// Purpose: Debug-print the response. You can optionally pass in the criteria
// used to come up with this response (usually present in the calling function)
// if you want to print that as well. DO NOT store the entire criteria set in
// CRR_Response just to make this debug print cleaner.
//-----------------------------------------------------------------------------
void CRR_Response::Describe( const CriteriaSet *pDebugCriteria )
{
if ( pDebugCriteria )
{
DevMsg( "Search criteria:\n" );
pDebugCriteria->Describe();
}
if ( m_szMatchingRule[ 0 ] )
{
DevMsg( "Matched rule '%s', ", m_szMatchingRule );
}
if ( m_szContext )
{
DevMsg( "Contexts to set '%s' on %s, ", m_szContext, m_bApplyContextToWorld ? "world" : "speaker" );
}
DevMsg( "response %s = '%s'\n", DescribeResponse( (ResponseType_t)m_Type ), m_szResponseName );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : char const
//-----------------------------------------------------------------------------
void CRR_Response::GetName( char *buf, size_t buflen ) const
{
Q_strncpy( buf, m_szResponseName, buflen );
}
//-----------------------------------------------------------------------------
// Purpose:
// Output : char const
//-----------------------------------------------------------------------------
void CRR_Response::GetResponse( char *buf, size_t buflen ) const
{
GetName( buf, buflen );
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : type -
// Output : char const
//-----------------------------------------------------------------------------
const char *CRR_Response::DescribeResponse( ResponseType_t type )
{
if ( (int)type < 0 || (int)type >= ResponseRules::NUM_RESPONSES )
{
Assert( 0 );
return "???CRR_Response bogus index";
}
switch( type )
{
default:
{
Assert( 0 );
}
// Fall through
case ResponseRules::RESPONSE_NONE:
return "RESPONSE_NONE";
case ResponseRules::RESPONSE_SPEAK:
return "RESPONSE_SPEAK";
case ResponseRules::RESPONSE_SENTENCE:
return "RESPONSE_SENTENCE";
case ResponseRules::RESPONSE_SCENE:
return "RESPONSE_SCENE";
case ResponseRules::RESPONSE_RESPONSE:
return "RESPONSE_RESPONSE";
case ResponseRules::RESPONSE_PRINT:
return "RESPONSE_PRINT";
case ResponseRules::RESPONSE_ENTITYIO:
return "RESPONSE_ENTITYIO";
}
return "RESPONSE_NONE";
}
/*
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CRR_Response::Release()
{
delete this;
}
*/
//-----------------------------------------------------------------------------
// Purpose:
// Output : soundlevel_t
//-----------------------------------------------------------------------------
soundlevel_t CRR_Response::GetSoundLevel() const
{
if ( m_Params.flags & ResponseParams::RG_SOUNDLEVEL )
{
return (soundlevel_t)m_Params.soundlevel;
}
return SNDLVL_TALKING;
}
float CRR_Response::GetRespeakDelay( void ) const
{
if ( m_Params.flags & ResponseParams::RG_RESPEAKDELAY )
{
interval_t temp;
m_Params.respeakdelay.ToInterval( temp );
return RandomInterval( temp );
}
return 0.0f;
}
float CRR_Response::GetWeaponDelay( void ) const
{
if ( m_Params.flags & ResponseParams::RG_WEAPONDELAY )
{
interval_t temp;
m_Params.weapondelay.ToInterval( temp );
return RandomInterval( temp );
}
return 0.0f;
}
bool CRR_Response::GetSpeakOnce( void ) const
{
if ( m_Params.flags & ResponseParams::RG_SPEAKONCE )
{
return true;
}
return false;
}
bool CRR_Response::ShouldntUseScene( void ) const
{
return ( m_Params.flags & ResponseParams::RG_DONT_USE_SCENE ) != 0;
}
bool CRR_Response::ShouldBreakOnNonIdle( void ) const
{
return ( m_Params.flags & ResponseParams::RG_STOP_ON_NONIDLE ) != 0;
}
int CRR_Response::GetOdds( void ) const
{
if ( m_Params.flags & ResponseParams::RG_ODDS )
{
return m_Params.odds;
}
return 100;
}
float CRR_Response::GetDelay() const
{
if ( m_Params.flags & ResponseParams::RG_DELAYAFTERSPEAK )
{
interval_t temp;
m_Params.delay.ToInterval( temp );
return RandomInterval( temp );
}
return 0.0f;
}
float CRR_Response::GetPreDelay() const
{
if ( m_Params.flags & ResponseParams::RG_DELAYBEFORESPEAK )
{
interval_t temp;
m_Params.predelay.ToInterval( temp );
return RandomInterval( temp );
}
return 0.0f;
}
//-----------------------------------------------------------------------------
// Purpose: Sets context string
// Output : void
//-----------------------------------------------------------------------------
void CRR_Response::SetContext( const char *context )
{
if (m_szContext)
{
delete[] m_szContext;
m_szContext = NULL;
}
if ( context )
{
int len = Q_strlen( context );
m_szContext = new char[ len + 1 ];
Q_memcpy( m_szContext, context, len );
m_szContext[ len ] = 0;
}
}

View File

@ -0,0 +1,73 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "rrbase.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
#if RR_CONCEPTS_ARE_STRINGS
#pragma error("RR_CONCEPTS_ARE_STRINGS no longer supported")
#else
using namespace ResponseRules;
// Used to turn ad-hoc concept from strings into numbers.
CRR_ConceptSymbolTable *g_pRRConceptTable = NULL;
// Q&D hack to defer initialization of concept table until I can figure out where it
// really needs to come from.
static void InitializeRRConceptTable()
{
if (g_pRRConceptTable == NULL)
{
g_pRRConceptTable = new CRR_ConceptSymbolTable( 64, 64, true );
}
}
// construct from string
CRR_Concept::CRR_Concept(const char *fromString)
{
InitializeRRConceptTable();
m_iConcept = g_pRRConceptTable->AddString(fromString);
}
CRR_Concept &CRR_Concept::operator=(const char *fromString)
{
InitializeRRConceptTable();
m_iConcept = g_pRRConceptTable->AddString(fromString);
return *this;
}
bool CRR_Concept::operator==(const char *pszConcept)
{
int otherConcept = g_pRRConceptTable->Find(pszConcept);
return ( otherConcept != UTL_INVAL_SYMBOL && otherConcept == m_iConcept );
}
const char *CRR_Concept::GetStringConcept() const
{
InitializeRRConceptTable();
AssertMsg( m_iConcept.IsValid(), "AI Concept has invalid string symbol.\n" );
const char * retval = g_pRRConceptTable->String(m_iConcept);
AssertMsg( retval, "An RR_Concept couldn't find its string in the symbol table!\n" );
if (retval == NULL)
{
Warning( "An RR_Concept couldn't find its string in the symbol table!\n" );
retval = "";
}
return retval;
}
const char *CRR_Concept::GetStringForGenericId(tGenericId genericId)
{
InitializeRRConceptTable();
return g_pRRConceptTable->String(genericId);
}
#endif

View File

@ -0,0 +1,59 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef RRBASE_H
#define RRBASE_H
#ifdef _WIN32
#pragma once
#endif
#ifdef _WIN32
// Silence certain warnings
// #pragma warning(disable : 4244) // int or float down-conversion
// #pragma warning(disable : 4305) // int or float data truncation
// #pragma warning(disable : 4201) // nameless struct/union
// #pragma warning(disable : 4511) // copy constructor could not be generated
// #pragma warning(disable : 4675) // resolved overload was found by argument dependent lookup
#endif
#ifdef _DEBUG
#define DEBUG 1
#endif
// Misc C-runtime library headers
#include <math.h>
#include <ctype.h>
#include <stdio.h>
// tier 0
#include "tier0/dbg.h"
#include "tier0/platform.h"
#include "basetypes.h"
// tier 1
#include "tier1/strtools.h"
#include "utlvector.h"
#include "utlsymbol.h"
// tier 2
#include "string_t.h"
// Shared engine/DLL constants
#include "const.h"
#include "edict.h"
// app
#if defined(_GAMECONSOLE)
#define DISABLE_DEBUG_HISTORY 1
#endif
#include "responserules/response_types.h"
#include "responserules/response_types_internal.h"
#include "responserules/response_host_interface.h"
#endif // CBASE_H

View File

@ -0,0 +1,13 @@
/// PLACEHOLDER FILE FOR RESPONSE RULES RUNTIME LIBRARY
#include "rrbase.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
namespace ResponseRules
{
/// Custom symbol table for the response rules.
CUtlSymbolTable g_RS;
};

View File

@ -0,0 +1,11 @@
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Builds the precompiled header for the game DLL
//
// $NoKeywords: $
//=============================================================================//
#include "rrbase.h"
// NOTE: DO NOT ADD ANY CODE OR HEADERS TO THIS FILE!!!

View File

@ -0,0 +1,2 @@
SN Visual Studio Integration
IMPORTANT: Do not remove the custom build step for this file