zerodowned

Moderator
Writing some code that requires a list of Timers, but you can't serialize a Timer...

Best solution I've thought of was creating a List of INT, using INT as an ontick countdown for a timer and when the INT reaches zero the timer stops.
Then I can ser/deser the List of INT and can add Timers back using that as a way to save how much time is left on each timer.

Is there a better way to do this?
 
I would think TimeSpan would be the proper way compared to int, but in the end if you deserialize it properly it should be fine.
 
Here's the solution I came up with, it's a little rough but it's a test so don't care to polish it up

I created a new class TimeRemaining that holds the timer and saves how much time is left on it's timer.
This way I only need one list to save the timer and it's time remaining
I also included console writelines for testing purposes


C#:
using System;
using System.Collections;
using System.Collections.Generic;
using Server;

namespace Server.Items
{
    public class TimerListTestItem : Item
    {
        private List<TimeRemaining> _TimerList;
       
        public List<TimeRemaining> TimerList
        {
            get { return _TimerList; }
        }
       
        [Constructable]
        public TimerListTestItem() : base(0x0)
        {
            Name = "TimerListTestItem";
            Hue = 350;
            ItemID = 5359;

            this._TimerList = new List<TimeRemaining>();
        }
       
        public override void AddNameProperty(ObjectPropertyList list)
        {
            base.AddNameProperty(list);
           list.Add("{0}", this.TimerList.Count ); //FFFFFF
           
        }
       
        public override void OnDoubleClick(Mobile from)
        {
            TimeRemaining t = new TimeRemaining( this, 5 );
            TimerList.Add( t );
        }
       
        public TimerListTestItem(Serial serial) : base(serial)
        {
        }
       
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write(0);
           
            writer.Write(this.TimerList.Count);
           
            for (int i = 0; i < this.TimerList.Count; ++i)
                this.TimerList[i].Serialize(writer);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            int counter = reader.ReadInt();
           
            this._TimerList = new List<TimeRemaining>(counter);

            for (int i = 0; i < counter; i++)
            {
                this.TimerList.Add(new TimeRemaining(reader));
            }
        }
       
        public class TimeRemaining
        {
            private TimerListTestItem _Test;
            public int Time { get; set;}
            public Timer InternalTimer;
           
            public TimerListTestItem Test
            {
                get { return _Test; }
            }
           
            public TimeRemaining( TimerListTestItem timer, int time )
            {
                _Test = timer;
                Time = time;
            }
           
            public virtual void StartTimer()
            {
                if (this.InternalTimer != null)
                    return;
               
                InternalTimer t = new InternalTimer(this);
                t.Start();
            }
           
            public void Serialize(GenericWriter writer)
            {
                writer.Write(0);
                writer.Write(_Test);
                writer.Write(Time);
            }

            public TimeRemaining(GenericReader reader)
            {
                int version = reader.ReadInt();
               
                _Test = reader.ReadItem() as TimerListTestItem;
                Time = reader.ReadInt();
               
                this.StartTimer();
            }
        }
       
        public class InternalTimer  : Timer
        {
            private TimeRemaining parent;
           
            public InternalTimer ( TimeRemaining p ) : base( TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1) )
            {
                Priority = TimerPriority.OneSecond;
                parent = p;
            }
   
            protected override void OnTick()
            {
                if ( this.parent.Time <= 0 )
                {
                    Stop();
                    Console.WriteLine("Timer stopped");
                   
                    parent.Test.TimerList.RemoveAll( i=> i.Time == 0 );
                    parent.InternalTimer = null;
                }
                else
                    parent.Time -= 1;
                    Console.WriteLine(this.parent.Time);
            }
        }
       
    }
}
 
changes as mentioned above

C#:
using System;
using System.Collections;
using System.Collections.Generic;
using Server;

namespace Server.Items
{
    public class TimerListTestItem : Item
    {
        private List<TimeRemaining> _TimerList;
       
        public List<TimeRemaining> TimerList
        {
            get { return _TimerList; }
        }
       
        [Constructable]
        public TimerListTestItem() : base(0x0)
        {
            Name = "TimerListTestItem";
            Hue = 350;
            ItemID = 5359;

            this._TimerList = new List<TimeRemaining>();
        }
       
        public override void AddNameProperty(ObjectPropertyList list)
        {
            base.AddNameProperty(list);
           list.Add("{0}", this.TimerList.Count ); //FFFFFF
           
        }
       
        public override void OnDoubleClick(Mobile from)
        {
            TimeRemaining t = new TimeRemaining( this, Utility.RandomMinMax(5, 25) );
            TimerList.Add( t );
            t.StartTimer();
        }
       
        public TimerListTestItem(Serial serial) : base(serial)
        {
        }
       
        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write(0);
           
            writer.Write(this.TimerList.Count);
           
            for (int i = 0; i < this.TimerList.Count; ++i)
                this.TimerList[i].Serialize(writer);
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();

            int counter = reader.ReadInt();
           
            this._TimerList = new List<TimeRemaining>(counter);

            for (int i = 0; i < counter; i++)
            {
                this.TimerList.Add(new TimeRemaining(reader));
            }
        }
       
        public class TimeRemaining
        {
            private TimerListTestItem _Test;
            private int _TimeLeft;
            public Timer InternalTimer;
           
            public TimerListTestItem Test
            {
                get { return _Test; }
            }
           
            public int TimeLeft
            {
                get { return _TimeLeft; }
                set { _TimeLeft = value; }
            }
           
            public TimeRemaining( TimerListTestItem timer, int _TimeLeft )
            {
                _Test = timer;
                TimeLeft = _TimeLeft;
            }
           
            public virtual void StartTimer()
            {
                if (this.InternalTimer != null)
                    return;
                   
                this.InternalTimer = Timer.DelayCall(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), new TimerCallback(Slice));
                this.InternalTimer.Priority = TimerPriority.OneSecond;
               
            }

            public virtual void StopTimer()
            {
                if (this.InternalTimer != null)
                    this.InternalTimer.Stop();
               
                this.InternalTimer = null;
            }

            public virtual void Slice()
            {
                if (this.TimeLeft <= 0)
                    this.Decay();
                else
                {               
                    this.TimeLeft -= 1;
                    Console.WriteLine(this.TimeLeft);
                }
            }

            public virtual void Decay()
            {
                this.StopTimer();
                _Test.TimerList.Remove(this);
                Console.WriteLine("Timer stopped");
            }
           
            public void Serialize(GenericWriter writer)
            {
                writer.Write(0);
                writer.Write(_Test);
                writer.Write(_TimeLeft);
            }

            public TimeRemaining(GenericReader reader)
            {
                int version = reader.ReadInt();
               
                _Test = reader.ReadItem() as TimerListTestItem;
                _TimeLeft = reader.ReadInt();
               
                this.StartTimer();
            }
        }
    }
}
 
Back