From 88488bc616897b7fd52251f08acd9c9fea6f9764 Mon Sep 17 00:00:00 2001 From: Mark Sturgill Date: Tue, 15 Oct 2013 21:15:59 -0700 Subject: [PATCH] generic pooled enumerators guild event bcp --- .../Explosion Potions/BaseExplosionPotion.cs | 2 +- Scripts/Misc/Guild.cs | 4 +- Scripts/Mobiles/AI/BaseAI.cs | 2 +- Server/EventSink.cs | 63 +- Server/Item.cs | 8 +- Server/Map.cs | 1015 +++++++++-------- Server/Mobile.cs | 22 +- Server/TileMatrix.cs | 2 +- Server/World.cs | 3 +- 9 files changed, 645 insertions(+), 476 deletions(-) diff --git a/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs b/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs index 018d69c3e..d59c69ba7 100644 --- a/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs +++ b/Scripts/Items/Skill Items/Magical/Potions/Explosion Potions/BaseExplosionPotion.cs @@ -249,7 +249,7 @@ namespace Server.Items if ( direct ) alchemyBonus = (int)(from.Skills.Alchemy.Value / (Core.AOS ? 5 : 10)); - IPooledEnumerable eable = LeveledExplosion ? map.GetObjectsInRange( loc, ExplosionRange ) : map.GetMobilesInRange( loc, ExplosionRange ); + IPooledEnumerable eable = LeveledExplosion ? (IPooledEnumerable)map.GetObjectsInRange( loc, ExplosionRange ) : (IPooledEnumerable)map.GetMobilesInRange( loc, ExplosionRange ); ArrayList toExplode = new ArrayList(); int toDamage = 0; diff --git a/Scripts/Misc/Guild.cs b/Scripts/Misc/Guild.cs index 5c183b9bf..a18163505 100644 --- a/Scripts/Misc/Guild.cs +++ b/Scripts/Misc/Guild.cs @@ -687,9 +687,9 @@ namespace Server.Guilds pm.SendGump( new GuildInfoGump( pm, pm.Guild as Guild ) ); } - public static BaseGuild EventSink_CreateGuild( CreateGuildEventArgs args ) + public static void EventSink_CreateGuild(CreateGuildEventArgs args) { - return (BaseGuild)(new Guild( args.Id )); + args.Guild = new Guild(args.Id); } #endregion diff --git a/Scripts/Mobiles/AI/BaseAI.cs b/Scripts/Mobiles/AI/BaseAI.cs index 1defc9343..4bb8e98dc 100644 --- a/Scripts/Mobiles/AI/BaseAI.cs +++ b/Scripts/Mobiles/AI/BaseAI.cs @@ -2592,7 +2592,7 @@ namespace Server.Mobiles #if Framework_4_0 object valLock = new object(); - Parallel.ForEach( eable.Cast(), m => { + Parallel.ForEach(eable, m => { if (m.Deleted || m.Blessed) return; diff --git a/Server/EventSink.cs b/Server/EventSink.cs index 3838cb4b1..2293c80ca 100644 --- a/Server/EventSink.cs +++ b/Server/EventSink.cs @@ -70,7 +70,7 @@ namespace Server public delegate void SetAbilityEventHandler( SetAbilityEventArgs e ); public delegate void FastWalkEventHandler( FastWalkEventArgs e ); public delegate void ServerStartedEventHandler(); - public delegate BaseGuild CreateGuildHandler( CreateGuildEventArgs e ); + public delegate void CreateGuildHandler( CreateGuildEventArgs e ); public delegate void GuildGumpRequestHandler( GuildGumpRequestArgs e ); public delegate void QuestGumpRequestHandler( QuestGumpRequestArgs e ); public delegate void ClientVersionReceivedHandler( ClientVersionReceivedArgs e ); @@ -95,6 +95,9 @@ namespace Server private int m_Id; public int Id { get { return m_Id; } set { m_Id = value; } } + private BaseGuild m_Guild; + public BaseGuild Guild { get { return m_Guild; } set { m_Guild = value; } } + public CreateGuildEventArgs( int id ) { m_Id = id; @@ -853,6 +856,58 @@ namespace Server public static event GuildGumpRequestHandler GuildGumpRequest; public static event QuestGumpRequestHandler QuestGumpRequest; public static event ClientVersionReceivedHandler ClientVersionReceived; + + /* The following is a .NET 2.0 "Generic EventHandler" implementation. + * It is a breaking change; we would have to refactor all event handlers. + * This style does not appear to be in widespread use. + * We could also look into .NET 4.0 Action/Func implementations. + */ + + /* + public static event EventHandler CharacterCreated; + public static event EventHandler OpenDoorMacroUsed; + public static event EventHandler Speech; + public static event EventHandler Login; + public static event EventHandler ServerList; + public static event EventHandler Movement; + public static event EventHandler HungerChanged; + public static event EventHandler Crashed; + public static event EventHandler Shutdown; + public static event EventHandler HelpRequest; + public static event EventHandler DisarmRequest; + public static event EventHandler StunRequest; + public static event EventHandler OpenSpellbookRequest; + public static event EventHandler CastSpellRequest; + public static event EventHandler BandageTargetRequest; + public static event EventHandler AnimateRequest; + public static event EventHandler Logout; + public static event EventHandler SocketConnect; + public static event EventHandler Connected; + public static event EventHandler Disconnected; + public static event EventHandler RenameRequest; + public static event EventHandler PlayerDeath; + public static event EventHandler VirtueGumpRequest; + public static event EventHandler VirtueItemRequest; + public static event EventHandler VirtueMacroRequest; + public static event EventHandler ChatRequest; + public static event EventHandler AccountLogin; + public static event EventHandler PaperdollRequest; + public static event EventHandler ProfileRequest; + public static event EventHandler ChangeProfileRequest; + public static event EventHandler AggressiveAction; + public static event EventHandler Command; + public static event EventHandler GameLogin; + public static event EventHandler DeleteRequest; + public static event EventHandler WorldLoad; + public static event EventHandler WorldSave; + public static event EventHandler SetAbility; + public static event EventHandler FastWalk; + public static event EventHandler CreateGuild; + public static event EventHandler ServerStarted; + public static event EventHandler GuildGumpRequest; + public static event EventHandler QuestGumpRequest; + public static event EventHandler ClientVersionReceived; + */ public static void InvokeClientVersionReceived( ClientVersionReceivedArgs e ) { @@ -866,12 +921,10 @@ namespace Server ServerStarted(); } - public static BaseGuild InvokeCreateGuild( CreateGuildEventArgs e ) + public static void InvokeCreateGuild( CreateGuildEventArgs e ) { if ( CreateGuild != null ) - return CreateGuild( e ); - else - return null; + CreateGuild( e ); } public static void InvokeSetAbility( SetAbilityEventArgs e ) diff --git a/Server/Item.cs b/Server/Item.cs index 1075709c7..a37ef5799 100644 --- a/Server/Item.cs +++ b/Server/Item.cs @@ -2174,7 +2174,7 @@ namespace Server Map map = m_Map; if ( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; if ( m_Parent == null ) return map.GetObjectsInRange( m_Location, range ); @@ -2187,7 +2187,7 @@ namespace Server Map map = m_Map; if ( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; if ( m_Parent == null ) return map.GetItemsInRange( m_Location, range ); @@ -2200,7 +2200,7 @@ namespace Server Map map = m_Map; if ( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; if ( m_Parent == null ) return map.GetMobilesInRange( m_Location, range ); @@ -2213,7 +2213,7 @@ namespace Server Map map = m_Map; if ( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; if ( m_Parent == null ) return map.GetClientsInRange( m_Location, range ); diff --git a/Server/Map.cs b/Server/Map.cs index ec87f4423..cf37c31cd 100644 --- a/Server/Map.cs +++ b/Server/Map.cs @@ -40,13 +40,14 @@ namespace Server FeluccaRules = None } - public interface IPooledEnumerable : IEnumerable - { + public interface IPooledEnumerable : IEnumerable { void Free(); } - public interface IPooledEnumerator : IEnumerator - { + public interface IPooledEnumerable : IPooledEnumerable, IEnumerable { + } + + public interface IPooledEnumerator : IEnumerator { void Free(); } @@ -198,114 +199,114 @@ namespace Server } #region Get*InRange/Bounds - public IPooledEnumerable GetObjectsInRange( Point3D p ) + public IPooledEnumerable GetObjectsInRange(Point3D p) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( ObjectEnumerator.Instantiate( this, new Rectangle2D( p.m_X - 18, p.m_Y - 18, 37, 37 ) ) ); + return PooledEnumerable.Instantiate(EntityEnumerator.Instantiate(this, new Rectangle2D(p.m_X - 18, p.m_Y - 18, 37, 37))); } - public IPooledEnumerable GetObjectsInRange( Point3D p, int range ) + public IPooledEnumerable GetObjectsInRange(Point3D p, int range) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( ObjectEnumerator.Instantiate( this, new Rectangle2D( p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1 ) ) ); + return PooledEnumerable.Instantiate(EntityEnumerator.Instantiate(this, new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1))); } - public IPooledEnumerable GetObjectsInBounds( Rectangle2D bounds ) + public IPooledEnumerable GetObjectsInBounds(Rectangle2D bounds) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( ObjectEnumerator.Instantiate( this, bounds ) ); + return PooledEnumerable.Instantiate(EntityEnumerator.Instantiate(this, bounds)); } - public IPooledEnumerable GetClientsInRange( Point3D p ) + public IPooledEnumerable GetClientsInRange(Point3D p) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( p.m_X - 18, p.m_Y - 18, 37, 37 ), SectorEnumeratorType.Clients ) ); + return PooledEnumerable.Instantiate(ClientEnumerator.Instantiate(this, new Rectangle2D(p.m_X - 18, p.m_Y - 18, 37, 37))); } - public IPooledEnumerable GetClientsInRange( Point3D p, int range ) + public IPooledEnumerable GetClientsInRange(Point3D p, int range) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1 ), SectorEnumeratorType.Clients ) ); + return PooledEnumerable.Instantiate(ClientEnumerator.Instantiate(this, new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1))); } - public IPooledEnumerable GetClientsInBounds( Rectangle2D bounds ) + public IPooledEnumerable GetClientsInBounds(Rectangle2D bounds) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, bounds, SectorEnumeratorType.Clients ) ); + return PooledEnumerable.Instantiate(ClientEnumerator.Instantiate(this, bounds)); } - public IPooledEnumerable GetItemsInRange( Point3D p ) + public IPooledEnumerable GetItemsInRange(Point3D p) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( p.m_X - 18, p.m_Y - 18, 37, 37 ), SectorEnumeratorType.Items ) ); + return PooledEnumerable.Instantiate(ItemEnumerator.Instantiate(this, new Rectangle2D(p.m_X - 18, p.m_Y - 18, 37, 37))); } - public IPooledEnumerable GetItemsInRange( Point3D p, int range ) + public IPooledEnumerable GetItemsInRange(Point3D p, int range) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1 ), SectorEnumeratorType.Items ) ); + return PooledEnumerable.Instantiate(ItemEnumerator.Instantiate(this, new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1))); } - public IPooledEnumerable GetItemsInBounds( Rectangle2D bounds ) + public IPooledEnumerable GetItemsInBounds(Rectangle2D bounds) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, bounds, SectorEnumeratorType.Items ) ); + return PooledEnumerable.Instantiate(ItemEnumerator.Instantiate(this, bounds)); } - public IPooledEnumerable GetMobilesInRange( Point3D p ) + public IPooledEnumerable GetMobilesInRange(Point3D p) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( p.m_X - 18, p.m_Y - 18, 37, 37 ), SectorEnumeratorType.Mobiles ) ); + return PooledEnumerable.Instantiate(MobileEnumerator.Instantiate(this, new Rectangle2D(p.m_X - 18, p.m_Y - 18, 37, 37))); } - public IPooledEnumerable GetMobilesInRange( Point3D p, int range ) + public IPooledEnumerable GetMobilesInRange(Point3D p, int range) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, new Rectangle2D( p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1 ), SectorEnumeratorType.Mobiles ) ); + return PooledEnumerable.Instantiate(MobileEnumerator.Instantiate(this, new Rectangle2D(p.m_X - range, p.m_Y - range, range * 2 + 1, range * 2 + 1))); } - public IPooledEnumerable GetMobilesInBounds( Rectangle2D bounds ) + public IPooledEnumerable GetMobilesInBounds(Rectangle2D bounds) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( TypedEnumerator.Instantiate( this, bounds, SectorEnumeratorType.Mobiles ) ); + return PooledEnumerable.Instantiate(MobileEnumerator.Instantiate(this, bounds)); } #endregion - public IPooledEnumerable GetMultiTilesAt( int x, int y ) + public IPooledEnumerable GetMultiTilesAt(int x, int y) { if ( this == Map.Internal ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; Sector sector = GetSector( x, y ); if ( sector.Multis.Count == 0 ) - return NullEnumerable.Instance; + return NullEnumerable.Instance; - return PooledEnumerable.Instantiate( MultiTileEnumerator.Instantiate( sector, new Point2D( x, y ) ) ); + return PooledEnumerable.Instantiate(MultiTileEnumerator.Instantiate(sector, new Point2D(x, y))); } #region CanFit @@ -1055,56 +1056,39 @@ namespace Server } #region Enumerables - public class NullEnumerable : IPooledEnumerable + public class NullEnumerable : IPooledEnumerable { - private InternalEnumerator m_Enumerator; + private InternalEnumerator m_Enumerator; - public static readonly NullEnumerable Instance = new NullEnumerable(); + public static readonly NullEnumerable Instance = new NullEnumerable(); - private NullEnumerable() - { - m_Enumerator = new InternalEnumerator(); + private NullEnumerable() { + m_Enumerator = new InternalEnumerator(); } - public IEnumerator GetEnumerator() - { - return m_Enumerator; - } + IEnumerator IEnumerable.GetEnumerator() { return m_Enumerator; } + public IEnumerator GetEnumerator() { return m_Enumerator; } - public void Free() - { - } + public void Free() { } - private class InternalEnumerator : IEnumerator - { - public void Reset() - { - } - - public object Current - { - get - { - return null; - } - } - - public bool MoveNext() - { - return false; - } + private class InternalEnumerator : IEnumerator { + public void Reset() { } + object IEnumerator.Current { get { return null; } } + public K Current { get { return default(K); } } + public bool MoveNext() { return false; } + void IDisposable.Dispose() { } } } - private class PooledEnumerable : IPooledEnumerable, IDisposable + private class PooledEnumerable : IPooledEnumerable, IDisposable { - private IPooledEnumerator m_Enumerator; + private IPooledEnumerator m_Enumerator; - private static Queue m_InstancePool = new Queue(); + private static Queue> m_InstancePool = new Queue>(); - public static PooledEnumerable Instantiate( IPooledEnumerator etor ) + public static PooledEnumerable Instantiate(IPooledEnumerator etor) { - PooledEnumerable e = null; + PooledEnumerable e = null; lock (m_InstancePool) { if ( m_InstancePool.Count > 0 ) { @@ -1114,17 +1098,25 @@ namespace Server } if (e == null ) - e = new PooledEnumerable( etor ); + e = new PooledEnumerable( etor ); return e; } - private PooledEnumerable( IPooledEnumerator etor ) + private PooledEnumerable(IPooledEnumerator etor) { m_Enumerator = etor; } - public IEnumerator GetEnumerator() + IEnumerator IEnumerable.GetEnumerator() + { + if (m_Enumerator == null) + throw new ObjectDisposedException("PooledEnumerable", "GetEnumerator() called after Free()"); + + return m_Enumerator; + } + + public IEnumerator GetEnumerator() { if ( m_Enumerator == null ) throw new ObjectDisposedException( "PooledEnumerable", "GetEnumerator() called after Free()" ); @@ -1134,7 +1126,7 @@ namespace Server public void Free() { - if ( m_Enumerator != null ) { + if ( m_Enumerator != null) { m_Enumerator.Free(); m_Enumerator = null; } @@ -1159,39 +1151,37 @@ namespace Server #endregion #region Enumerators - private enum SectorEnumeratorType - { - Mobiles, - Items, - Clients - } - - private class TypedEnumerator : IPooledEnumerator + private class ClientEnumerator : IPooledEnumerator { private Map m_Map; private Rectangle2D m_Bounds; - private SectorEnumerator m_Enumerator; - private SectorEnumeratorType m_Type; - private object m_Current; - private static Queue m_InstancePool = new Queue(); + private int m_xSector, m_ySector; + private int m_xSectorStart, m_ySectorStart; + private int m_xSectorEnd, m_ySectorEnd; + private List m_CurrentList; + private int m_CurrentIndex; - public static TypedEnumerator Instantiate( Map map, Rectangle2D bounds, SectorEnumeratorType type ) + private static Queue m_InstancePool = new Queue(); + + public static ClientEnumerator Instantiate(Map map, Rectangle2D bounds) { - TypedEnumerator e = null; - - lock (m_InstancePool) { - if ( m_InstancePool.Count > 0 ) { + ClientEnumerator e = null; + + lock (m_InstancePool) + { + if (m_InstancePool.Count > 0) + { e = m_InstancePool.Dequeue(); e.m_Map = map; e.m_Bounds = bounds; - e.m_Type = type; } } - if (e == null) { - e = new TypedEnumerator( map, bounds, type ); + if (e == null) + { + e = new ClientEnumerator(map, bounds); } e.Reset(); @@ -1201,101 +1191,119 @@ namespace Server public void Free() { - if ( m_Map == null ) + if (m_Map == null) return; m_Map = null; - if ( m_Enumerator != null) { - m_Enumerator.Free(); - m_Enumerator = null; - } - - lock (m_InstancePool) { + lock (m_InstancePool) + { if (m_InstancePool.Count < 200) // Arbitrary - m_InstancePool.Enqueue( this ); + m_InstancePool.Enqueue(this); } } - public TypedEnumerator( Map map, Rectangle2D bounds, SectorEnumeratorType type ) + private ClientEnumerator(Map map, Rectangle2D bounds) { m_Map = map; m_Bounds = bounds; - m_Type = type; } - public object Current { get { return m_Current; } } + public NetState Current + { + get + { + return m_CurrentList[m_CurrentIndex]; + } + } + + object IEnumerator.Current { get { return m_CurrentList[m_CurrentIndex]; } } + + void IDisposable.Dispose() { } public bool MoveNext() { - while ( m_Enumerator.MoveNext() ) { - object o; + while (true) + { + ++m_CurrentIndex; - try { - o = m_Enumerator.Current; - } catch { - continue; + if (m_CurrentIndex == m_CurrentList.Count) + { + ++m_ySector; + + if (m_ySector > m_ySectorEnd) + { + m_ySector = m_ySectorStart; + ++m_xSector; + + if (m_xSector > m_xSectorEnd) + { + m_CurrentIndex = -1; + return false; + } + } + + m_CurrentIndex = -1; + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Clients; } + else + { + Mobile m = m_CurrentList[m_CurrentIndex].Mobile; - if ( o is Mobile ) { - Mobile m = (Mobile) o; - - if ( !m.Deleted && m_Bounds.Contains( m.Location ) ) { - m_Current = o; + if ( m != null && !m.Deleted && m_Bounds.Contains( m.Location ) ) return true; - } - } else if ( o is Item ) { - Item item = (Item) o; - - if ( !item.Deleted && item.Parent == null && m_Bounds.Contains( item.Location ) ) { - m_Current = o; - return true; - } - } else if ( o is NetState ) { - Mobile m = ( (NetState) o ).Mobile; - - if ( m != null && !m.Deleted && m_Bounds.Contains( m.Location ) ) { - m_Current = o; - return true; - } } } - - m_Current = null; - return false; } public void Reset() { - m_Current = null; - m_Enumerator = SectorEnumerator.Instantiate( m_Map, m_Bounds, m_Type );//new SectorEnumerator( m_Map, m_Origin, m_Type, m_Range ); + m_Map.Bound(m_Bounds.Start.m_X, m_Bounds.Start.m_Y, out m_xSectorStart, out m_ySectorStart); + m_Map.Bound(m_Bounds.End.m_X - 1, m_Bounds.End.m_Y - 1, out m_xSectorEnd, out m_ySectorEnd); + + m_xSector = m_xSectorStart >>= Map.SectorShift; + m_ySector = m_ySectorStart >>= Map.SectorShift; + + m_xSectorEnd >>= Map.SectorShift; + m_ySectorEnd >>= Map.SectorShift; + + m_CurrentIndex = -1; + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Clients; } } - private class MultiTileEnumerator : IPooledEnumerator + private class EntityEnumerator : IPooledEnumerator { - private List m_List; - private Point2D m_Location; - private object m_Current; - private int m_Index; + private Map m_Map; + private Rectangle2D m_Bounds; - private static Queue m_InstancePool = new Queue(); + private int m_xSector, m_ySector; + private int m_xSectorStart, m_ySectorStart; + private int m_xSectorEnd, m_ySectorEnd; + private int m_Stage; + private IList m_CurrentList; + private int m_CurrentIndex; - public static MultiTileEnumerator Instantiate( Sector sector, Point2D loc ) + private static Queue m_InstancePool = new Queue(); + + public static EntityEnumerator Instantiate(Map map, Rectangle2D bounds) { - MultiTileEnumerator e = null; + EntityEnumerator e = null; - lock (m_InstancePool) { - if ( m_InstancePool.Count > 0 ) { + lock (m_InstancePool) + { + if (m_InstancePool.Count > 0) + { e = m_InstancePool.Dequeue(); - e.m_List = sector.Multis; - e.m_Location = loc; + e.m_Map = map; + e.m_Bounds = bounds; } } - if (e == null) { - e = new MultiTileEnumerator( sector, loc ); + if (e == null) + { + e = new EntityEnumerator(map, bounds); } e.Reset(); @@ -1303,37 +1311,421 @@ namespace Server return e; } - private MultiTileEnumerator( Sector sector, Point2D loc ) + public void Free() + { + if (m_Map == null) + return; + + m_Map = null; + + lock (m_InstancePool) + { + if (m_InstancePool.Count < 200) // Arbitrary + m_InstancePool.Enqueue(this); + } + } + + private EntityEnumerator(Map map, Rectangle2D bounds) + { + m_Map = map; + m_Bounds = bounds; + } + + public IEntity Current + { + get + { + return (IEntity)m_CurrentList[m_CurrentIndex]; + } + } + + object IEnumerator.Current { get { return m_CurrentList[m_CurrentIndex]; } } + + void IDisposable.Dispose() { } + + public bool MoveNext() + { + while (true) + { + ++m_CurrentIndex; + + if (m_CurrentIndex == m_CurrentList.Count) + { + ++m_ySector; + + if (m_ySector > m_ySectorEnd) + { + m_ySector = m_ySectorStart; + ++m_xSector; + + if (m_xSector > m_xSectorEnd) + { + if (m_Stage > 0) { + m_CurrentIndex = -1; + return false; + } + ++m_Stage; + m_xSector = m_xSectorStart >>= Map.SectorShift; + m_ySector = m_ySectorStart >>= Map.SectorShift; + } + } + + m_CurrentIndex = -1; + + if (m_Stage == 0) + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Items; + else + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Mobiles; + } + else + { + IEntity e = (IEntity)m_CurrentList[m_CurrentIndex]; + + if (e is Item) + { + Item item = (Item)e; + + if (!item.Deleted && item.Parent == null && m_Bounds.Contains(e.Location)) + return true; + } + else if (e is Mobile) + { + Mobile m = (Mobile)e; + if (!m.Deleted && m_Bounds.Contains(e.Location)) + return true; + } + } + } + } + + public void Reset() + { + m_Map.Bound(m_Bounds.Start.m_X, m_Bounds.Start.m_Y, out m_xSectorStart, out m_ySectorStart); + m_Map.Bound(m_Bounds.End.m_X - 1, m_Bounds.End.m_Y - 1, out m_xSectorEnd, out m_ySectorEnd); + + m_xSector = m_xSectorStart >>= Map.SectorShift; + m_ySector = m_ySectorStart >>= Map.SectorShift; + + m_xSectorEnd >>= Map.SectorShift; + m_ySectorEnd >>= Map.SectorShift; + + m_CurrentIndex = -1; + m_Stage = 0; + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Items; + } + } + + private class ItemEnumerator : IPooledEnumerator + { + private Map m_Map; + private Rectangle2D m_Bounds; + + private int m_xSector, m_ySector; + private int m_xSectorStart, m_ySectorStart; + private int m_xSectorEnd, m_ySectorEnd; + private List m_CurrentList; + private int m_CurrentIndex; + + private static Queue m_InstancePool = new Queue(); + + public static ItemEnumerator Instantiate(Map map, Rectangle2D bounds) + { + ItemEnumerator e = null; + + lock (m_InstancePool) + { + if (m_InstancePool.Count > 0) + { + e = m_InstancePool.Dequeue(); + + e.m_Map = map; + e.m_Bounds = bounds; + } + } + + if (e == null) + { + e = new ItemEnumerator(map, bounds); + } + + e.Reset(); + + return e; + } + + public void Free() + { + if (m_Map == null) + return; + + m_Map = null; + + lock (m_InstancePool) + { + if (m_InstancePool.Count < 200) // Arbitrary + m_InstancePool.Enqueue(this); + } + } + + private ItemEnumerator(Map map, Rectangle2D bounds) + { + m_Map = map; + m_Bounds = bounds; + } + + public Item Current + { + get + { + return m_CurrentList[m_CurrentIndex]; + } + } + + object IEnumerator.Current { get { return m_CurrentList[m_CurrentIndex]; } } + + void IDisposable.Dispose() { } + + public bool MoveNext() + { + while (true) + { + ++m_CurrentIndex; + + if (m_CurrentIndex == m_CurrentList.Count) + { + ++m_ySector; + + if (m_ySector > m_ySectorEnd) + { + m_ySector = m_ySectorStart; + ++m_xSector; + + if (m_xSector > m_xSectorEnd) + { + m_CurrentIndex = -1; + return false; + } + } + + m_CurrentIndex = -1; + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Items; + } + else + { + Item item = m_CurrentList[m_CurrentIndex]; + + if (!item.Deleted && item.Parent == null && m_Bounds.Contains(item.Location)) + return true; + } + } + } + + public void Reset() + { + m_Map.Bound(m_Bounds.Start.m_X, m_Bounds.Start.m_Y, out m_xSectorStart, out m_ySectorStart); + m_Map.Bound(m_Bounds.End.m_X - 1, m_Bounds.End.m_Y - 1, out m_xSectorEnd, out m_ySectorEnd); + + m_xSector = m_xSectorStart >>= Map.SectorShift; + m_ySector = m_ySectorStart >>= Map.SectorShift; + + m_xSectorEnd >>= Map.SectorShift; + m_ySectorEnd >>= Map.SectorShift; + + m_CurrentIndex = -1; + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Items; + } + } + + private class MobileEnumerator : IPooledEnumerator + { + private Map m_Map; + private Rectangle2D m_Bounds; + + private int m_xSector, m_ySector; + private int m_xSectorStart, m_ySectorStart; + private int m_xSectorEnd, m_ySectorEnd; + private List m_CurrentList; + private int m_CurrentIndex; + + private static Queue m_InstancePool = new Queue(); + + public static MobileEnumerator Instantiate(Map map, Rectangle2D bounds) + { + MobileEnumerator e = null; + + lock (m_InstancePool) + { + if (m_InstancePool.Count > 0) + { + e = m_InstancePool.Dequeue(); + + e.m_Map = map; + e.m_Bounds = bounds; + } + } + + if (e == null) + { + e = new MobileEnumerator(map, bounds); + } + + e.Reset(); + + return e; + } + + public void Free() + { + if (m_Map == null) + return; + + m_Map = null; + + lock (m_InstancePool) + { + if (m_InstancePool.Count < 200) // Arbitrary + m_InstancePool.Enqueue(this); + } + } + + private MobileEnumerator(Map map, Rectangle2D bounds) + { + m_Map = map; + m_Bounds = bounds; + } + + public Mobile Current + { + get + { + return m_CurrentList[m_CurrentIndex]; + } + } + + object IEnumerator.Current { get { return m_CurrentList[m_CurrentIndex]; } } + + void IDisposable.Dispose() { } + + public bool MoveNext() + { + while (true) + { + ++m_CurrentIndex; + + if (m_CurrentIndex == m_CurrentList.Count) + { + ++m_ySector; + + if (m_ySector > m_ySectorEnd) + { + m_ySector = m_ySectorStart; + ++m_xSector; + + if (m_xSector > m_xSectorEnd) + { + m_CurrentIndex = -1; + return false; + } + } + + m_CurrentIndex = -1; + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Mobiles; + } + else + { + Mobile m = m_CurrentList[m_CurrentIndex]; + + if ( !m.Deleted && m_Bounds.Contains( m.Location ) ) + return true; + } + } + } + + public void Reset() + { + m_Map.Bound(m_Bounds.Start.m_X, m_Bounds.Start.m_Y, out m_xSectorStart, out m_ySectorStart); + m_Map.Bound(m_Bounds.End.m_X - 1, m_Bounds.End.m_Y - 1, out m_xSectorEnd, out m_ySectorEnd); + + m_xSector = m_xSectorStart >>= Map.SectorShift; + m_ySector = m_ySectorStart >>= Map.SectorShift; + + m_xSectorEnd >>= Map.SectorShift; + m_ySectorEnd >>= Map.SectorShift; + + m_CurrentIndex = -1; + m_CurrentList = m_Map.InternalGetSector(m_xSector, m_ySector).Mobiles; + } + } + + private class MultiTileEnumerator : IPooledEnumerator + { + private List m_List; + private Point2D m_Location; + private StaticTile[] m_Current; + private int m_Index; + + private static Queue m_InstancePool = new Queue(); + + public static MultiTileEnumerator Instantiate(Sector sector, Point2D loc) + { + MultiTileEnumerator e = null; + + lock (m_InstancePool) + { + if (m_InstancePool.Count > 0) + { + e = m_InstancePool.Dequeue(); + + e.m_List = sector.Multis; + e.m_Location = loc; + } + } + + if (e == null) + { + e = new MultiTileEnumerator(sector, loc); + } + + e.Reset(); + + return e; + } + + private MultiTileEnumerator(Sector sector, Point2D loc) { m_List = sector.Multis; m_Location = loc; } - public object Current { get { return m_Current; } } + public StaticTile[] Current { get { return m_Current; } } + + object IEnumerator.Current { get { return m_Current; } } + + void IDisposable.Dispose() { } public bool MoveNext() { - while ( ++m_Index < m_List.Count ) + while (++m_Index < m_List.Count) { BaseMulti m = m_List[m_Index]; - if ( m != null && !m.Deleted ) + if (m != null && !m.Deleted) { MultiComponentList list = m.Components; - int xOffset = m_Location.m_X - ( m.Location.m_X + list.Min.m_X ); - int yOffset = m_Location.m_Y - ( m.Location.m_Y + list.Min.m_Y ); + int xOffset = m_Location.m_X - (m.Location.m_X + list.Min.m_X); + int yOffset = m_Location.m_Y - (m.Location.m_Y + list.Min.m_Y); - if ( xOffset >= 0 && xOffset < list.Width && yOffset >= 0 && yOffset < list.Height ) + if (xOffset >= 0 && xOffset < list.Width && yOffset >= 0 && yOffset < list.Height) { StaticTile[] tiles = list.Tiles[xOffset][yOffset]; - if ( tiles.Length > 0 ) + if (tiles.Length > 0) { // TODO: How to avoid this copy? StaticTile[] copy = new StaticTile[tiles.Length]; - for ( int i = 0; i < copy.Length; ++i ) + for (int i = 0; i < copy.Length; ++i) { copy[i] = tiles[i]; copy[i].Z += m.Z; @@ -1351,12 +1743,13 @@ namespace Server public void Free() { - if ( m_List == null ) + if (m_List == null) return; - lock (m_InstancePool) { + lock (m_InstancePool) + { if (m_InstancePool.Count < 200) // Arbitrary - m_InstancePool.Enqueue( this ); + m_InstancePool.Enqueue(this); m_List = null; } @@ -1368,284 +1761,6 @@ namespace Server m_Index = -1; } } - - private class ObjectEnumerator : IPooledEnumerator - { - private Map m_Map; - private Rectangle2D m_Bounds; - private SectorEnumerator m_Enumerator; - private int m_Stage; // 0 = items, 1 = mobiles - private object m_Current; - - private static Queue m_InstancePool = new Queue(); - - public static ObjectEnumerator Instantiate( Map map, Rectangle2D bounds ) - { - ObjectEnumerator e = null; - - lock (m_InstancePool) { - if ( m_InstancePool.Count > 0 ) { - e = m_InstancePool.Dequeue(); - - e.m_Map = map; - e.m_Bounds = bounds; - } - } - - if (e == null) { - e = new ObjectEnumerator( map, bounds ); - } - - e.Reset(); - - return e; - } - - public void Free() - { - if ( m_Map == null ) - return; - - m_Map = null; - - if ( m_Enumerator != null ) { - m_Enumerator.Free(); - m_Enumerator = null; - } - - lock (m_InstancePool) { - if (m_InstancePool.Count < 200) // Arbitrary - m_InstancePool.Enqueue( this ); - } - } - - private ObjectEnumerator( Map map, Rectangle2D bounds ) - { - m_Map = map; - m_Bounds = bounds; - } - - public object Current { get { return m_Current; } } - - public bool MoveNext() - { - while ( true ) - { - if ( m_Enumerator.MoveNext() ) - { - object o; - - try - { - o = m_Enumerator.Current; - } - catch - { - continue; - } - - if ( o is Mobile ) - { - Mobile m = (Mobile) o; - - if ( m_Bounds.Contains( m.Location ) ) - { - m_Current = o; - return true; - } - } - else if ( o is Item ) - { - Item item = (Item) o; - - if ( item.Parent == null && m_Bounds.Contains( item.Location ) ) - { - m_Current = o; - return true; - } - } - } - else if ( m_Stage == 0 ) - { - m_Enumerator.Free(); - m_Enumerator = SectorEnumerator.Instantiate( m_Map, m_Bounds, SectorEnumeratorType.Mobiles ); - - m_Current = null; - m_Stage = 1; - } - else - { - m_Enumerator.Free(); - m_Enumerator = null; - - m_Current = null; - m_Stage = -1; - - return false; - } - } - } - - public void Reset() - { - m_Stage = 0; - - m_Current = null; - - if ( m_Enumerator != null ) - m_Enumerator.Free(); - - m_Enumerator = SectorEnumerator.Instantiate( m_Map, m_Bounds, SectorEnumeratorType.Items ); - } - } - - private class SectorEnumerator : IPooledEnumerator - { - private Map m_Map; - private Rectangle2D m_Bounds; - - private int m_xSector, m_ySector; - private int m_xSectorStart, m_ySectorStart; - private int m_xSectorEnd, m_ySectorEnd; - private IList m_CurrentList; - private int m_CurrentIndex; - private SectorEnumeratorType m_Type; - - private static Queue m_InstancePool = new Queue(); - - public static SectorEnumerator Instantiate( Map map, Rectangle2D bounds, SectorEnumeratorType type ) - { - SectorEnumerator e = null; - - lock (m_InstancePool) { - if ( m_InstancePool.Count > 0 ) { - e = m_InstancePool.Dequeue(); - - e.m_Map = map; - e.m_Bounds = bounds; - e.m_Type = type; - } - } - - if (e == null) { - e = new SectorEnumerator( map, bounds, type ); - } - - e.Reset(); - - return e; - } - - public void Free() - { - if ( m_Map == null ) - return; - - m_Map = null; - - lock (m_InstancePool) { - if (m_InstancePool.Count < 200) // Arbitrary - m_InstancePool.Enqueue( this ); - } - } - - private SectorEnumerator( Map map, Rectangle2D bounds, SectorEnumeratorType type ) - { - m_Map = map; - m_Bounds = bounds; - m_Type = type; - } - - private IList GetListForSector( Sector sector ) - { - switch ( m_Type ) - { - case SectorEnumeratorType.Clients: - return sector.Clients; - case SectorEnumeratorType.Mobiles: - return sector.Mobiles; - case SectorEnumeratorType.Items: - return sector.Items; - default: - throw new Exception( "Invalid SectorEnumeratorType" ); - } - } - - public object Current - { - get - { - return m_CurrentList[m_CurrentIndex]; - /*try - { - return m_CurrentList[m_CurrentIndex]; - } - catch - { - Console.WriteLine( "Warning: Object removed during enumeration. May not be recoverable" ); - - m_CurrentIndex = -1; - m_CurrentList = GetListForSector( m_Map.InternalGetSector( m_xSector, m_ySector ) ); - - if ( MoveNext() ) - { - return Current; - } - else - { - throw new Exception( "Object disposed during enumeration. Was not recoverable." ); - } - }*/ - } - } - - public bool MoveNext() - { - while ( true ) - { - ++m_CurrentIndex; - - if ( m_CurrentIndex == m_CurrentList.Count ) - { - ++m_ySector; - - if ( m_ySector > m_ySectorEnd ) - { - m_ySector = m_ySectorStart; - ++m_xSector; - - if ( m_xSector > m_xSectorEnd ) - { - m_CurrentIndex = -1; - return false; - } - } - - m_CurrentIndex = -1; - m_CurrentList = GetListForSector( m_Map.InternalGetSector( m_xSector, m_ySector ) );//m_Map.m_Sectors[m_xSector][m_ySector] ); - } - else - { - return true; - } - } - } - - public void Reset() - { - m_Map.Bound( m_Bounds.Start.m_X, m_Bounds.Start.m_Y, out m_xSectorStart, out m_ySectorStart ); - m_Map.Bound( m_Bounds.End.m_X - 1, m_Bounds.End.m_Y - 1, out m_xSectorEnd, out m_ySectorEnd ); - - m_xSector = m_xSectorStart >>= Map.SectorShift; - m_ySector = m_ySectorStart >>= Map.SectorShift; - - m_xSectorEnd >>= Map.SectorShift; - m_ySectorEnd >>= Map.SectorShift; - - m_CurrentIndex = -1; - m_CurrentList = GetListForSector( m_Map.InternalGetSector( m_xSector, m_ySector ) ); - } - } #endregion public Point3D GetPoint( object o, bool eye ) diff --git a/Server/Mobile.cs b/Server/Mobile.cs index 896e2e2f6..1fabb6805 100644 --- a/Server/Mobile.cs +++ b/Server/Mobile.cs @@ -4776,7 +4776,7 @@ namespace Server Map map = m_Map; if( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; return map.GetItemsInRange( m_Location, range ); } @@ -4786,7 +4786,7 @@ namespace Server Map map = m_Map; if( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; return map.GetObjectsInRange( m_Location, range ); } @@ -4796,7 +4796,7 @@ namespace Server Map map = m_Map; if( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; return map.GetMobilesInRange( m_Location, range ); } @@ -4806,7 +4806,7 @@ namespace Server Map map = m_Map; if( map == null ) - return Server.Map.NullEnumerable.Instance; + return Server.Map.NullEnumerable.Instance; return map.GetClientsInRange( m_Location, range ); } @@ -4866,7 +4866,7 @@ namespace Server IPooledEnumerable eable = m_Map.GetObjectsInRange( m_Location, range ); #if Framework_4_0 - Parallel.ForEach(eable.Cast(), o => { + Parallel.ForEach(eable, o => { #else foreach(IEntity o in eable) { #endif @@ -6601,9 +6601,9 @@ namespace Server { IPooledEnumerable eable = m_Map.GetObjectsInRange( m_Location, Core.GlobalMaxUpdateRange ); #if Framework_4_0 - Parallel.ForEach( eable.Cast(), o => { + Parallel.ForEach(eable, o => { #else - foreach( object o in eable ) { + foreach ( object o in eable ) { #endif if( o is Mobile ) { Mobile m = (Mobile)o; @@ -6806,9 +6806,9 @@ namespace Server { IPooledEnumerable eable = m_Map.GetObjectsInRange( m_Location, Core.GlobalMaxUpdateRange ); #if Framework_4_0 - Parallel.ForEach( eable.Cast(), o => { + Parallel.ForEach(eable, o => { #else - foreach( object o in eable ) { + foreach ( object o in eable ) { #endif if( o is Item ) { Item item = (Item)o; @@ -9139,9 +9139,9 @@ namespace Server // We are attached to a client, so it's a bit more complex. We need to send new items and people to ourself, and ourself to other clients #if Framework_4_0 - Parallel.ForEach( eable.Cast(), o => { + Parallel.ForEach(eable, o => { #else - foreach( object o in eable ) { + foreach ( object o in eable ) { #endif if( o is Item ) { diff --git a/Server/TileMatrix.cs b/Server/TileMatrix.cs index f0ffc1f4d..aeb460105 100644 --- a/Server/TileMatrix.cs +++ b/Server/TileMatrix.cs @@ -309,7 +309,7 @@ namespace Server { IPooledEnumerable eable = m_Owner.GetMultiTilesAt( x, y ); - if ( eable == Map.NullEnumerable.Instance ) + if ( eable == Map.NullEnumerable.Instance ) return tiles[x & 0x7][y & 0x7]; bool any = false; diff --git a/Server/World.cs b/Server/World.cs index 9ffafe3d6..a6de47a17 100644 --- a/Server/World.cs +++ b/Server/World.cs @@ -850,7 +850,8 @@ namespace Server { int length = idxReader.ReadInt32(); createEventArgs.Id = id; - BaseGuild guild = EventSink.InvokeCreateGuild( createEventArgs ); + EventSink.InvokeCreateGuild(createEventArgs); + BaseGuild guild = createEventArgs.Guild; if ( guild != null ) guilds.Add( new GuildEntry( guild, pos, length ) ); }