/// <summary>
        /// 引数の解決。
        /// </summary>
        /// <param name="varManager">変数管理。</param>
        /// <param name="argsInfo">引数情報。</param>
        /// <param name="args">引数。</param>
        /// <param name="argTypes">引数の型。</param>
        internal static void ResolveArgs(VarPool varManager, object[] argsInfo, out object[] args, out Type[] argTypes)
        {
            args     = new object[argsInfo.Length];
            argTypes = new Type[argsInfo.Length];
            for (int i = 0; i < argsInfo.Length; i++)
            {
                VarAddress handle = argsInfo[i] as VarAddress;

                //値の場合
                if (handle == null)
                {
                    args[i] = argsInfo[i];
                    if (args[i] != null)
                    {
                        argTypes[i] = args[i].GetType();
                    }
                }
                //変数の場合は登録されているオブジェクトに変換
                else
                {
                    VarAndType varAndType = varManager.GetVarAndType(handle);
                    args[i]     = varAndType.Core;
                    argTypes[i] = varAndType.Type;
                }
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// 存命解除。
 /// </summary>
 /// <param name="varAddress">変数アドレス。</param>
 internal void FreeKeepAlive(VarAddress varAddress)
 {
     lock (this)
     {
         int count = 0;
         if (!_keepAlive.TryGetValue(varAddress.Core, out count))
         {
             return;
         }
         count--;
         if (count <= 0)
         {
             _keepAlive.Remove(varAddress.Core);
             if (!_handleAndObject.ContainsKey(varAddress.Core))
             {
                 //すでに変数プールから削除されているなら番号解放
                 _varAddressManager.FreeNo(varAddress.Core);
             }
         }
         else
         {
             _keepAlive[varAddress.Core] = count;
         }
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// 戻り値をAppVarで取得する通信。
        /// </summary>
        /// <param name="invoker">呼び出し元。</param>
        /// <param name="friendlyConnector">アプリケーションとの接続者。</param>
        /// <param name="protocolType">通信タイプ。</param>
        /// <param name="operationTypeInfo">操作タイプ情報。</param>
        /// <param name="varAddress">変数アドレス。</param>
        /// <param name="typeFullName">タイプフルネーム。</param>
        /// <param name="operation">操作名称。</param>
        /// <param name="arguments">引数。</param>
        /// <returns>変数。</returns>
        internal static AppVar SendAndVarReceive(object invoker, IFriendlyConnector friendlyConnector, ProtocolType protocolType,
                                                 OperationTypeInfo operationTypeInfo, VarAddress varAddress, string typeFullName, string operation, object[] arguments)
        {
            object     value     = SendAndValueReceive(invoker, friendlyConnector, protocolType, operationTypeInfo, varAddress, typeFullName, operation, arguments);
            VarAddress retHandle = value as VarAddress;

            return((retHandle == null) ? (null) : (new AppVar(friendlyConnector, retHandle)));
        }
Ejemplo n.º 4
0
 /// <summary>
 /// オブジェクトの設定。
 /// </summary>
 /// <param name="varAddress">変数アドレス。</param>
 /// <param name="obj">オブジェクト。</param>
 internal void SetObject(VarAddress varAddress, object obj)
 {
     lock (this)
     {
         //非同期実行時には、値を設定に来ても、受け取る変数自体が削除されていることがありうる
         if (_handleAndObject.ContainsKey(varAddress.Core))
         {
             _handleAndObject[varAddress.Core] = new VarAndType(obj);
         }
     }
 }
Ejemplo n.º 5
0
 /// <summary>
 /// 指定の変数アドレスが存在しない、またはnullであるか。
 /// このメソッドはスレッドセーフである。
 /// </summary>
 /// <param name="varAddress">変数アドレス。</param>
 /// <returns>指定の変数アドレスが存在しない、またはnullであるか。</returns>
 internal bool IsEmptyVar(VarAddress varAddress)
 {
     lock (this)
     {
         VarAndType varAndType;
         if (_handleAndObject.TryGetValue(varAddress.Core, out varAndType))
         {
             return(object.ReferenceEquals(varAndType.Core, null));
         }
         return(true);
     }
 }
Ejemplo n.º 6
0
 /// <summary>
 /// 変数取得。
 /// </summary>
 /// <param name="varAddress">変数アドレス。</param>
 /// <returns>変数。</returns>
 internal VarAndType GetVarAndType(VarAddress varAddress)
 {
     lock (this)
     {
         VarAndType varAndType;
         if (_handleAndObject.TryGetValue(varAddress.Core, out varAndType))
         {
             return(new VarAndType(varAndType.Core, varAndType.Type));
         }
         throw new InternalException();
     }
 }
Ejemplo n.º 7
0
 /// <summary>
 /// 存命登録。
 /// </summary>
 /// <param name="varAddress">変数アドレス。</param>
 internal void KeepAlive(VarAddress varAddress)
 {
     lock (this)
     {
         int count = 0;
         if (!_keepAlive.TryGetValue(varAddress.Core, out count))
         {
             count = 0;
         }
         count++;
         _keepAlive.Remove(varAddress.Core);
         _keepAlive.Add(varAddress.Core, count);
     }
 }
 /// <summary>
 /// 呼び出し後の引数反映。
 /// </summary>
 /// <param name="varManager">変数管理。</param>
 /// <param name="argsInfo">引数情報。</param>
 /// <param name="args">引数。</param>
 internal static void ReflectArgsAfterInvoke(VarPool varManager, object[] argsInfo, object[] args)
 {
     if (argsInfo.Length != args.Length)
     {
         throw new InternalException();
     }
     for (int i = 0; i < argsInfo.Length; i++)
     {
         VarAddress handle = argsInfo[i] as VarAddress;
         if (handle != null)
         {
             varManager.SetObject(handle, args[i]);
         }
     }
 }
 /// <summary>
 /// 存命登録解除。
 /// </summary>
 /// <param name="varManager">変数管理。</param>
 /// <param name="arguments">引数情報。</param>
 /// <param name="handle">戻り値ハンドル。</param>
 static void FreeKeepAlive(VarPool varManager, object[] arguments, VarAddress handle)
 {
     if (handle != null)
     {
         varManager.FreeKeepAlive(handle);
     }
     for (int i = 0; i < arguments.Length; i++)
     {
         VarAddress aliveHandle = arguments[i] as VarAddress;
         if (aliveHandle != null)
         {
             varManager.FreeKeepAlive(aliveHandle);
         }
     }
 }
Ejemplo n.º 10
0
 /// <summary>
 /// 削除。
 /// </summary>
 /// <param name="varAddress">変数アドレス。</param>
 /// <returns>成否。</returns>
 internal bool Remove(VarAddress varAddress)
 {
     lock (this)
     {
         if (!_handleAndObject.ContainsKey(varAddress.Core))
         {
             return(false);
         }
         _handleAndObject.Remove(varAddress.Core);
         if (!_keepAlive.ContainsKey(varAddress.Core))
         {
             //存命中でなければ番号解放
             _varAddressManager.FreeNo(varAddress.Core);
         }
         return(true);
     }
 }
        /// <summary>
        /// メソッドorプロパティー実行。
        /// </summary>
        /// <param name="async">非同期実行用。</param>
        /// <param name="varManager">変数管理。</param>
        /// <param name="info">呼び出し情報。</param>
        /// <param name="obj">実行対象オブジェクト。</param>
        /// <param name="args">操作実行引数。</param>
        /// <param name="method">メソッド情報。</param>
        /// <returns>戻り情報。</returns>
        static ReturnInfo ExecuteMethodOrProperty(IAsyncInvoke async, VarPool varManager,
                                                  ProtocolInfo info, object obj, object[] args, MethodInfo method)
        {
            //戻り値
            VarAddress handle = null;

            if (method.ReturnParameter.ParameterType != typeof(void))
            {
                handle = varManager.Add(null);
            }

            //番号管理から消されないようにする
            KeepAlive(varManager, info.Arguments, handle);

            //非同期実行
            async.Execute(delegate
            {
                ReturnInfo retInfo = new ReturnInfo();
                try
                {
                    object retObj = method.Invoke(obj, args);
                    if (method.ReturnParameter.ParameterType != typeof(void))
                    {
                        varManager.SetObject(handle, retObj);
                    }
                    //ref, outの解決
                    List <object> retArgsTmp = new List <object>();
                    retArgsTmp.Add(null); //完了通知変数を戻す。しかし、ここではまだ格納しない
                    retArgsTmp.AddRange(args);
                    ReflectArgsAfterInvoke(varManager, info.Arguments, retArgsTmp.ToArray());
                }
                catch (Exception e)
                {
                    retInfo = new ReturnInfo(new ExceptionInfo(e));
                }

                //完了通知
                varManager.SetObject((VarAddress)info.Arguments[0], retInfo);

                //存命状態を解く
                FreeKeepAlive(varManager, info.Arguments, handle);
            });

            return(new ReturnInfo(handle));
        }
        /// <summary>
        /// フィールド操作実行。
        /// </summary>
        /// <param name="async">非同期実行用。</param>
        /// <param name="varManager">変数管理。</param>
        /// <param name="info">呼び出し情報。</param>
        /// <param name="obj">実行対象オブジェクト。</param>
        /// <param name="args">操作実行引数。</param>
        /// <param name="field">フィールド情報。</param>
        /// <returns>戻り情報。</returns>
        static ReturnInfo ExecuteField(IAsyncInvoke async, VarPool varManager, ProtocolInfo info,
                                       object obj, object[] args, FieldInfo field)
        {
            //get
            if (args.Length == 0)
            {
                //戻り値格納用
                VarAddress getVar = varManager.Add(null);

                //番号管理から消されないようにする
                KeepAlive(varManager, info.Arguments, getVar);

                //非同期実行
                async.Execute(delegate
                {
                    ReturnInfo retInfo = new ReturnInfo();
                    try
                    {
                        varManager.SetObject(getVar, field.GetValue(obj));
                    }
                    catch (Exception e)
                    {
                        retInfo = new ReturnInfo(new ExceptionInfo(e));
                    }

                    //完了通知
                    varManager.SetObject((VarAddress)info.Arguments[0], retInfo);

                    //存命状態を解く
                    FreeKeepAlive(varManager, info.Arguments, getVar);
                });
                return(new ReturnInfo(getVar));
            }
            //set
            else if (args.Length == 1)
            {
                //番号管理から消されないようにする
                KeepAlive(varManager, info.Arguments, null);

                //非同期実行
                async.Execute(delegate
                {
                    ReturnInfo retInfo = new ReturnInfo();
                    try
                    {
                        field.SetValue(obj, args[0]);
                    }
                    catch (Exception e)
                    {
                        retInfo = new ReturnInfo(new ExceptionInfo(e));
                    }

                    //完了通知
                    varManager.SetObject((VarAddress)info.Arguments[0], retInfo);

                    //存命状態を解く
                    FreeKeepAlive(varManager, info.Arguments, null);
                });
                return(new ReturnInfo());
            }
            throw new InternalException();
        }
Ejemplo n.º 13
0
 /// <summary>
 /// コンストラクタ。
 /// </summary>
 /// <param name="friendlyConnector">アプリケーションとの接続クラス。</param>
 /// <param name="varAddress">変数アドレス</param>
 internal AppVar(IFriendlyConnector friendlyConnector, VarAddress varAddress)
 {
     _friendlyConnector = friendlyConnector;
     _varAddress        = varAddress;
 }
Ejemplo n.º 14
0
        /// <summary>
        /// 戻り値を値で取得する通信処理。
        /// 通信基本形。
        /// </summary>
        /// <param name="invoker">呼び出し元。</param>
        /// <param name="friendlyConnector">アプリケーションとの接続者。</param>
        /// <param name="protocolType">通信タイプ。</param>
        /// <param name="operationTypeInfo">操作タイプ情報。</param>
        /// <param name="varAddress">変数アドレス。</param>
        /// <param name="typeFullName">タイプフルネーム。</param>
        /// <param name="operation">操作名称。</param>
        /// <param name="arguments">引数。</param>
        /// <returns>値。</returns>
        internal static object SendAndValueReceive(object invoker, IFriendlyConnector friendlyConnector, ProtocolType protocolType,
                                                   OperationTypeInfo operationTypeInfo, VarAddress varAddress, string typeFullName, string operation, object[] arguments)
        {
            //配列の場合の調整
            arguments = AdjustArrayArgs(arguments);

            ReturnInfo ret = friendlyConnector.SendAndReceive(new ProtocolInfo(protocolType, operationTypeInfo, varAddress, typeFullName, operation, ConvertAppVar(friendlyConnector, arguments)));

            GC.KeepAlive(invoker);
            GC.KeepAlive(friendlyConnector);
            for (int i = 0; i < arguments.Length; i++)
            {
                if (arguments[i] != null)
                {
                    GC.KeepAlive(arguments[i]);
                }
            }
            if (ret.Exception != null)
            {
                throw new FriendlyOperationException(ret.Exception);
            }
            return(ret.ReturnValue);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// 同期実行。
        /// しかし、Windowsの場合、操作実行は非同期で実行しないと、稀にに操作中にSendMessageが失敗してしまう操作がある。
        /// そのため、非同期操作のプロトコルを使って、実行させ、終了するのを待つ。
        /// </summary>
        /// <param name="info">呼び出し情報。</param>
        /// <param name="receiveWindow">受信ウィンドウ。</param>
        /// <returns>戻り値。</returns>
        private ReturnInfo Operation(ProtocolInfo info, ReceiveAfterSend receiveWindow)
        {
            //完了の成否確認用
            ReturnInfo isComplete = SendForExecuteContext(new ProtocolInfo(ProtocolType.VarInitialize, null, null, string.Empty, string.Empty, new object[] { null }), receiveWindow);

            if (isComplete.Exception != null)
            {
                return(isComplete);
            }

            //引数の先頭に存在確認フラグを挿入
            List <object> arg = new List <object>();

            arg.Add(isComplete.ReturnValue);
            arg.AddRange(info.Arguments);

            //非同期実行
            ReturnInfo retValue = SendForExecuteContext(new ProtocolInfo(ProtocolType.AsyncOperation, info.OperationTypeInfo, info.VarAddress, info.TypeFullName, info.Operation, arg.ToArray()), receiveWindow);

            if (retValue.Exception != null)
            {
                return(retValue);
            }

            //処理が完了するのを待つ
            VarAddress complateCheckHandle = (VarAddress)isComplete.ReturnValue;
            int        sleepTime           = 1;

            while (true)
            {
                //結果の確認は実行対象スレッド以外で実施する。
                //処理が完了するまで、そのスレッドには割り込まない。
                ReturnInfo ret = CopyDataProtocolTalker.SendAndRecieve(_friendlyConnectorWindowInAppHandleAsync,
                                                                       new ProtocolInfo(ProtocolType.IsEmptyVar, null, null, string.Empty, string.Empty, new object[] { complateCheckHandle })
                                                                       , receiveWindow) as ReturnInfo;
                if (ret == null)
                {
                    throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorAppCommunication);
                }
                if (!(bool)ret.ReturnValue)
                {
                    break;
                }
                Thread.Sleep(sleepTime);
                sleepTime++;
                if (100 < sleepTime)
                {
                    sleepTime = 100;
                }
            }

            //結果を取得
            ReturnInfo checkComplate = SendForExecuteContext(new ProtocolInfo(ProtocolType.GetValue, null, complateCheckHandle, string.Empty, string.Empty, new object[0]), receiveWindow);

            if (checkComplate.Exception != null)
            {
                return(checkComplate);
            }
            ReturnInfo checkComplateCore = checkComplate.ReturnValue as ReturnInfo;

            if (checkComplateCore == null)
            {
                throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorAppCommunication);
            }
            if (checkComplateCore.Exception != null)
            {
                return(checkComplateCore);
            }

            //解放
            NativeMethods.SendMessage(_friendlyConnectorWindowInAppHandle, FriendlyConnectorWindowInApp.WM_BINOFF, new IntPtr(complateCheckHandle.Core), IntPtr.Zero);

            //戻り値を返す
            return(retValue);
        }