Go Back   RunUO - Ultima Online Emulation > RunUO > Custom Script Release Archive

Custom Script Release Archive This is a pre-script database archive of what our users had released.

 
 
Thread Tools Display Modes
Old 08-14-2005, 03:34 PM   #1 (permalink)
Forum Expert
 
arul's Avatar
 
Join Date: Jan 2005
Location: Hic sunt leones ...
Age: 21
Posts: 1,300
Send a message via MSN to arul
Default [Hint] : Enumeration has changed exception

Sometimes you need in your custom scripts to iterate for example through the World.Mobiles or World.Item hashtables and delete certain entry on the fly. But you can't do that since you can't change collection ( hashtable ) while iterating through it.
One way how to do it is write an array where you temporarily store objects to be deleted.
Code:
public ArrayList toDelete;
foreach ( Mobile m in World.Mobiles.Values )
{
if ( /* condition */ )
toDelete.Add ( m );
}
foreach ( Mobile m in toDelete )
{
m.Delete();
}
But its too unpractical to write it again and again for every single script.
Easier way to do it is by isolating the enemuration from the collection using custom enumerator:
Code:
    public class Isolator : IEnumerable
    {
        internal class IsolatorEnumerator : IEnumerator
        {
            ArrayList items = new ArrayList();
            int currentItem;

            internal IsolatorEnumerator( IEnumerator enumerator )
            {
                while ( enumerator.MoveNext() != false )
                {
                    items.Add( enumerator.Current );
                }
                IDisposable disposable = enumerator as IDisposable;
                if ( disposable != null )
                {
                    disposable.Dispose();
                }
                currentItem = -1;
            }

            public void Reset( )
            {
                currentItem = -1;
            }

            public bool MoveNext( )
            {
                currentItem++;
                if ( currentItem == items.Count )
                    return false;

                return true;
            }

            public object Current
            {
                get
                {
                    return items[currentItem];
                }
            }
        }

        public Isolator( IEnumerable enumerable )
        {
            this.enumerable = enumerable;
        }

        public IEnumerator GetEnumerator( )
        {
            return new IsolatorEnumerator( enumerable.GetEnumerator() );
        }

        IEnumerable enumerable;
    }
And finally you can do:
Code:
                        foreach ( Mobile m in new Isolator( World.Mobiles.Values ) )
                        {
                            if ( /* condition */ )
                            {
                                m.Delete();
                            }
                        }
This is just example that can be useful for many people, use it at your own risk
arul is offline  
 

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off



Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.2.0 RC5