Swapper.NET Logo

Source Code Interfaces ~ BasePlugIn.cs


using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using RevolutionaryStuff.JBT;

namespace RevolutionaryStuff.P2P.Basics
{
	/// 
	/// Summary description for BasePlugIn.
	/// 
	public class BasePlugIn : IPlugIn
	{
		private TimeSpan WaterMarkSleep;
		private readonly ManualResetEvent ShutdownEvent = new ManualResetEvent(false);

		public DateTime CreationTime
		{
			[DebuggerStepThrough]
			get { return this.CreationTime_p; }
		}
		private readonly DateTime CreationTime_p = DateTime.Now;

		protected BasePlugIn(TimeSpan waterMarkSleep)
		{
			this.WaterMarkSleep = waterMarkSleep;
		}

		public ICore Core
		{
			[DebuggerStepThrough]
			get { return this.Core_p; }
		}
		private ICore Core_p;

		protected IPlugInInitParams InitParam
		{
			[DebuggerStepThrough]
			get { return this.InitParam_p; }
		}
		private IPlugInInitParams InitParam_p;

		protected readonly Stats Stats = new Stats();

		private Thread WaterMarkThread;

		protected int WaterMarkCalls
		{
			[DebuggerStepThrough]
			get { return this.WaterMarkCalls_p;}
		}
		private int WaterMarkCalls_p;

		private void WaterMark()
		{
			for (;;)
			{
				try
				{
					WaterMark2();
				}
				catch (Exception ex)
				{
					Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManager.Publish(ex);
				}
				++WaterMarkCalls_p;
				if (ShutdownEvent.WaitOne(this.WaterMarkSleep, true)) break;
			}
		}

		protected virtual void WaterMark2()
		{}

		#region IPlugIn Members

		public void Init(IPlugInInitParams initParam)
		{
			if (null==initParam) throw new ArgumentNullException("initParam");
			if (null==initParam.Core) throw new ArgumentNullException("initParam.Core");
			this.Core_p = initParam.Core;
			this.InitParam_p = initParam;
			Init2();
		}

		protected virtual void Init2()
		{
			IConfigurationManager cm = this.ConfigurationManager;
			if (cm==null) return;
			try
			{
				using (Stream st = this.InitParam.CompoundFile.OpenStream(ConfigDataStreamName))
				{
					StreamReader sr = new StreamReader(st);
					string config = sr.ReadToEnd();
					cm.SetConfigData(config);
				}		
			}
			catch (Exception){}
		}

		private int StartCalled;
		public void Start()
		{
			if (1!=Interlocked.Increment(ref StartCalled)) throw new SingleCallException();
			Start2();
			if (this.WaterMarkSleep.TotalSeconds==0) return;
			this.WaterMarkThread = Stuff.ThreadCreate(
				new ThreadStart(WaterMark), 
				string.Format("{0} Watermark", this.GetType().Name),
				true,
				true);
		}
		protected virtual void Start2()
		{}

		private int ShutdownCalled;
		public void Shutdown()
		{
			if (1!=Interlocked.Increment(ref ShutdownCalled)) throw new SingleCallException();
			try
			{
				Shutdown2();
			}
			catch (Exception ex)
			{
				Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManager.Publish(ex);
			}
			this.ShutdownEvent.Set();
			if (this.WaterMarkThread==null) return;
			if (!this.WaterMarkThread.Join(1000))
			{
				this.WaterMarkThread.Abort();
			}
		}

		protected virtual void Shutdown2()
		{
			Save();
		}

		public virtual IAbout About
		{
			get
			{
				if (null==About_p)
				{
					this.About_p = AboutCreate();
				}
				return this.About_p;
			}
		}
		private IAbout About_p;

		protected virtual IAbout AboutCreate()
		{
			return new About(this.GetType());
		}

		public virtual IConfigurationManager ConfigurationManager 
		{ 
			get
			{
				if (null==ConfigurationManager_p)
				{
					this.ConfigurationManager_p = ConfigurationManagerCreate();
				}
				return this.ConfigurationManager_p;			
			}
		}
		private IConfigurationManager ConfigurationManager_p;

		protected virtual IConfigurationManager ConfigurationManagerCreate()
		{
			return null;
		}

		#endregion

		private int Saving;
		protected void Save()
		{
			try
			{
				if (1!=Interlocked.Increment(ref Saving)) return;
				Save2();
			}
			catch (Exception ex)
			{
				Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManager.Publish(ex);
			}
			finally
			{
				Interlocked.Decrement(ref Saving);
			}
		}

		protected const string ConfigDataStreamName = "Config";

		protected virtual void Save2()
		{
			IConfigurationManager cm = this.ConfigurationManager;
			if (cm==null) return;
			string config = cm.GetConfigData();
			using (Stream st = this.InitParam.CompoundFile.CreateStream(ConfigDataStreamName))
			{
				StreamWriter sw = new StreamWriter(st);
				sw.Write(config);
				sw.Close();
			}
		}
	}
}