store traits differently (index on trait class rather than actor)
This commit is contained in:
@@ -92,7 +92,7 @@ namespace OpenRA.FileFormats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class TypeExts
|
public static class TypeExts
|
||||||
{
|
{
|
||||||
public static IEnumerable<Type> BaseTypes( this Type t )
|
public static IEnumerable<Type> BaseTypes( this Type t )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,8 +21,6 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public class Actor
|
public class Actor
|
||||||
{
|
{
|
||||||
[Sync]
|
|
||||||
readonly TypeDictionary traits = new TypeDictionary();
|
|
||||||
public readonly ActorInfo Info;
|
public readonly ActorInfo Info;
|
||||||
|
|
||||||
public readonly World World;
|
public readonly World World;
|
||||||
@@ -191,27 +189,27 @@ namespace OpenRA
|
|||||||
|
|
||||||
public T Trait<T>()
|
public T Trait<T>()
|
||||||
{
|
{
|
||||||
return traits.Get<T>();
|
return World.traitDict.Get<T>( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public T TraitOrDefault<T>()
|
public T TraitOrDefault<T>()
|
||||||
{
|
{
|
||||||
return traits.GetOrDefault<T>();
|
return World.traitDict.GetOrDefault<T>( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<T> TraitsImplementing<T>()
|
public IEnumerable<T> TraitsImplementing<T>()
|
||||||
{
|
{
|
||||||
return traits.WithInterface<T>();
|
return World.traitDict.WithInterface<T>( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasTrait<T>()
|
public bool HasTrait<T>()
|
||||||
{
|
{
|
||||||
return traits.Contains<T>();
|
return World.traitDict.Contains<T>( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddTrait( object t )
|
public void AddTrait( object trait )
|
||||||
{
|
{
|
||||||
traits.Add( t );
|
World.traitDict.Add( this, trait );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
@@ -238,6 +238,7 @@
|
|||||||
<Compile Include="Network\Session.cs" />
|
<Compile Include="Network\Session.cs" />
|
||||||
<Compile Include="ObjectCreator.cs" />
|
<Compile Include="ObjectCreator.cs" />
|
||||||
<Compile Include="Network\SyncReport.cs" />
|
<Compile Include="Network\SyncReport.cs" />
|
||||||
|
<Compile Include="TraitDictionary.cs" />
|
||||||
<Compile Include="Traits\PrimaryBuilding.cs" />
|
<Compile Include="Traits\PrimaryBuilding.cs" />
|
||||||
<Compile Include="Widgets\Delegates\DeveloperModeDelegate.cs" />
|
<Compile Include="Widgets\Delegates\DeveloperModeDelegate.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -269,4 +270,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ namespace OpenRA
|
|||||||
static void Run( string[] args )
|
static void Run( string[] args )
|
||||||
{
|
{
|
||||||
Game.Initialize( new Arguments(args) );
|
Game.Initialize( new Arguments(args) );
|
||||||
|
GC.Collect();
|
||||||
Game.Run();
|
Game.Run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
139
OpenRA.Game/TraitDictionary.cs
Executable file
139
OpenRA.Game/TraitDictionary.cs
Executable file
@@ -0,0 +1,139 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2010 The OpenRA Developers (see AUTHORS)
|
||||||
|
* This file is part of OpenRA, which is free software. It is made
|
||||||
|
* available to you under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation. For more information,
|
||||||
|
* see LICENSE.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.FileFormats;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace OpenRA
|
||||||
|
{
|
||||||
|
class TraitDictionary
|
||||||
|
{
|
||||||
|
Dictionary<Type, ITraitContainer> traits = new Dictionary<Type, ITraitContainer>();
|
||||||
|
|
||||||
|
ITraitContainer InnerGet( Type t )
|
||||||
|
{
|
||||||
|
return traits.GetOrAdd( t, CreateTraitContainer );
|
||||||
|
}
|
||||||
|
|
||||||
|
static ITraitContainer CreateTraitContainer( Type t )
|
||||||
|
{
|
||||||
|
return (ITraitContainer)typeof( TraitContainer<> ).MakeGenericType( t )
|
||||||
|
.GetConstructor( new Type[ 0 ] ).Invoke( new object[ 0 ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add( Actor actor, object val )
|
||||||
|
{
|
||||||
|
var t = val.GetType();
|
||||||
|
|
||||||
|
foreach( var i in t.GetInterfaces() )
|
||||||
|
InnerAdd( actor, i, val );
|
||||||
|
foreach( var tt in t.BaseTypes() )
|
||||||
|
InnerAdd( actor, tt, val );
|
||||||
|
}
|
||||||
|
|
||||||
|
void InnerAdd( Actor actor, Type t, object val )
|
||||||
|
{
|
||||||
|
InnerGet( t ).Add( actor, val );
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Contains<T>( Actor actor )
|
||||||
|
{
|
||||||
|
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).GetMultiple( actor ).Count() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Get<T>( Actor actor )
|
||||||
|
{
|
||||||
|
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).Get( actor );
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetOrDefault<T>( Actor actor )
|
||||||
|
{
|
||||||
|
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).GetOrDefault( actor );
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<T> WithInterface<T>( Actor actor )
|
||||||
|
{
|
||||||
|
return ( (TraitContainer<T>)InnerGet( typeof( T ) ) ).GetMultiple( actor );
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ITraitContainer
|
||||||
|
{
|
||||||
|
void Add( Actor actor, object trait );
|
||||||
|
}
|
||||||
|
|
||||||
|
class TraitContainer<T> : ITraitContainer
|
||||||
|
{
|
||||||
|
List<uint> actors = new List<uint>();
|
||||||
|
List<T> traits = new List<T>();
|
||||||
|
|
||||||
|
public void Add( Actor actor, object trait )
|
||||||
|
{
|
||||||
|
var insertIndex = actors.BinarySearchMany( actor.ActorID + 1 );
|
||||||
|
actors.Insert( insertIndex, actor.ActorID );
|
||||||
|
traits.Insert( insertIndex, (T)trait );
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Get( Actor actor )
|
||||||
|
{
|
||||||
|
var index = actors.BinarySearchMany( actor.ActorID );
|
||||||
|
if( index >= actors.Count || actors[ index ] != actor.ActorID )
|
||||||
|
throw new InvalidOperationException( string.Format( "TraitDictionary does not contain instance of type `{0}`", typeof( T ) ) );
|
||||||
|
else if( index + 1 < actors.Count && actors[ index + 1 ] == actor.ActorID )
|
||||||
|
throw new InvalidOperationException( string.Format( "TraitDictionary contains multiple instance of type `{0}`", typeof( T ) ) );
|
||||||
|
else
|
||||||
|
return traits[ index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetOrDefault( Actor actor )
|
||||||
|
{
|
||||||
|
var index = actors.BinarySearchMany( actor.ActorID );
|
||||||
|
if( index >= actors.Count || actors[ index ] != actor.ActorID )
|
||||||
|
return default( T );
|
||||||
|
else if( index + 1 < actors.Count && actors[ index + 1 ] == actor.ActorID )
|
||||||
|
throw new InvalidOperationException( string.Format( "TraitDictionary contains multiple instance of type `{0}`", typeof( T ) ) );
|
||||||
|
else return traits[ index ];
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<T> GetMultiple( Actor actor )
|
||||||
|
{
|
||||||
|
var index = actors.BinarySearchMany( actor.ActorID );
|
||||||
|
while( index < actors.Count && actors[ index ] == actor.ActorID )
|
||||||
|
{
|
||||||
|
yield return traits[ index ];
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ListExts
|
||||||
|
{
|
||||||
|
public static int BinarySearchMany<T>( this List<T> list, T searchFor )
|
||||||
|
where T : IComparable<T>
|
||||||
|
{
|
||||||
|
int start = 0;
|
||||||
|
int end = list.Count;
|
||||||
|
int mid = 0;
|
||||||
|
while( start != end )
|
||||||
|
{
|
||||||
|
mid = ( start + end ) / 2;
|
||||||
|
var c = list[ mid ].CompareTo( searchFor );
|
||||||
|
if( c < 0 )
|
||||||
|
start = mid + 1;
|
||||||
|
else
|
||||||
|
end = mid;
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
public class World
|
public class World
|
||||||
{
|
{
|
||||||
|
internal TraitDictionary traitDict = new TraitDictionary();
|
||||||
Set<Actor> actors = new Set<Actor>();
|
Set<Actor> actors = new Set<Actor>();
|
||||||
List<IEffect> effects = new List<IEffect>();
|
List<IEffect> effects = new List<IEffect>();
|
||||||
Queue<Action<World>> frameEndActions = new Queue<Action<World>>();
|
Queue<Action<World>> frameEndActions = new Queue<Action<World>>();
|
||||||
|
|||||||
Reference in New Issue
Block a user