Пример #1
0
 /// <summary>
 /// 可能なら引数付きでコールバックを呼びます。
 /// </summary>
 /// <param name="dummyArgumentsControl">仮引数コントロール</param>
 /// <param name="cagt">仮引数スタック</param>
 /// <param name="func">コールバック変数</param>
 /// <param name="arg">コールバック引数</param>
 protected void TryCallCallBack(DummyArgumentsControl dummyArgumentsControl, DummyArgumentsStack cagt, ICbValue func, object arg)
 {
     if (CanCallBack(func))
     {
         CallCallBack(dummyArgumentsControl, cagt, func, arg);
     }
 }
Пример #2
0
 /// <summary>
 /// 可能ならコールバックを呼びます。
 /// </summary>
 /// <param name="cagt">仮引数スタック</param>
 /// <param name="func">コールバック変数</param>
 protected void TryCallCallBack(DummyArgumentsStack cagt, ICbValue func)
 {
     if (CanCallBack(func))
     {
         CallCallBack(cagt, func);
     }
 }
Пример #3
0
        /// <summary>
        /// コールバックを呼び出します。
        /// </summary>
        /// <param name="variable">変数</param>
        /// <param name="dummyArgumentstack">仮引数スタック</param>
        /// <returns>コールバックの返し値</returns>
        protected ICbValue CallEvent(ICbValue variable, DummyArgumentsStack dummyArgumentstack)
        {
            ICbEvent cbEvent = variable as ICbEvent;

            cbEvent.InvokeCallback(dummyArgumentstack);
            return(cbEvent.Value);
        }
Пример #4
0
 /// <summary>
 /// 引数付きでコールバックを呼びます。
 /// </summary>
 /// <param name="dummyArgumentsControl">仮引数コントロール</param>
 /// <param name="cagt">仮引数スタック</param>
 /// <param name="func">コールバック変数</param>
 /// <param name="arg">コールバック引数</param>
 protected void CallCallBack(DummyArgumentsControl dummyArgumentsControl, DummyArgumentsStack cagt, ICbValue func, object arg)
 {
     if (arg is ICbValue cbValue)
     {
         dummyArgumentsControl.EnableCbValue(cagt, cbValue);    // 仮引数に引数を登録
     }
     else
     {
         dummyArgumentsControl.Enable(cagt, (dynamic)arg);    // 仮引数に引数を登録
     }
     CallEvent(func, cagt);
     dummyArgumentsControl.Invalidated(cagt);    // 仮引数後処理
 }
Пример #5
0
 /// <summary>
 /// コールバックを呼んで返り値を得ます。
 /// </summary>
 /// <typeparam name="R">返り値の型</typeparam>
 /// <param name="dummyArgumentsControl">仮引数コントロール</param>
 /// <param name="cagt">仮引数スタック</param>
 /// <param name="func">コールバック変数</param>
 /// <param name="def">コールバックの返り値を得られなかったときの返り値</param>
 /// <returns>コールバックの返り値</returns>
 protected R GetCallBackResult <R>(DummyArgumentsStack cagt, ICbValue func, R def)
 {
     if (!CanCallBack(func))
     {
         return(def);
     }
     if (typeof(R) == typeof(ICbValue))
     {
         ICbValue result = CallEvent(func, cagt);
         return((R)result);
     }
     else
     {
         R result = (R)CallEvent(func, cagt).Data;
         return(result);
     }
 }
Пример #6
0
        /// <summary>
        /// オリジナル型の値に変換します。
        /// </summary>
        /// <param name="value"></param>
        /// <param name="col"></param>
        /// <param name="dummyArgumentsControl"></param>
        /// <param name="dummyArgumentsStack"></param>
        /// <returns></returns>
        private object getBindObject(
            ICbValue value,
            MultiRootConnector col,
            DummyArgumentsControl dummyArgumentsControl,
            DummyArgumentsStack dummyArgumentsStack
            )
        {
            if (value.IsList)
            {
                ICbList cbList = value.GetListValue;

                // リストは、オリジナルの型のインスタンスを用意する

                if (dummyArgumentsControl is null)
                {
                    return(cbList.ConvertOriginalTypeList(col, dummyArgumentsStack));
                }
                else
                {
                    return(cbList.ConvertOriginalTypeList(dummyArgumentsControl, dummyArgumentsStack));
                }
            }
            else if (dummyArgumentsControl != null && value is ICbEvent cbEvent)
            {
                // Func<> 及び Action<> は、オリジナルの型のインスタンスを用意する

                if (cbEvent.Callback is null)
                {
                    return(null);
                }
                else
                {
                    Debug.Assert(dummyArgumentsControl != null);
                    return(cbEvent.GetCallbackOriginalType(dummyArgumentsControl, dummyArgumentsStack));
                }
            }
            if (value.IsNull)
            {
                return(null);
            }
            return(value.Data);
        }
Пример #7
0
        /// <summary>
        /// 引数をメソッドに合わせて調整しリストアップします。
        /// </summary>
        /// <param name="col">スクリプトのルートノード</param>
        /// <param name="dummyArgumentsControl">仮引数管理オブジェクト</param>
        /// <param name="callArguments">引数リスト</param>
        /// <param name="dummyArgumentsStack">仮引数スタック</param>
        /// <param name="variableIds">スクリプト変数IDリスト</param>
        /// <param name="isClassInstanceMethod">インスタンスメソッドか?</param>
        /// <param name="methodArguments">メソッド呼び出し引数リスト</param>
        /// <returns>メソッド呼び出し引数リスト</returns>
        private List <object> SetArguments(
            MultiRootConnector col,
            DummyArgumentsControl dummyArgumentsControl,
            List <ICbValue> callArguments,
            DummyArgumentsStack dummyArgumentsStack,
            bool isClassInstanceMethod,
            List <object> methodArguments
            )
        {
            int argumentIndex = 0;

            if (callArguments.Count > 0)
            {
                methodArguments ??= new List <object>();
            }

            bool isTaskRequest = callArguments.Count(n => n.IsList || n is ICbEvent) > 2;   // タスクで処理する条件

            if (isTaskRequest)
            {
                // タスクを使った処理

                List <Task <object> > tasks = new List <Task <object> >();
                for (int i = 0; i < callArguments.Count; ++i)
                {
                    var node = callArguments[argumentIndex++];
                    CheckArgument(node);

                    if (i == 0 && isClassInstanceMethod)
                    {
                        // クラスメソッドの第一引数は、self(this)を受け取るのでメソッド呼び出しの引数にしない

                        continue;
                    }

                    tasks.Add(Task.Run(() =>
                    {
                        return(getBindObject(node, col, dummyArgumentsControl, dummyArgumentsStack));
                    }));
                }
                foreach (var task in tasks)
                {
                    methodArguments.Add(task.Result);
                }
            }
            else
            {
                // 通常処理

                for (int i = 0; i < callArguments.Count; ++i)
                {
                    var node = callArguments[argumentIndex++];
                    CheckArgument(node);

                    if (i == 0 && isClassInstanceMethod)
                    {
                        // クラスメソッドの第一引数は、self(this)を受け取るのでメソッド呼び出しの引数にしない

                        continue;
                    }

                    methodArguments.Add(getBindObject(node, col, dummyArgumentsControl, dummyArgumentsStack));
                }
            }

            return(methodArguments);
        }
Пример #8
0
        /// <summary>
        /// メソッド呼び出しの実装です。
        /// </summary>
        /// <param name="col">スクリプトのルートノード</param>
        /// <param name="dummyArgumentsControl">仮引数管理オブジェクト</param>
        /// <param name="callArguments">引数リスト</param>
        /// <param name="dummyArgumentsStack">仮引数スタック</param>
        /// <param name="returnValue">返り値</param>
        private void ImplCallMethod(
            MultiRootConnector col,
            Type classType,
            DummyArgumentsControl dummyArgumentsControl,
            List <ICbValue> callArguments,
            DummyArgumentsStack dummyArgumentsStack,
            ICbValue returnValue
            )
        {
            try
            {
                bool          isClassInstanceMethod = ArgumentTypeList != null && ArgumentTypeList[0].IsSelf && !IsConstructor;
                List <object> methodArguments       = null;

                methodArguments = SetArguments(
                    col,
                    dummyArgumentsControl,
                    callArguments,
                    dummyArgumentsStack,
                    isClassInstanceMethod,
                    methodArguments
                    );

                object classInstance = null;
                if (isClassInstanceMethod)
                {
                    // クラスメソッドの第一引数は、self(this)を受け取るのでクラスインスタンスとして扱う

                    classInstance = getBindObject(callArguments[0], col, dummyArgumentsControl, dummyArgumentsStack);
                    if (classInstance is null)
                    {
                        throw new Exception($"self(this) is invalid.");
                    }
                    // 返却方法が入っていないならセットしておく
                    var cbVSValue = callArguments[0];
                    if (!cbVSValue.IsDelegate && !cbVSValue.IsLiteral && cbVSValue.ReturnAction is null)
                    {
                        if (cbVSValue.IsList)
                        {
                            ICbList cbList = cbVSValue.GetListValue;
                            cbVSValue.ReturnAction = (value) =>
                            {
                                cbList.CopyFrom(value);
                            };
                        }
                        else if (!(cbVSValue is ICbClass))
                        {
                            cbVSValue.ReturnAction = (value) =>
                            {
                                cbVSValue.Data = value;
                            };
                        }
                    }
                }

                object result = CallMethod(
                    classInstance,
                    col,
                    classType,
                    callArguments,
                    isClassInstanceMethod,
                    methodArguments);

                ProcReturnValue(col, returnValue, result);
            }
            catch (Exception ex)
            {
                col.ExceptionFunc(returnValue, ex);
            }
        }
Пример #9
0
 /// <summary>
 /// 引数付きでコールバックを呼んで返り値を得ます。
 /// </summary>
 /// <typeparam name="R">返り値の型</typeparam>
 /// <param name="dummyArgumentsControl">仮引数コントロール</param>
 /// <param name="cagt">仮引数スタック</param>
 /// <param name="func">コールバック変数</param>
 /// <param name="arg">コールバック引数</param>
 /// <param name="def">コールバックの返り値を得られなかったときの返り値</param>
 /// <returns>コールバックの返り値</returns>
 protected R GetCallBackResult <R>(DummyArgumentsControl dummyArgumentsControl, DummyArgumentsStack cagt, ICbValue func, object arg, R def)
 {
     if (!CanCallBack(func))
     {
         return(def);
     }
     if (arg is ICbValue cbValue)
     {
         dummyArgumentsControl.EnableCbValue(cagt, cbValue);    // 仮引数に引数を登録
     }
     else
     {
         dummyArgumentsControl.Enable(cagt, (dynamic)arg);    // 仮引数に引数を登録
     }
     if (typeof(R) == typeof(ICbValue))
     {
         ICbValue result = CallEvent(func, cagt);
         dummyArgumentsControl.Invalidated(cagt);    // 仮引数後処理
         return((R)result);
     }
     else
     {
         R result = (R)CallEvent(func, cagt).Data;
         dummyArgumentsControl.Invalidated(cagt);    // 仮引数後処理
         return(result);
     }
 }
Пример #10
0
 /// <summary>
 /// コールバックを呼びます。
 /// </summary>
 /// <param name="cagt">仮引数スタック</param>
 /// <param name="func">コールバック変数</param>
 protected void CallCallBack(DummyArgumentsStack cagt, ICbValue func)
 {
     CallEvent(func, cagt);
 }