public static bool HasCompatibleValueOutput(this IUnitOption option, Type inputType) { Ensure.That(nameof(inputType)).IsNotNull(inputType); foreach (var valueOutputType in option.valueOutputTypes) { if (ConversionUtility.CanConvert(valueOutputType, inputType, false)) { return(true); } } return(false); }
private void _Run(object assigner, object assignee) { var oldValue = this.assignee.Get(assignee); var newValue = ConversionUtility.Convert(this.assigner.Invoke(assigner), this.assignee.type); this.assignee.Set(assignee, newValue); if (!Equals(oldValue, newValue)) { if (assigner is IAssigner _assigner) { _assigner.ValueChanged(); } } }
private bool CanPredict(ValueInput input) { if (!input.hasValidConnection) { if (!TryGetDefaultValue(input, out var defaultValue)) { return(false); } if (typeof(Component).IsAssignableFrom(input.type)) { defaultValue = defaultValue?.ConvertTo(input.type); } if (!input.allowsNull && defaultValue == null) { return(false); } return(true); } var output = input.validConnectedPorts.Single(); if (!CanPredict(output)) { return(false); } var connectedValue = GetValue(output); if (!ConversionUtility.CanConvert(connectedValue, input.type, false)) { return(false); } if (typeof(Component).IsAssignableFrom(input.type)) { connectedValue = connectedValue?.ConvertTo(input.type); } if (!input.allowsNull && connectedValue == null) { return(false); } return(true); }
private void EnforceType() { if (metadata.value?.GetType() == type) { return; } metadata.UnlinkChildren(); if (type == null) { metadata.value = null; } else if (ConversionUtility.CanConvert(metadata.value, type, true)) { metadata.value = ConversionUtility.Convert(metadata.value, type); } else { metadata.value = type.TryInstantiate(); } metadata.InferOwnerFromParent(); }
public static object GetValue(this IGettable gettable, Type type) { return(ConversionUtility.Convert(gettable.GetValue(), type)); }
private IEnumerable <Warning> ValueInputWarnings(ValueInput valueInput) { // We can disable null reference check if no self is available // and the port requires an owner, for example in macros. var trustFutureOwner = valueInput.nullMeansSelf && reference.self == null; var checkForNullReference = BoltFlow.Configuration.predictPotentialNullReferences && !valueInput.allowsNull && !trustFutureOwner; var checkForMissingComponent = BoltFlow.Configuration.predictPotentialMissingComponents && typeof(Component).IsAssignableFrom(valueInput.type); // Note that we cannot directly check the input's predicted value, because it // will return false for safeguard specifically because it might be missing requirements. // Therefore, we first check the connected value, then the default value. // If the port is connected to a predictable output, use the connected value to perform checks. if (valueInput.hasValidConnection) { var valueOutput = valueInput.validConnectedPorts.Single(); if (Flow.CanPredict(valueOutput, reference)) { if (checkForNullReference) { if (Flow.Predict(valueOutput, reference) == null) { yield return(Warning.Severe($"{PortLabel(valueInput)} cannot be null.")); } } if (checkForMissingComponent) { var connectedPredictedValue = Flow.Predict(valueOutput, reference); // This check is necessary, because the predicted value could be // incompatible as connections with non-guaranteed conversions are allowed. if (ConversionUtility.CanConvert(connectedPredictedValue, typeof(GameObject), true)) { var gameObject = ConversionUtility.Convert <GameObject>(connectedPredictedValue); if (gameObject != null) { var component = (Component)ConversionUtility.Convert(gameObject, valueInput.type); if (component == null) { yield return(Warning.Caution($"{PortLabel(valueInput)} is missing a {valueInput.type.DisplayName()} component.")); } } } } } } // If the port isn't connected but has a default value, use the default value to perform checks. else if (valueInput.hasDefaultValue) { if (checkForNullReference) { if (Flow.Predict(valueInput, reference) == null) { yield return(Warning.Severe($"{PortLabel(valueInput)} cannot be null.")); } } if (checkForMissingComponent) { var unconnectedPredictedValue = Flow.Predict(valueInput, reference); if (ConversionUtility.CanConvert(unconnectedPredictedValue, typeof(GameObject), true)) { var gameObject = ConversionUtility.Convert <GameObject>(unconnectedPredictedValue); if (gameObject != null) { var component = (Component)ConversionUtility.Convert(gameObject, valueInput.type); if (component == null) { yield return(Warning.Caution($"{PortLabel(valueInput)} is missing a {valueInput.type.DisplayName()} component.")); } } } } } // The value isn't connected and has no default value, // therefore it is certain to be missing at runtime. else { yield return(Warning.Severe($"{PortLabel(valueInput)} is missing.")); } }
public static object Predict(IUnitValuePort port, GraphReference reference, Type type) { return(ConversionUtility.Convert(Predict(port, reference), type)); }
public static object FetchValue(ValueInput input, Type type, GraphReference reference) { return(ConversionUtility.Convert(FetchValue(input, reference), type)); }
public object GetValue(ValueInput input, Type type) { return(ConversionUtility.Convert(GetValue(input), type)); }
public virtual object Operate(object leftOperand, object rightOperand) { OperatorQuery query; var leftType = leftOperand?.GetType(); var rightType = rightOperand?.GetType(); if (leftType != null && rightType != null) { query = new OperatorQuery(leftType, rightType); } else if (leftType != null && leftType.IsNullable()) { query = new OperatorQuery(leftType, leftType); } else if (rightType != null && rightType.IsNullable()) { query = new OperatorQuery(rightType, rightType); } else if (leftType == null && rightType == null) { return(BothNullHandling()); } else { return(SingleNullHandling()); } if (handlers.ContainsKey(query)) { return(handlers[query](leftOperand, rightOperand)); } if (customMethodName != null) { if (!userDefinedOperators.ContainsKey(query)) { var leftMethod = query.leftType.GetMethod(customMethodName, BindingFlags.Public | BindingFlags.Static, null, new[] { query.leftType, query.rightType }, null); if (query.leftType != query.rightType) { var rightMethod = query.rightType.GetMethod(customMethodName, BindingFlags.Public | BindingFlags.Static, null, new[] { query.leftType, query.rightType }, null); if (leftMethod != null && rightMethod != null) { throw new AmbiguousOperatorException(symbol, query.leftType, query.rightType); } var method = (leftMethod ?? rightMethod); if (method != null) { userDefinedOperandTypes.Add(query, ResolveUserDefinedOperandTypes(method)); } userDefinedOperators.Add(query, method?.Prewarm()); } else { if (leftMethod != null) { userDefinedOperandTypes.Add(query, ResolveUserDefinedOperandTypes(leftMethod)); } userDefinedOperators.Add(query, leftMethod?.Prewarm()); } } if (userDefinedOperators[query] != null) { leftOperand = ConversionUtility.Convert(leftOperand, userDefinedOperandTypes[query].leftType); rightOperand = ConversionUtility.Convert(rightOperand, userDefinedOperandTypes[query].rightType); return(userDefinedOperators[query].Invoke(null, leftOperand, rightOperand)); } } return(CustomHandling(leftOperand, rightOperand)); }