static private RSQueryInfo ValidateQueryId(EntityScopedIdentifier inIdentifier, RSTypeInfo inExpectedType, RSValidationFlags inFlags, RSValidationState ioState, RSValidationContext inContext) { bool bNoParams = inFlags.Has(RSValidationFlags.DisallowParameters); ValidateEntityScope(inIdentifier.Scope, inFlags.ForMethodScope(), ioState, inContext); if (inIdentifier.Id == 0) { ioState.Error("Null query not allowed"); return(null); } else { RSQueryInfo queryInfo = inContext.Library.GetQuery(inIdentifier.Id); if (queryInfo == null) { ioState.Error("Query {0} does not exist", inIdentifier.Id); } else { if (inExpectedType != null && !queryInfo.ReturnType.CanConvert(inExpectedType)) { ioState.Error("Query {0} returns incompatible type {1}, which cannot convert to desired type {2}", queryInfo.Name, queryInfo.ReturnType, inExpectedType); } if (bNoParams && queryInfo.Parameters != null && queryInfo.Parameters.Length > 0) { ioState.Error("Query {0} has parameters, which is not allowed in this context", queryInfo.Name); } switch (inIdentifier.Scope.Type) { case EntityScopeType.Global: { if (queryInfo.OwnerType != null) { ioState.Error("Query {0} is bound to type {1} but was specified as a global query", queryInfo.Name, queryInfo.OwnerType.Name); } break; } case EntityScopeType.Null: case EntityScopeType.Invalid: break; default: { if (queryInfo.OwnerType == null) { ioState.Error("Query {0} is bound to global scope but was specified as a local query", queryInfo.Name); } break; } } } return(queryInfo); } }
public string GetPreviewString(RSTriggerInfo inTriggerContext, RSLibrary inLibrary) { switch (Mode) { case ResolvableValueMode.Value: return(Value.GetPreviewString(inTriggerContext, inLibrary)); case ResolvableValueMode.Argument: return(string.Format("Arg({0})", inTriggerContext?.ParameterType?.Name ?? "TriggerArg")); case ResolvableValueMode.Query: { using (PooledStringBuilder psb = PooledStringBuilder.Alloc()) { var sb = psb.Builder; sb.Append(Query.GetPreviewStringAsQuery(inTriggerContext, inLibrary)); if (QueryArguments != null && QueryArguments.Length > 0) { sb.Append("("); RSQueryInfo queryInfo = inLibrary.GetQuery(Query.Id); for (int i = 0; i < QueryArguments.Length; ++i) { if (i > 0) { sb.Append("; "); } if (queryInfo != null && i < queryInfo.Parameters.Length) { sb.Append(queryInfo.Parameters[i].Name); } else { sb.Append(i); } sb.Append(": "); sb.Append(QueryArguments[i].GetPreviewString(inTriggerContext, inLibrary)); } sb.Append(")"); } return(sb.ToString()); } } case ResolvableValueMode.Register: return(string.Format("Register({0})", Register)); default: return("[No Value]"); } }
/// <summary> /// Evaluates a query with static scope. /// </summary> public RSValue EvaluateQuery(IRSRuntimeEntity inEntity, string inQueryId, params object[] inArgs) { RSQueryInfo queryInfo = Library.GetQuery(inQueryId); ExecutionScope scope = CreateScope(inEntity, RSValue.Null, TableUtils.GetRuleFlags(queryInfo.Flags)); using (new SharedRef <ExecutionScope>(scope)) { return(EvaluateQuery(inEntity, queryInfo, InternalScriptUtils.Convert(inArgs), scope)); } }
static private RuleFlags GetRuleFlags(RSQueryInfo inInfo) { RuleFlags flags = 0; if (inInfo != null) { flags |= GetRuleFlags(inInfo.Flags); } return(flags); }
/// <summary> /// Evaluates a query with static scope. /// </summary> public RSValue EvaluateQuery(string inQueryId, params object[] inArgs) { RSQueryInfo queryInfo = Library.GetQuery(inQueryId); ExecutionScope scope = m_StaticScope; CloneScopeIfNecessary(scope, TableUtils.GetRuleFlags(queryInfo.Flags), out scope); using (new SharedRef <ExecutionScope>(scope)) { return(EvaluateQuery(null, queryInfo, InternalScriptUtils.Convert(inArgs), scope)); } }
/// <summary> /// Resolves a query to a set of values. /// </summary> public MultiReturn <RSValue> EvaluateQuery(EntityScopedIdentifier inQuery, NestedValue[] inArguments) { RSQueryInfo queryInfo = m_Environment.Library.GetQuery(inQuery.Id); MultiReturn <IRSRuntimeEntity> targets = ResolveEntity(inQuery.Scope); ResolveArgsArray(inArguments, queryInfo.TempArgStorage); if (targets.Set != null) { return(new MultiReturn <RSValue>(m_Environment.EvaluateQueries(targets.Set, queryInfo, queryInfo.TempArgStorage, this))); } return(new MultiReturn <RSValue>(m_Environment.EvaluateQuery(targets.Single, queryInfo, queryInfo.TempArgStorage, this))); }
static private void DoResolvableValueData(UndoTarget inUndo, GUIContent inLabel, RSResolvableValueData ioValue, RSTypeInfo inExpectedType, RSValue inDefaultValue, RSValidationFlags inFlags, RSValidationContext inContext) { EditorGUILayout.BeginVertical(); bool bDisallowDirectValue = (inExpectedType == null || inExpectedType == RSBuiltInTypes.Any || inFlags.Has(RSValidationFlags.DisallowDirectValue)); ResolvableValueMode nextMode = ListGUILayout.Popup(inLabel, ioValue.Mode, RSEditorUtility.GetResolvableValueModes(inExpectedType, inFlags, inContext)); if (nextMode != ioValue.Mode) { inUndo.MarkDirty("Changed Resolvable Value Mode"); ioValue.Mode = nextMode; switch (nextMode) { case ResolvableValueMode.Argument: RSResolvableValueData.SetAsArgument(ref ioValue); break; case ResolvableValueMode.Query: RSResolvableValueData.SetAsQuery(ref ioValue, new EntityScopedIdentifier(EntityScopeData.Self(), 0)); break; case ResolvableValueMode.Value: RSResolvableValueData.SetAsValue(ref ioValue, inDefaultValue); break; case ResolvableValueMode.Register: RSResolvableValueData.SetAsRegister(ref ioValue, RegisterIndex.Register0); break; } } using (new EditorGUI.IndentLevelScope()) { switch (ioValue.Mode) { case ResolvableValueMode.Argument: { if (inContext.Trigger == null) { EditorGUILayout.HelpBox("No parameter available: No Trigger", MessageType.Error); } else if (inContext.Trigger.ParameterType == null) { EditorGUILayout.HelpBox(string.Format("No parameter available - Trigger {0} has no parameter", inContext.Trigger.Name), MessageType.Error); } else if (inExpectedType != null && !inContext.Trigger.ParameterType.Type.CanConvert(inExpectedType)) { EditorGUILayout.HelpBox(string.Format("No parameter available - Trigger {0} has incompatible parameter type {1}, which cannot convert to {2}", inContext.Trigger.Name, inContext.Trigger.ParameterType.Type, inExpectedType), MessageType.Error); } break; } case ResolvableValueMode.Value: { if (bDisallowDirectValue) { EditorGUILayout.HelpBox("Cannot specify a value in this context", MessageType.Error); } else { RSValue nextValue = ValueGUILayout.RSValueField(EditorGUIUtility.TrTempContent(inExpectedType.FriendlyName), ioValue.Value, inExpectedType, inFlags, inContext); if (nextValue != ioValue.Value) { inUndo.MarkDirty("Changed Resolvable Value Value"); ioValue.Value = nextValue; } } break; } case ResolvableValueMode.Register: { RegisterIndex nextRegister = (RegisterIndex)EnumGUILayout.EnumField(Content.ResolvableValueRegisterLabel, ioValue.Register); if (nextRegister != ioValue.Register) { inUndo.MarkDirty("Changed Resolvable Value Register"); ioValue.Register = nextRegister; } break; } case ResolvableValueMode.Query: { EntityScopedIdentifier query = ValueGUILayout.QueryField(Content.ResolvableValueQueryLabel, ioValue.Query, inExpectedType, inFlags.ForMethod(true), inContext); RSQueryInfo queryInfo = inContext.Library.GetQuery(query.Id); if (query != ioValue.Query) { bool bChangedId = query.Id != ioValue.Query.Id; inUndo.MarkDirty("Changed Resolvable Value Query", true); ioValue.Query = query; if (bChangedId) { if (queryInfo == null) { ioValue.QueryArguments = null; } else { queryInfo.PopulateDefaultArguments(ioValue); } } } int currentArgsLength = 0; if (ioValue.QueryArguments != null) { currentArgsLength = ioValue.QueryArguments.Length; } int desiredArgsLength = 0; if (queryInfo != null && queryInfo.Parameters != null) { desiredArgsLength = queryInfo.Parameters.Length; } if (desiredArgsLength == 0 && ioValue.QueryArguments != null) { inUndo.MarkDirtyWithoutUndo("Resizing Arguments", true); ioValue.QueryArguments = null; } else if (desiredArgsLength > 0 && currentArgsLength != desiredArgsLength) { inUndo.MarkDirtyWithoutUndo("Resizing Arguments", true); queryInfo.PopulateDefaultArguments(ioValue, currentArgsLength); } if (ioValue.QueryArguments != null && ioValue.QueryArguments.Length > 0) { using (new EditorGUI.IndentLevelScope()) { EditorGUILayout.Space(); EditorGUILayout.LabelField(Content.ResolvableValueQueryArgsLabel, RSGUIStyles.SubHeaderStyle); for (int i = 0; i < ioValue.QueryArguments.Length && i < queryInfo.Parameters.Length; ++i) { NestedValue nextValue = ValueGUILayout.NestedParameterField(queryInfo.Parameters[i], ioValue.QueryArguments[i], inFlags, inContext); if (nextValue != ioValue.QueryArguments[i]) { inUndo.MarkDirty("Changed Resolvable Value Query Argument"); ioValue.QueryArguments[i] = nextValue; } } } } break; } } } EditorGUILayout.EndVertical(); }
static private void ValidateResolvableValue(RSResolvableValueData inValue, RSTypeInfo inExpectedType, RSValidationFlags inFlags, RSValidationState ioState, RSValidationContext inContext) { bool bDisallowDirectValue = (inExpectedType == null || inExpectedType == RSBuiltInTypes.Any || inFlags.Has(RSValidationFlags.DisallowDirectValue)); switch (inValue.Mode) { case ResolvableValueMode.Argument: { ValidateTriggerArgument(inExpectedType, inFlags, ioState, inContext); break; } case ResolvableValueMode.Value: { if (bDisallowDirectValue) { ioState.Error("Cannot specify a direct value in this context"); } else { ValidateValue(inValue.Value, inExpectedType, inFlags, ioState, inContext); } break; } case ResolvableValueMode.Register: { if (inFlags.Has(RSValidationFlags.DisallowRegisters)) { ioState.Error("Cannot use a register in this context"); } break; } case ResolvableValueMode.Query: { ioState.PushContext("Query Id"); RSQueryInfo queryInfo = ValidateQueryId(inValue.Query, inExpectedType, inFlags.ForMethod(true), ioState, inContext); ioState.PopContext(); ioState.PushContext("Arguments"); if (queryInfo != null) { int argCount = queryInfo.Parameters.Length; if (argCount <= 0) { if (inValue.QueryArguments != null && inValue.QueryArguments.Length > 0) { ioState.Error("Arguments provided for action {0} but none required", queryInfo.Name); } } else { if (inValue.QueryArguments == null) { ioState.Error("No arguments provided for action {0} but {1} required", queryInfo.Name, argCount); } else if (inValue.QueryArguments.Length != argCount) { ioState.Error("Argument count mismatch for action {0} - {1} required but {2} provided", queryInfo.Name, argCount, inValue.QueryArguments.Length); } else { for (int i = 0; i < argCount; ++i) { ValidateNestedParameter(queryInfo.Parameters[i], inValue.QueryArguments[i], ioState, inContext); } } } } ioState.PopContext(); break; } } }
internal IEnumerable <RSValue> EvaluateQueries(IEnumerable <IRSRuntimeEntity> inEntities, RSQueryInfo inQuery, RSValue[] inArguments, ExecutionScope inContext) { inQuery.PrepArguments(inArguments, inContext); foreach (var entity in inEntities) { yield return(inQuery.InvokeWithCachedArgs(entity, inContext)); } }
internal RSValue EvaluateQuery(IRSRuntimeEntity inEntity, RSQueryInfo inQuery, RSValue[] inArgs, ExecutionScope inContext) { return(inQuery.Invoke(inEntity, inArgs, inContext)); }