private static void StartNewSong(Song song, TimeSpan?startPosition) { lock (_volumeLock) { if (_volumeController != null) { _volumeController.Dispose(); _volumeController = null; } } _currentSong = song; //We need to start playing from 0, then seek the stream when the topology is ready, otherwise the song doesn't play. if (startPosition.HasValue) { _desiredPosition = PositionVariantFor(startPosition.Value); } _session.SetTopology(SessionSetTopologyFlags.Immediate, song.Topology); StartSession(PositionBeginning); // The volume service won't be available until the session topology // is ready, so we now need to wait for the event indicating this }
public void ReadWriteNullableVariantWithNull() { Variant?expected = null; var json = Serializer.SerializeObject(expected); var result = Serializer.DeserializeObject <Variant?>(json); Assert.Equal(expected, result); }
private static void OnTopologyReady() { IntPtr volumeObjectPtr; MediaFactory.GetService(_session, MediaServiceKeys.StreamVolume, AudioStreamVolumeGuid, out volumeObjectPtr); _volumeController = CppObject.FromPointer <AudioStreamVolume>(volumeObjectPtr); SetChannelVolumes(); if (_desiredPosition.HasValue) { StartSession(_desiredPosition.Value); _desiredPosition = null; } }
/// <inheritdoc/> public VariantValue Encode(Variant?value, out BuiltInType builtinType) { if (value == null || value == Variant.Null) { builtinType = BuiltInType.Null; return(VariantValue.Null); } using (var stream = new MemoryStream()) { using (var encoder = new JsonEncoderEx(stream, Context) { UseAdvancedEncoding = true }) { encoder.WriteVariant(nameof(value), value.Value); } var token = Serializer.Parse(stream.ToArray()); Enum.TryParse((string)token.GetByPath("value.Type"), true, out builtinType); return(token.GetByPath("value.Body")); } }
/// <inheritdoc /> public bool Equals(Variant?other) { return(ReferenceEquals(this, other)); }
/// <summary> /// Shows a value in control. /// </summary> private async Task ShowValue(int index, bool overwrite, object value) { if (value == null) { return; } // show monitored items. MonitoredItem monitoredItem = value as MonitoredItem; if (monitoredItem != null) { m_monitoredItem = monitoredItem; ShowValue(ref index, ref overwrite, monitoredItem.LastValue.ToString()); return; } // show data changes MonitoredItemNotification datachange = value as MonitoredItemNotification; if (datachange != null) { ShowValue(ref index, ref overwrite, datachange.Value.ToString()); return; } // show events EventFieldList eventFields = value as EventFieldList; if (eventFields != null) { for (int ii = 0; ii < eventFields.EventFields.Count; ii++) { ShowValue(ref index, ref overwrite, eventFields, ii); } return; } // show extension bodies. ExtensionObject extension = value as ExtensionObject; if (extension != null) { ShowValue(ref index, ref overwrite, extension.Body.ToString()); return; } // show encodeables. IEncodeable encodeable = value as IEncodeable; if (encodeable != null) { PropertyInfo[] properties = encodeable.GetType().GetProperties(); foreach (PropertyInfo property in properties) { ShowValue(ref index, ref overwrite, encodeable, property); } return; } // show bytes. byte[] bytes = value as byte[]; if (bytes != null) { bool result = await PromptOnLongList(bytes.Length / 16); if (!result) { return; } for (int ii = 0; ii < bytes.Length; ii += 16) { ShowValue(ref index, ref overwrite, bytes, ii); } return; } // show arrays Array array = value as Array; if (array != null) { bool result = await PromptOnLongList(array.Length); if (!result) { return; } for (int ii = 0; ii < array.Length; ii++) { ShowValue(ref index, ref overwrite, array, ii); } return; } // show lists IList list = value as IList; if (list != null) { bool result = await PromptOnLongList(list.Count); if (!result) { return; } for (int ii = 0; ii < list.Count; ii++) { ShowValue(ref index, ref overwrite, list, ii); } return; } // show xml elements XmlElement xml = value as XmlElement; if (xml != null) { bool result = await PromptOnLongList(xml.ChildNodes.Count); if (!result) { return; } for (int ii = 0; ii < xml.ChildNodes.Count; ii++) { ShowValue(ref index, ref overwrite, xml, ii); } return; } // show data value. DataValue datavalue = value as DataValue; if (datavalue != null) { ShowValue(ref index, ref overwrite, datavalue, 0); ShowValue(ref index, ref overwrite, datavalue, 1); ShowValue(ref index, ref overwrite, datavalue, 2); ShowValue(ref index, ref overwrite, datavalue, 3); return; } // show node id value. NodeId nodeId = value as NodeId; if (nodeId != null) { ShowValue(ref index, ref overwrite, nodeId, 0); ShowValue(ref index, ref overwrite, nodeId, 1); ShowValue(ref index, ref overwrite, nodeId, 2); return; } // show expanded node id value. ExpandedNodeId expandedNodeId = value as ExpandedNodeId; if (expandedNodeId != null) { ShowValue(ref index, ref overwrite, expandedNodeId, 0); ShowValue(ref index, ref overwrite, expandedNodeId, 1); ShowValue(ref index, ref overwrite, expandedNodeId, 2); ShowValue(ref index, ref overwrite, expandedNodeId, 3); return; } // show qualified name value. QualifiedName qualifiedName = value as QualifiedName; if (qualifiedName != null) { ShowValue(ref index, ref overwrite, qualifiedName, 0); ShowValue(ref index, ref overwrite, qualifiedName, 1); return; } // show qualified name value. LocalizedText localizedText = value as LocalizedText; if (localizedText != null) { ShowValue(ref index, ref overwrite, localizedText, 0); ShowValue(ref index, ref overwrite, localizedText, 1); return; } // show variant. Variant?variant = value as Variant?; if (variant != null) { ShowValue(ref index, ref overwrite, variant.Value.Value.ToString()); return; } // show unknown types as strings. ShowValue(ref index, ref overwrite, String.Format("{0}", value)); }
private static void OnTopologyReady() { IntPtr volumeObjectPtr; MediaFactory.GetService(_session, MediaServiceKeys.StreamVolume, AudioStreamVolumeGuid, out volumeObjectPtr); _volumeController = CppObject.FromPointer<AudioStreamVolume>(volumeObjectPtr); SetChannelVolumes(); if (_desiredPosition.HasValue) { StartSession(_desiredPosition.Value); _desiredPosition = null; } }
private static void StartNewSong(Song song, TimeSpan? startPosition) { if (_volumeController != null) { _volumeController.Dispose(); _volumeController = null; } _currentSong = song; //We need to start playing from 0, then seek the stream when the topology is ready, otherwise the song doesn't play. if (startPosition.HasValue) _desiredPosition = PositionVariantFor(startPosition.Value); _session.SetTopology(SessionSetTopologyFlags.Immediate, song.Topology); StartSession(PositionBeginning); // The volume service won't be available until the session topology // is ready, so we now need to wait for the event indicating this }
public void ParseFromVariant(string text, Variant?expected) { Assert.AreEqual(expected, text.TryParseFromVariant()); }
/// <summary> /// Shows a value in control. /// </summary> private void ShowValue(ref int index, ref bool overwrite, object value) { if (value == null) { return; } // show monitored items. MonitoredItem monitoredItem = value as MonitoredItem; if (monitoredItem != null) { m_monitoredItem = monitoredItem; ShowValue(ref index, ref overwrite, monitoredItem.LastValue); return; } // show data changes MonitoredItemNotification datachange = value as MonitoredItemNotification; if (datachange != null) { ShowValue(ref index, ref overwrite, datachange.Value); return; } // show write value with IndexRange WriteValue writevalue = value as WriteValue; if (writevalue != null) { // check if the value is an array Array arrayvalue = writevalue.Value.Value as Array; if (arrayvalue != null) { NumericRange indexRange; ServiceResult result = NumericRange.Validate(writevalue.IndexRange, out indexRange); if (ServiceResult.IsGood(result) && indexRange != NumericRange.Empty) { for (int ii = 0; ii < arrayvalue.Length; ii++) { bool enabled = ((indexRange.Begin <= ii && indexRange.End >= ii) || (indexRange.End < 0 && indexRange.Begin == ii)); ShowValue(ref index, ref overwrite, arrayvalue, ii, enabled); } return; } } } // show events EventFieldList eventFields = value as EventFieldList; if (eventFields != null) { for (int ii = 0; ii < eventFields.EventFields.Count; ii++) { ShowValue(ref index, ref overwrite, eventFields, ii); } return; } // show extension bodies. ExtensionObject extension = value as ExtensionObject; if (extension != null) { ShowValue(ref index, ref overwrite, extension.Body); return; } // show encodeables. IEncodeable encodeable = value as IEncodeable; if (encodeable != null) { PropertyInfo[] properties = encodeable.GetType().GetProperties(); foreach (PropertyInfo property in properties) { ShowValue(ref index, ref overwrite, encodeable, property); } return; } // show bytes. byte[] bytes = value as byte[]; if (bytes != null) { if (!PromptOnLongList(bytes.Length / 16)) { return; } for (int ii = 0; ii < bytes.Length; ii += 16) { ShowValue(ref index, ref overwrite, bytes, ii); } return; } // show arrays Array array = value as Array; if (array == null) { Matrix matrix = value as Matrix; if (matrix != null) { array = matrix.ToArray(); } } if (array != null) { if (!PromptOnLongList(array.GetLength(0))) { return; } for (int ii = 0; ii < array.GetLength(0); ii++) { ShowValue(ref index, ref overwrite, array, ii); } return; } // show lists IList list = value as IList; if (list != null) { if (!PromptOnLongList(list.Count)) { return; } for (int ii = 0; ii < list.Count; ii++) { ShowValue(ref index, ref overwrite, list, ii); } return; } // show xml elements XmlElement xml = value as XmlElement; if (xml != null) { if (!PromptOnLongList(xml.ChildNodes.Count)) { return; } for (int ii = 0; ii < xml.ChildNodes.Count; ii++) { ShowValue(ref index, ref overwrite, xml, ii); } return; } // show data value. DataValue datavalue = value as DataValue; if (datavalue != null) { ShowValue(ref index, ref overwrite, datavalue, 0); ShowValue(ref index, ref overwrite, datavalue, 1); ShowValue(ref index, ref overwrite, datavalue, 2); ShowValue(ref index, ref overwrite, datavalue, 3); return; } // show node id value. NodeId nodeId = value as NodeId; if (nodeId != null) { ShowValue(ref index, ref overwrite, nodeId, 0); ShowValue(ref index, ref overwrite, nodeId, 1); ShowValue(ref index, ref overwrite, nodeId, 2); return; } // show expanded node id value. ExpandedNodeId expandedNodeId = value as ExpandedNodeId; if (expandedNodeId != null) { ShowValue(ref index, ref overwrite, expandedNodeId, 0); ShowValue(ref index, ref overwrite, expandedNodeId, 1); ShowValue(ref index, ref overwrite, expandedNodeId, 2); ShowValue(ref index, ref overwrite, expandedNodeId, 3); return; } // show qualified name value. QualifiedName qualifiedName = value as QualifiedName; if (qualifiedName != null) { ShowValue(ref index, ref overwrite, qualifiedName, 0); ShowValue(ref index, ref overwrite, qualifiedName, 1); return; } // show qualified name value. LocalizedText localizedText = value as LocalizedText; if (localizedText != null) { ShowValue(ref index, ref overwrite, localizedText, 0); ShowValue(ref index, ref overwrite, localizedText, 1); return; } // show variant. Variant?variant = value as Variant?; if (variant != null) { ShowValue(ref index, ref overwrite, variant.Value.Value); return; } // show unknown types as strings. ShowValue(ref index, ref overwrite, String.Format("{0}", value)); }
void recursiveInterpret(FunctionalInterpretationContext interpretationContext, ImmutableNodeReferer node) { if (!node.isBranch) { // it's it's own result node.interpretationResult = node; return; } // if we are here it must be an branch which must be executable // figure out if it is a native function call or a registered function call or a variable // if it is a string then this means that it indicates an variablename and not an call if (!node.children[0].isBranch && node.children[0].type == ValueNode.EnumType.STRING_DATATYPE && node.children[0].valueString == "string") { string variableName = getNativeString(node); Ensure.ensure(interpretationContext.existsVariableByName(variableName)); node.interpretationResult = interpretationContext.getVariableByName(variableName); return; } // was the result of the node already set in the node // used if we return an nonatomic result bool interpretationResultOfNodeIsAlreadySet = false; string operationName = getNativeString(node.children[0]); bool isSequence = operationName == "seq"; bool isLet = operationName == "let"; bool isCondition = operationName == "if"; bool isSpecial = isSequence || isLet || isCondition; string callName = ""; if (!isSpecial) { callName = operationName; if ( isNativeCallValid(callName) || interpretationContext.publicFnRegistryAndDispatcher.existsFunction(callName) ) { // nothing by purpose } else { throw new Exception("INTERPRETATIONEXCEPTION name \"" + operationName + "\"is not a native function call or a registered function call or a variable"); } } int callId = -1, sequenceId = -1, conditionId = -1; // illegal if (isSequence) { sequenceId = tracer.sequenceEnter(node); } else if (isLet) { // nothing by purpose } else if (isCondition) { conditionId = tracer.conditionEnter(node); } else { Ensure.ensureHard(!isSpecial); callId = tracer.callEnter(callName, node); } // is null if the result initialization is dependent on the callName Variant?interpretationResult = null; bool isFirstArgument = true; primitiveCalcResultForAdditionalArgumentType primitiveCalcResultForAdditionalArgument = delegate(Variant argument) { if (isFirstArgument) { isFirstArgument = false; interpretationResult = argument; return; } { // scope just for the null mess of interpretationResult Variant interpretationResultTemp = interpretationResult.Value; tryToWidenArithmeticType(ref interpretationResultTemp, argument.type); interpretationResult = interpretationResultTemp; } Variant castedArgument = hardCastVariantTo(argument, interpretationResult.Value.type); if (callName == "+") { if (castedArgument.type == Variant.EnumType.FLOAT) { interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat + castedArgument.valueFloat); } else if (castedArgument.type == Variant.EnumType.INT) { interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt + castedArgument.valueInt); } } else if (callName == "-") { if (castedArgument.type == Variant.EnumType.FLOAT) { interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat - castedArgument.valueFloat); } else if (castedArgument.type == Variant.EnumType.INT) { interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt - castedArgument.valueInt); } } else if (callName == "*") { if (castedArgument.type == Variant.EnumType.FLOAT) { interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat * castedArgument.valueFloat); } else if (castedArgument.type == Variant.EnumType.INT) { interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt * castedArgument.valueInt); } } else if (callName == "/") { if (castedArgument.type == Variant.EnumType.FLOAT) { Ensure.ensure(castedArgument.valueFloat != 0.0); interpretationResult = Variant.makeFloat(interpretationResult.Value.valueFloat / castedArgument.valueFloat); } else if (castedArgument.type == Variant.EnumType.INT) { Ensure.ensure(castedArgument.valueInt != 0); interpretationResult = Variant.makeInt(interpretationResult.Value.valueInt / castedArgument.valueInt); } } }; if (isLet) { Ensure.ensure(node.children.Length == 1 + 2); // let and variableAssignmentNode an executionNode ImmutableNodeReferer variableAssignmentArrayNode = node.children[1]; ImmutableNodeReferer executionNode = node.children[2]; Ensure.ensure(variableAssignmentArrayNode.isBranch); Ensure.ensure(variableAssignmentArrayNode.children.Length != 0); Ensure.ensure(getNativeString(variableAssignmentArrayNode.children[0]) == "array"); Ensure.ensure((variableAssignmentArrayNode.children.Length - 1) % 2 == 0); // array minus the array prefix must have a length divisable by two int numberOfAssingments = (variableAssignmentArrayNode.children.Length - 1) / 2; for (int assigmentI = 0; assigmentI < numberOfAssingments; assigmentI++) { string assignmentVariableName = getNativeString(variableAssignmentArrayNode.children[(1 + assigmentI * 2)]); ImmutableNodeReferer assignmentNode = variableAssignmentArrayNode.children[(1 + assigmentI * 2) + 1]; // for it to be calculated recursiveInterpret(interpretationContext, assignmentNode); // try to assign the variable Ensure.ensure(!interpretationContext.existsVariableByName(assignmentVariableName)); interpretationContext.assignVariable(assignmentVariableName, assignmentNode.interpretationResult); } // execute the execution node recursiveInterpret(interpretationContext, executionNode); // transfer result node.interpretationResult = executionNode.interpretationResult; } else if (isCondition) { Ensure.ensure(node.children.Length == 1 + 3); // "if" and conditionNode and true tode and false node ImmutableNodeReferer conditionNode = node.children[1]; ImmutableNodeReferer trueBranchNode = node.children[2]; ImmutableNodeReferer falseBranchNode = node.children[3]; // execute the condition node recursiveInterpret(interpretationContext, conditionNode); Ensure.ensure(conditionNode.interpretationResult != null); Ensure.ensure(!conditionNode.isBranch); Ensure.ensure(conditionNode.type == ValueNode.EnumType.VALUE); Ensure.ensure(conditionNode.value.type == Variant.EnumType.INT); // int which gets interpreted as bool long conditionInt = conditionNode.value.valueInt; Ensure.ensure(conditionInt == 0 || conditionInt == 1); // is it a valid boolean value bool conditionBool = conditionInt == 1; tracer.conditionCondition(conditionId, conditionNode, conditionNode.interpretationResult); tracer.conditionPathTaken(conditionId, conditionNode, conditionBool); if (conditionBool) { recursiveInterpret(interpretationContext, trueBranchNode); node.interpretationResult = trueBranchNode.interpretationResult; } else { recursiveInterpret(interpretationContext, falseBranchNode); node.interpretationResult = falseBranchNode.interpretationResult; } } else { // force all arguments to be calculated for (int argIdx = 0; argIdx < node.children.Length - 1; argIdx++) { ImmutableNodeReferer argumentNode = node.children[argIdx + 1]; if (isSequence) { tracer.sequenceElement(sequenceId, argumentNode); } recursiveInterpret(interpretationContext, argumentNode); } } if (isSequence) { tracer.sequenceResult(sequenceId, node.children[node.children.Length - 1].interpretationResult); tracer.sequenceExit(sequenceId); } else if (isCondition) { tracer.conditionExit(conditionId); } else if (!isSpecial) { if (isArithmetic(callName)) { // process arguments for (int argIdx = 0; argIdx < node.children.Length - 1; argIdx++) { ImmutableNodeReferer argumentValueNode = node.children[argIdx + 1].interpretationResult; primitiveCalcResultForAdditionalArgument(argumentValueNode.value); tracer.callArgument(callId, node.children[argIdx + 1], argumentValueNode, argIdx); } } else if (isBasicMathFunctionWithOneParameter(callName)) { Ensure.ensure(node.children.Length == 1 + 1 /* one arguments*/); ImmutableNodeReferer valueNode = node.children[1 + 0].interpretationResult; Ensure.ensure(isCastableTo(valueNode.value, Variant.EnumType.FLOAT)); Variant castedValueVariant = hardCastVariantTo(valueNode.value, Variant.EnumType.FLOAT); double resultValue = 0.0; switch (callName) { case "exp": resultValue = Math.Exp(castedValueVariant.valueFloat); break; case "sin": resultValue = Math.Sin(castedValueVariant.valueFloat); break; case "asin": resultValue = Math.Asin(castedValueVariant.valueFloat); break; case "cos": resultValue = Math.Cos(castedValueVariant.valueFloat); break; case "acos": resultValue = Math.Acos(castedValueVariant.valueFloat); break; case "tan": resultValue = Math.Tan(castedValueVariant.valueFloat); break; case "atan": resultValue = Math.Atan(castedValueVariant.valueFloat); break; default: throw new Exception("INTERNALERROR interpreter internal error"); } interpretationResult = Variant.makeFloat(resultValue); tracer.callArgument(callId, node.children[1 + 0], valueNode, 0); } else if (callName == "shl" || callName == "shr" || callName == "bAnd" || callName == "bOr") // shift { Ensure.ensure(node.children.Length == 1 + 2 /* two arguments*/); ImmutableNodeReferer leftNode = node.children[1 + 0].interpretationResult; ImmutableNodeReferer rightNode = node.children[1 + 1].interpretationResult; long leftValue = leftNode.value.valueInt; long rightValue = rightNode.value.valueInt; long result = 0; if (callName == "shl") { result = leftValue << (int)rightValue; } else if (callName == "shr") { result = leftValue >> (int)rightValue; } else if (callName == "bAnd") { result = leftValue & rightValue; } else if (callName == "bOr") { result = leftValue | rightValue; } // else should never happen interpretationResult = Variant.makeInt(result); tracer.callArgument(callId, node.children[1 + 0], leftNode, 0); tracer.callArgument(callId, node.children[1 + 1], rightNode, 1); } else if (interpretationContext.publicFnRegistryAndDispatcher.existsFunction(callName)) { // a function was invoked IList <ImmutableNodeReferer> invokeParameters = new List <ImmutableNodeReferer>(); // collect invoke parameters for (int i = 0; i < node.children.Length - 1; i++) { invokeParameters.Add(node.children[1 + 0].interpretationResult); } ImmutableNodeReferer calleeResult = interpretationContext.publicFnRegistryAndDispatcher.dispatchCall(callName, invokeParameters); node.interpretationResult = calleeResult; interpretationResultOfNodeIsAlreadySet = true; } else { throw new Exception("INTERNALERRROR"); // hard internal error because the case should be handled, because we already made sure that the callName is valid } if (!interpretationResultOfNodeIsAlreadySet) { node.interpretationResult = ImmutableNodeReferer.makeNonbranch(ValueNode.makeAtomic(interpretationResult.Value)); } tracer.callResult(callId, node.interpretationResult); tracer.callExit(callId); } }