/// <summary>
        /// メソッド呼び出し処理を実装する
        /// </summary>
        /// <param name="col">スクリプトのルートノード</param>
        /// <param name="isReBuildMode">再構築か?(保存データからの復帰)</param>
        public override bool ImplAsset(MultiRootConnector col, bool isReBuildMode = false)
        {
            DummyArgumentsControl dummyArgumentsControl = new DummyArgumentsControl(col);
            string exTitle = GetGenericArgumentsString(col, isReBuildMode);

            return(ImplAsset(col, dummyArgumentsControl, exTitle));
        }
Beispiel #2
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);
     }
 }
Beispiel #3
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);
     }
 }
Beispiel #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);    // 仮引数後処理
 }
        /// <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);
        }
        /// <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);
        }
        /// <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);
            }
        }
        /// <summary>
        /// メソッド呼び出し処理を実装する
        /// </summary>
        /// <param name="col">スクリプトのルートノード</param>
        /// <param name="dummyArgumentsControl">仮引数管理</param>
        protected bool ImplAsset(
            MultiRootConnector col,
            DummyArgumentsControl dummyArgumentsControl,
            string exTitle)
        {
            Type            classType  = ClassType;
            string          funcTitle  = FuncTitle;
            Func <ICbValue> returnType = ReturnType;

            if (classType.IsGenericType)
            {
                // ジェネリッククラスの型を確定する

                var data = ReturnType().Data;
                if (data is CbGeneMethArg gmaType)
                {
                    List <Type> argTypes = new List <Type>();
                    for (int i = 0; i < typeRequests.Count; ++i)
                    {
                        argTypes.Add(col.SelectedVariableType[i]);
                    }

                    //クラスの型を確定した型で差し替える
                    classType = classType.MakeGenericType(argTypes.ToArray());

                    if (IsConstructor)
                    {
                        returnType = CbST.CbCreateTF(classType);
                        if (funcTitle.Contains("<"))
                        {
                            // 確定した型情報に差し替える

                            funcTitle = funcTitle.Substring(0, funcTitle.IndexOf("<"));
                        }
                    }
                }
                else if (CbSTUtils.HaveGenericParamater(classType))
                {
                    // ユーザー選択ではなく直接 self からコピーされた型の場合は、そのまま内容を登録する

                    List <Type> argTypes = new List <Type>();
                    for (int i = 0; i < typeRequests.Count; ++i)
                    {
                        argTypes.Add(col.SelectedVariableType[i]);
                    }

                    //クラスの型を確定した型で差し替える
                    classType = CbST.GetTypeEx(classType.FullName).MakeGenericType(argTypes.ToArray());
                }
            }

            {// 返し値の型を差し替える
                var methodReturnType = returnType();
                if (methodReturnType.MyType == typeof(CbClass <CbGeneMethArg>))
                {
                    // 未確定なジェネリック型を確定した型で差し替える

                    // 引数の型を差し替える
                    Type repType = GetConfirmedType(col, (CbGeneMethArg)methodReturnType.Data);
                    returnType = CbST.CbCreateTF(repType);
                }
            }

            List <ICbValue> argumentTypeList = new List <ICbValue>();

            if (ArgumentTypeList != null)
            {
                // 引数用の変数を用意する

                foreach (var node in ArgumentTypeList)
                {
                    var argumentType = node.CreateArgument();
                    if (argumentType.MyType == typeof(CbClass <CbGeneMethArg>))
                    {
                        // 未確定なジェネリック型を確定した型で差し替える

                        // 引数の型を差し替える
                        Type replaceArgumentType = GetConfirmedType(col, (CbGeneMethArg)argumentType.Data);
                        argumentType = CbST.CbCreate(replaceArgumentType, argumentType.Name);
                    }
                    argumentTypeList.Add(argumentType);
                }
            }

            col.OldSpecification = oldSpecification;
            col.MakeFunction(
                funcTitle + exTitle,
                NodeHelpText,
                returnType,
                argumentTypeList,
                new Func <List <ICbValue>, DummyArgumentsStack, ICbValue>(
                    (arguments, cagt) =>
            {
                var ret = returnType();
                if (dummyArgumentsControl != null && dummyArgumentsControl.IsInvalid(cagt))
                {
                    return(ret);        // 実行環境が有効でない
                }
                ImplCallMethod(col, classType, dummyArgumentsControl, arguments, cagt, ret);
                return(ret);
            }
                    )
                );

            argumentTypeList.Clear();

            return(true);
        }
Beispiel #9
0
 public DelegateFunction(CbFunc <T, RT> self, DummyArgumentsControl dummyArgumentsControl, DummyArgumentsStack cagt) : base(self, dummyArgumentsControl, cagt)
 {
 }
Beispiel #10
0
 protected DelegateFunctionBase(CbFunc <T, RT> self, DummyArgumentsControl dummyArgumentsControl, DummyArgumentsStack cagt)
 {
     this.self = self;
     this.dummyArgumentsControl = dummyArgumentsControl;
     this.cagt = cagt;
 }