/// <summary>キーと値のペアを用いてマップ型変数を生成します。</summary> /// <param name="values">キーと値のペア</param> /// <returns>入力データに対応するマップ型変数</returns> public static QiMap <K, V> Create(IEnumerable <KeyValuePair <K, V> > values) { if (!values.Any()) { throw new InvalidOperationException("values length must be greater than 0"); } //中身のシグネチャ揃ってるかどうか検証 var pf = values.First(); var ksig = pf.Key.Signature; var vsig = pf.Value.Signature; if (values.Any(pair => (pair.Key.Signature != ksig || pair.Value.Signature != vsig))) { throw new InvalidOperationException("key or values type is inconsistent"); } string sig = QiSignatures.TypeMapBegin + ksig + vsig + QiSignatures.TypeMapEnd; var map = QiValue.Create(sig); foreach (var pair in values) { map[pair.Key.QiValue] = pair.Value.QiValue; } return(new QiMap <K, V>(map, sig)); }
/// <summary> /// 列挙された<see cref="QiAnyValue"/>派生型から、それに対応したリストを生成します。 /// </summary> /// <param name="values">何かしらの値の列挙</param> /// <returns></returns> public static QiList <T> Create(IEnumerable <T> values) { if (!values.Any()) { throw new InvalidOperationException("values length must be greater than 0"); } //リストは中身のシグネチャ揃ってないとアウト(ダイナミックリストの場合は例外) string elemSig = values.First().Signature; if (values.Any(v => v.Signature != elemSig)) { throw new InvalidOperationException("values kind is not same"); } string sig = QiSignatures.TypeListBegin + elemSig + QiSignatures.TypeListEnd; var list = QiValue.Create(sig); foreach (var v in values) { list.AddElement(v.QiValue); } return(new QiList <T>(list, sig)); }
/// <summary> /// リストに要素を追加します。 /// </summary> /// <param name="value">追加する値</param> /// <returns></returns> public bool AddElement(QiValue value) { if (ValueKind != QiValueKind.QiList) { throw new InvalidOperationException("this QiValue is not QiList"); } return(QiApiValue.AddList(this, value)); }
public QiMethod(QiObjectMethod method) { ManagedMethod = method; UnmanagedMethod = (sig, args, ret, _) => { var result = ManagedMethod(sig, new QiValue(args)); var retValue = new QiValue(ret); //すり替え処理によって計算結果を渡したい //(というかC言語APIだと他に良い手が無さそうに見える) QiValue.Swap(retValue, result); }; }
/// <summary> /// 全ての要素が<see cref="QiDynamic"/>であるようなタプルを生成します。 /// このようなタプルは<see cref="QiMethod.Call"/>の引数として渡す処理に適しています。 /// </summary> /// <param name="values">タプルの要素</param> /// <returns>生成されたタプル</returns> public static QiTuple CreateDynamic(params QiAnyValue[] values) { string sig = QiSignatures.TypeTupleBegin + new string(QiSignatures.TypeDynamic[0], values.Length) + QiSignatures.TypeTupleEnd; var tuple = QiValue.Create(sig); for (int i = 0; i < values.Length; i++) { tuple[i] = values[i].QiValue; } return(new QiTuple(tuple, sig)); }
internal QiMethodInfo(QiValue mInfo) { UID = mInfo[0].ToInt64(); ReturnValueSignature = mInfo[1].ToString(); Name = mInfo[2].ToString(); ArgumentSignature = mInfo[3].ToString(); Description = mInfo[4].ToString(); ArgumentsInfo = new ReadOnlyList <QiMethodArgumentInfo>( Enumerable.Range(0, mInfo[5].Count) .Select(i => new QiMethodArgumentInfo(mInfo[5][i])) .ToList()); ReturnValueDescription = mInfo[6].ToString(); }
internal QiMethodInfo(QiValue mInfo) { UID = mInfo[0].ToInt64(); ReturnValueSignature = mInfo[1].ToString(); Name = mInfo[2].ToString(); ArgumentSignature = mInfo[3].ToString(); Description = mInfo[4].ToString(); ArgumentsInfo = new ReadOnlyList<QiMethodArgumentInfo>( Enumerable.Range(0, mInfo[5].Count) .Select(i => new QiMethodArgumentInfo(mInfo[5][i])) .ToList()); ReturnValueDescription = mInfo[6].ToString(); }
/// <summary> /// 列挙された<see cref="QiAnyValue"/>派生型を要素として含む、動的型の内容からなるリストを生成します。 /// </summary> /// <param name="values">何かしらの値の列挙</param> /// <returns>指定した値を保持する動的型のリスト</returns> public static QiList <QiDynamic> CreateDynamic(IEnumerable <QiAnyValue> values) { if (!values.Any()) { throw new InvalidOperationException("values length must be greater than 0"); } string sig = QiSignatures.TypeListBegin + QiSignatures.TypeDynamic + QiSignatures.TypeListEnd; var list = QiValue.Create(sig); foreach (var v in values) { list.AddElement(v.QiValue); } return(new QiList <QiDynamic>(list, sig)); }
/// <summary> /// 連想配列にキー要素でアクセスします。キーが連想配列に含まれるかどうかはチェックされません。 /// </summary> /// <param name="key"></param> /// <returns></returns> public QiValue this[QiValue key] { get { if (ContentValueKind != QiValueKind.QiMap) { throw new InvalidOperationException("This QiValue is not QiMap"); } return(QiApiValue.GetMap(NonDynamicValue, key)); } set { if (ContentValueKind != QiValueKind.QiMap) { throw new InvalidOperationException("This QiValue is not QiMap"); } QiApiValue.SetMap(NonDynamicValue, key, value); } }
/// <summary>内容として用いる値を指定してタプルを生成します。</summary> /// <param name="values">タプルに含む値</param> /// <returns>指定した値を順に格納したタプル</returns> public static QiTuple Create(params QiAnyValue[] values) { string sig = QiSignatures.TypeTupleBegin + string.Join("", values.Select(v => v.Signature).ToArray()) + QiSignatures.TypeTupleEnd; var tuple = QiValue.Create(sig); for (int i = 0; i < values.Length; i++) { //Dynamicはそのまま渡すと想定外の入れ子構造を取るので中身を渡す if (values[i].Signature == QiSignatures.TypeDynamic) { tuple[i] = (values[i] as QiDynamic).Value; } else { tuple[i] = values[i].QiValue; } } return(new QiTuple(tuple, sig)); }
/// <summary> /// リストに要素を追加します。 /// </summary> /// <param name="value">追加する値</param> /// <returns></returns> public bool AddElement(QiValue value) { if (ValueKind != QiValueKind.QiList) { throw new InvalidOperationException("this QiValue is not QiList"); } return QiApiValue.AddList(this, value); }
/// <summary> /// 格納する値を指定してインスタンスを初期化します。 /// </summary> /// <param name="value">格納する値</param> public QiUInt64(ulong value) { QiValue = QiValue.Create(QiSignatures.TypeUInt64); QiValue.SetValue(value); }
/// <summary>この変数が動的型であると想定し、値を設定します。</summary> /// <param name="v">設定する値</param> /// <returns>設定に成功した場合はtrue</returns> public bool SetValue(QiValue v) => QiApiValue.SetDynamic(this, v);
private QiTuple(QiValue value, string sig) { QiValue = value; Signature = sig; }
/// <summary> /// 指定した2つの値を入れ替えます。 /// </summary> /// <param name="v1"></param> /// <param name="v2"></param> public static void Swap(QiValue v1, QiValue v2) => QiApiValue.Swap(v1, v2);
/// <summary>(動作未確認)オブジェクトのプロパティに値を設定します。</summary> /// <param name="pname">プロパティ名</param> /// <param name="v">プロパティへ代入する値</param> /// <returns>代入結果への予約</returns> public QiFuture SetProperty(string pname, QiValue v) => QiApiObject.SetProperty(this, pname, v);
/// <summary> /// 格納する値を指定してインスタンスを初期化します。 /// </summary> /// <param name="value">格納する値</param> public QiBool(bool value) { QiValue = QiValue.Create(QiSignatures.TypeBool); QiValue.SetValue(Convert.ToInt64(value)); }
/// <summary> /// 値を設定します。 /// </summary> /// <param name="value">設定する値</param> public void SetValue(QiValue value) => QiApiPromise.SetValue(this, value);
/// <summary>値の情報をデバッグ用文字列として取得します。</summary> /// <returns>値をあらわすデバッグ用の文字列</returns> public string Dump() => QiValue.Dump();
/// <summary> /// 格納する値を指定してインスタンスを初期化します。 /// </summary> /// <param name="value">格納する値</param> public QiInt16(short value) { QiValue = QiValue.Create(QiSignatures.TypeInt16); QiValue.SetValue(value); }
/// <summary> /// 格納する値を指定してインスタンスを初期化します。 /// </summary> /// <param name="value">格納する値</param> public QiInt8(sbyte value) { QiValue = QiValue.Create(QiSignatures.TypeInt8); QiValue.SetValue(value); }
/// <summary> /// 連想配列にキー要素でアクセスします。キーが連想配列に含まれるかどうかはチェックされません。 /// </summary> /// <param name="key"></param> /// <returns></returns> public QiValue this[QiValue key] { get { if (ContentValueKind != QiValueKind.QiMap) { throw new InvalidOperationException("This QiValue is not QiMap"); } return QiApiValue.GetMap(NonDynamicValue, key); } set { if (ContentValueKind != QiValueKind.QiMap) { throw new InvalidOperationException("This QiValue is not QiMap"); } QiApiValue.SetMap(NonDynamicValue, key, value); } }
/// <summary> /// 自力でシグネチャを正しく定義してタプルを渡し、関数を非同期で呼び出します。 /// デバッグ目的で公開されており、普通は<see cref="this[string]"/>で選択した<see cref="QiMethod"/>で /// <see cref="QiMethod.Post(QiAnyValue[])"/>を使用してください。 /// </summary> /// <param name="signature">関数名と引数タプルの合わさった文字列("ping::()"など)</param> /// <param name="argsTuple">引数の入ってるタプル</param> /// <returns>非同期呼び出しの状態確認を行うために使われるID</returns> public int PostDirect(string signature, QiValue argsTuple) => QiApiObject.Post(this, signature, argsTuple);
/// <summary> /// 値のコピーを生成します。 /// </summary> /// <param name="src">生成元の値</param> /// <returns>コピーされた値</returns> public static QiValue GetCopy(QiValue src) => QiApiValue.Copy(src);
private QiList(QiValue value, string sig) { QiValue = value; Signature = sig; }
/// <summary> /// 自力でシグネチャを正しく定義してタプルを渡し、関数を呼び出します。 /// ラッパーの動作不良に備えて公開されており、通常は<see cref="this[string]"/>で選択したメソッドを用いてください。 /// </summary> /// <param name="signature">関数名と引数タプルの合わさった文字列("ping::()"など)</param> /// <param name="argsTuple">引数の入ってるタプル</param> /// <returns>戻り値の非同期取得に使えるfuture型</returns> public QiFuture CallDirect(string signature, QiValue argsTuple) => QiApiObject.Call(this, signature, argsTuple);
/// <summary> /// 格納する値を指定してインスタンスを初期化します。 /// </summary> /// <param name="value">格納する値</param> public QiUInt32(uint value) { QiValue = QiValue.Create(QiSignatures.TypeUInt32); QiValue.SetValue(value); }