cotopboy
9/2/2013 - 8:45 AM

LabMapSend_Safe Class is a singlton class which provides functions to send integer, real and string value to LabMap safely. All these Send-

LabMapSend_Safe Class is a singlton class which provides functions to send integer, real and string value to LabMap safely. All these Send-functions in this class will send value in the folloing process:

1.Call LabMap API LabMapSendXXX(..) to send the value to the specific handle. 2.Call LabMap API LabMapWait() to make sure to continue after the operation finished. 3.Call LabMap API LabMapGetXXX(..) to make sure the setValue is the same as the returnValue from the handle.

When the tryCount bigger than tryCountLimit in each sending process
A LabMapSendValueFailException will be thrown.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Loop_Beleuchtung_Stadtpark_Norderstedt
{
    /// <summary>
    /// LabMapSend_Safe Class is a singlton class
    /// which provides functions to send integer, real and string value to LabMap safely.
    /// All these Send-functions in this class will send value in the folloing process:
    /// 
    /// 1.Call LabMap API LabMapSendXXX(..) to send the value to the specific handle.
    /// 2.Call LabMap API LabMapWait() to make sure to continue after the operation finished.
    /// 3.Call LabMap API LabMapGetXXX(..) to make sure the setValue is the same as the returnValue from the handle.
    /// 
    /// When the tryCount bigger than tryCountLimit in each sending process
    /// A LabMapSendValueFailException will be thrown.
    /// </summary>
    public class LabMapSend_Safe
    {
        #region Singleton 
        private static volatile LabMapSend_Safe instance;

        private static object syncRoot = new object();
        private static object syncRoot_Int = new object();
        private static object syncRoot_Real = new object();
        private static object syncRoot_String = new object();

        public static LabMapSend_Safe Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new LabMapSend_Safe();
                    }
                }
                return instance;
            }

        }
        #endregion

        LabMapDotNet.LabMap lab_map = LabMapDotNet.LabMap.Instance;

        public void LabMapSendInt_Safe(uint handleNo, int setValue, int tryCountLimit)
        {
            int returnValue = int.MinValue;
            int tryCount = 0;
            
            lock (syncRoot_Int)
            {
                do
                {
                    if (tryCount >= tryCountLimit)
                    {
                        Exception exp =  new LabMapSendValueFailedException(handleNo, typeof(int), setValue);
                        LabMapSendLogger.Instance.LogLabMapSendException(exp);
                        throw exp;
                    }
                    try
                    {

                        lab_map.LabMapSendInt(handleNo, setValue);

                        lab_map.LabMapWait(handleNo);

                        int status = lab_map.LabMapGetStatus(handleNo, 0);

                        if ((status & LabMapDotNet.LabMapStatus.HandleReady) == LabMapDotNet.LabMapStatus.HandleReady)
                        { 
                            
                        }

                        returnValue = lab_map.LabMapGetInt(handleNo);

                        LabMapSendLogger.Instance.LabMapSendIntLog(handleNo, setValue, returnValue, tryCount);

                    }
                    finally
                    {
                        tryCount++;
                    }
  
                    if (returnValue == setValue) return;

                } while (true);

            }
        }

        public void LabMapSendInt_Safe_Ex(uint handleNo, int setValue, int tryCountLimit)
        {
            int returnValue = int.MinValue;
            int tryCount = 0;

            lock (syncRoot_Int)
            {
                do
                {
                    if (tryCount >= tryCountLimit)
                    {
                        Exception exp = new LabMapSendValueFailedException(handleNo, typeof(int), setValue);
                        LabMapSendLogger.Instance.LogLabMapSendException(exp);
                        throw exp;
                    }
                    try
                    {
                        lab_map.LabMapSendInt(handleNo, setValue);

                        lab_map.LabMapWait(handleNo);

                        returnValue = lab_map.LabMapGetInt(handleNo);
                        LabMapSendLogger.Instance.LabMapSendIntLog(handleNo, setValue, returnValue, tryCount);
                    }
                    finally
                    {
                        tryCount++;
                    }
                    if (this.CheckIntReturnValueValid(setValue,returnValue)) return;

                } while (true);

            }

        }

        private bool CheckIntReturnValueValid(int setValue,int returnValue)
        {
            int off               = 0;      //    -> 9
            int start_ramp_up     = 1;      //    -> 11     -> 10
            int start_breathing   = 2;      //    -> 21     -> 20
            int restart_breathing = 21;     //  
            int start_ramp_down   = 3;      //    -> 31     -> 30 
            int start_lightplay   = 4;      //    -> 41 
            int set_max_values    = 5;      //    -> 50

            if (setValue == off               ) { return ((returnValue == setValue) || (returnValue == 9)) ; }
            if (setValue == start_ramp_up     ) { return ((returnValue == setValue) || (returnValue == 10) || (returnValue == 11));}
            if (setValue == start_breathing   ) { return ((returnValue == setValue) || (returnValue == 21) || (returnValue == 20));}
            if (setValue == restart_breathing ) { return ( returnValue == setValue);}
            if (setValue == start_ramp_down   ) { return ((returnValue == setValue) || (returnValue == 31) || (returnValue == 30));}
            if (setValue == start_lightplay   ) { return ((returnValue == setValue) || (returnValue == 41));}
            if (setValue == set_max_values    ) { return ((returnValue == setValue) || (returnValue == 50));}

            return (setValue == returnValue);

        }


        public void LabMapSendReal_Safe(uint handleNo, double setValue, int tryCountLimit)
        {
            float returnValue = float.NaN ;
            int tryCount = 0;

            lock (syncRoot_Real)
            {
                do
                {
                    if (tryCount >= tryCountLimit)
                    {
                        Exception exp =  new LabMapSendValueFailedException(handleNo, typeof(float), setValue);
                        LabMapSendLogger.Instance.LogLabMapSendException(exp);
                        throw exp;
                    }
                    try
                    {
                        lab_map.LabMapSendReal(handleNo, (float)setValue);

                        lab_map.LabMapWait(handleNo);

                        returnValue = lab_map.LabMapGetReal(handleNo);

                        LabMapSendLogger.Instance.LabMapSendRealLog(handleNo, (float)setValue, returnValue, tryCount);
                    }
                    finally
                    {
                        tryCount++;
                    }

                    if (Math.Abs(returnValue - setValue) < 0.001f) return;

                } while (true);
            }
        }

        public void LabMapSendString_Safe(uint handleNo, string setValue, int tryCountLimit)
        {
            string returnValue = string.Empty;
            int tryCount = 0;

            lock (syncRoot_String)
            {
                do
                {
                    if (tryCount >= tryCountLimit)
                    {
                        Exception exp = new LabMapSendValueFailedException(handleNo, typeof(int), setValue);
                        LabMapSendLogger.Instance.LogLabMapSendException(exp);
                        throw exp;
                    }
                    try
                    {
                        lab_map.LabMapSendString(handleNo, setValue);

                        lab_map.LabMapWait(handleNo);

                        returnValue = lab_map.LabMapGetString(handleNo);

                        LabMapSendLogger.Instance.LabMapSendStringLog(handleNo, setValue, returnValue, tryCount);
                    }
                    finally
                    {
                        tryCount++;
                    }

                    if (returnValue == setValue) return;

                } while (true);
            }
        }

        
    }

    public class LabMapSendValueFailedException : Exception
    {
        private uint _handleNo;
        private Type _valueType;
        private object _value;

        public uint HandleNo
        {
            get { return _handleNo; }
            set { _handleNo = value; }
        }

        public Type ValueType
        {
            get { return _valueType; }
            set { _valueType = value; }
        }

        public object Value
        {
            get { return _value; }
            set { _value = value; }
        }

        public LabMapSendValueFailedException(uint handleNo, Type valueType, object value)
        {
            this._handleNo = handleNo;
            this._valueType = valueType;
            this._value = value;
        }
    }

    public class LabMapSendLogger
    {
        #region Singleton
        private static volatile LabMapSendLogger instance;

        private static object syncRoot = new object();
        private static object syncRoot_Write = new object();

        public static LabMapSendLogger Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new LabMapSendLogger();
                    }
                }
                return instance;
            }

        }

        private LabMapSendLogger()
        {
            Initialize();
        }

        #endregion

        private string logFileName = "LabMapSendLog.txt";
        private bool isLogEnable = false;
        private FileStream fs = null;

        private void Initialize()
        {
            this.isLogEnable = (ini_settings.GetValue("DEBUG", "enable_labmap_send_log") == "True");
            fs = new FileStream(logFileName, FileMode.Append);
        }

        public void LogLabMapSendException(Exception exp)
        {
            lock (syncRoot_Write)
            {
                if (!this.isLogEnable) return;
                if (exp != null)
                {
                    this.LogExceptiontoFile(exp);
                }
            }
        }

        public void LabMapSendIntLog(uint handleNo, int value, int returnValue, int tryCount)
        {
            lock (syncRoot_Write)
            {
                if (!this.isLogEnable) return;
                string logText = string.Format("TryCount:{2} TimeStamp:{3}      {4}<==LabMapSendInt({0},{1});", handleNo, value, tryCount, DateTime.Now.ToString("g"), returnValue);
                this.LogTxtToFile(logText);
            }
        }

        public void LabMapSendRealLog(uint handleNo, float value, float returnValue, int tryCount)
        {
            lock (syncRoot_Write)
            {
                if (!this.isLogEnable) return;
                string logText = string.Format("TryCount:{2} TimeStamp:{3}      {4}<==LabMapSendReal({0},{1});", handleNo, value, tryCount, DateTime.Now.ToString("g"), returnValue);
                this.LogTxtToFile(logText);
            }
        }

        public void LabMapSendStringLog(uint handleNo, string value, string returnValue, int tryCount)
        {
            lock (syncRoot_Write)
            {
                if (!this.isLogEnable) return;
                string logText = string.Format("TryCount:{2} TimeStamp:{3}      {4}<==LabMapSendString({0},\"{1}\");", handleNo, value, tryCount, DateTime.Now.ToString("g"), returnValue);
                this.LogTxtToFile(logText);
            }
        }

        private void LogTxtToFile(string txt)
        {
            try
            {
                byte[] data = new UTF8Encoding().GetBytes(txt + Environment.NewLine);
                fs.Write(data, 0, data.Length);
                fs.Flush();
            }
            catch { }
        }

        private void LogExceptiontoFile(Exception objException)
        {
            try
            {
                string content = Exception2TextString(objException);
                byte[] data = new UTF8Encoding().GetBytes(content.ToString());
                fs.Write(data, 0, data.Length);
                fs.Flush();
            }
            catch { }
        }

        private string Exception2TextString(Exception objException)
        {
            StringBuilder content = new StringBuilder(1000);
            content.AppendLine("");
            content.AppendLine("=============================================");
            content.AppendLine("+++++++++++LabMapSend Error++++++++++++++++++");

            content.AppendLine("Date  	: " + DateTime.Now.ToLongTimeString());
            content.AppendLine("Time		: " + DateTime.Now.ToShortDateString());
            content.AppendLine("Error		: " + objException.Message.ToString().Trim());
            content.AppendLine(objException.Message);
            if (objException is LabMapSendValueFailedException)
            {
                LabMapSendValueFailedException exp = objException as LabMapSendValueFailedException;
                content.AppendLine("HandleNo    : " + exp.HandleNo);
                content.AppendLine("Error		: " + exp.Value.ToString());
            }

            content.AppendLine("+++++++++++++++++++++++++++++++++++++++++++++");
            return content.ToString();
        }

        ~LabMapSendLogger()
        {
            fs.Close();
        }

    }



    /*
    public class TestClass
    {
        public TestClass()
        { 
            try
            {
                LabMapSend_Safe.Instance.LabMapSendInt_Safe(1, 1, 5);
    
            }
            catch(LabMapSendValueFailedException exp)
            {
                System.Windows.Forms.MessageBox.Show(
                        string.Format("HanedleNo:{0} ValueType:{1} Value:{2}",
                        exp.HandleNo,
                        exp.ValueType,
                        exp.Value));
            }

        }
            
   }*/
}