//called when data for any output pin is requested public override void Evaluate(int SpreadMax) { var FieldCount = Getters.Count; if (FLearn[0] && FInput.SliceCount > 0 && FInput[0] != null) { var type = FInput[0].GetType(); FLogger.Log(LogType.Debug, "Learning Type... " + type.FullName); FieldInfo[] fields = type.GetFields(); FieldCount = fields.Length; FName.SliceCount = FieldCount; Getters.Clear(); var formular = new MessageFormular(type.FullName, ""); for (var i = 0; i < FieldCount; i++) { var name = fields[i].Name; FName[i] = name; var fieldInfo = type.GetField(name); try { formular.Append(new FormularFieldDescriptor(fieldInfo.FieldType, name, 1), true); var getter = fieldInfo.CompileGetter(); Getters.Add(name, getter); FLogger.Log(LogType.Debug, "Success: " + fieldInfo.FieldType.Name + " " + name); } catch (Exception) { FLogger.Log(LogType.Debug, "Failed: " + fieldInfo.FieldType.Name + " " + name); //FLogger.Log(ex, LogType.Debug); } } Formular = formular; } SpreadMax = FInput.SliceCount; FOutput.SliceCount = SpreadMax; for (int i = 0; i < SpreadMax; i++) { var m = new Message(Formular.Name); foreach (var fieldName in Formular.FieldNames) { var getter = Getters[fieldName]; var bin = BinFactory.New(Formular[fieldName].Type); bin.Add(getter(FInput[i])); m[fieldName] = bin; } FOutput[i] = m; } }
private Bin <T> Fresh <T>() { var bin = BinFactory.New <T>(); Assert.IsTrue(bin.IsChanged); bin.IsChanged = false; return(bin); }
public override void Evaluate(int SpreadMax) { InitDX11Graph(); bool warnPinSafety = false; if (RemovePinsFirst) { warnPinSafety = !RetryConfig(); } if (!FNew.Any()) // if none true { FOutput.FlushNil(); return; } SpreadMax = FNew.CombineWith(FTopic); foreach (string name in FPins.Keys) { var pin = FPins[name].ToISpread(); pin.Sync(); SpreadMax = Math.Max(pin.SliceCount, SpreadMax); } FOutput.SliceCount = 0; for (int i = 0; i < SpreadMax; i++) { if (FNew[i]) { var message = new Message(); message.Topic = FTopic[i]; foreach (string name in FPins.Keys) { var pin = FPins[name].ToISpread(); if (pin.SliceCount > 0) { message.AssignFrom(name, pin[i] as ISpread); } else { message[name] = BinFactory.New(Formular[name].Type); // will do empty spreads as well, but ignore faults } } FOutput.Add(message); } } FOutput.Flush(); if (warnPinSafety) { throw new PinConnectionException("Manually remove unneeded links first! [Create]. ID = [" + PluginHost.GetNodePath(false) + "]"); } }
public void Multiple() { var json = @"{'Field':['Test', 'Foo', 'Bar']}"; var message = JsonConvert.DeserializeObject <Message>(json); Assert.IsFalse(message.IsEmpty); var bin = BinFactory.New("Test", "Foo", "Bar"); Assert.AreEqual(bin, message["Field"]); }
public void ConvertExplicit() { var json = @"{'Field<int>':['1', '2', '3']}"; var message = JsonConvert.DeserializeObject <Message>(json); Assert.IsFalse(message.IsEmpty); var bin = BinFactory.New(1, 2, 3); Assert.AreEqual(bin, message["Field"]); }
private Bin <T> BinCreationEmpty <T>() { var bin = BinFactory.New <T>(); Assert.AreEqual(bin.IsChanged, true); Assert.AreEqual(bin.GetInnerType(), typeof(T)); Assert.IsInstanceOfType(bin, typeof(Bin <T>)); Assert.AreEqual(bin.Count, 0); return(bin); }
private Bin <T> BinCreationSingle <T>(T item) { var bin = BinFactory.New <T>(item); // works the same without <T> Assert.AreEqual(bin.GetInnerType(), typeof(T)); Assert.IsInstanceOfType(bin, typeof(Bin <T>)); Assert.AreEqual(bin.Count, 1); Assert.IsInstanceOfType(bin.First, typeof(T)); Assert.AreEqual(bin[0], item); Assert.AreEqual(bin.IsChanged, true); return(bin); }
public void IsEqual() { var bin = BinFactory.New(1, 2, 3); var binA = BinFactory.New(1, 2, 3); var binB = BinFactory.New(1, 2); var binC = BinFactory.New(1.0, 2.0, 3.0); Assert.AreEqual(bin, binA); Assert.AreNotEqual(bin, binB); Assert.AreNotEqual(bin, binC); }
public void InitTest() { var name = "field"; var m = new Message("topic"); m.Commit(this); Assert.IsFalse(m.IsChanged); m.Init(name, 1, 2, 3, 4); Assert.IsTrue(m.IsChanged); Assert.AreEqual(m[name], BinFactory.New(1, 2, 3, 4)); Assert.AreEqual(m[name].Count, 4); }
public override void Evaluate(int SpreadMax) { if (!FNew.Any()) // if none true { FOutput.FlushNil(); if (RemovePinsFirst) { RetryConfig(); } return; } SpreadMax = FNew.CombineWith(FTopic); foreach (string name in FPins.Keys) { var pin = FPins[name].ToISpread(); pin.Sync(); SpreadMax = Math.Max(pin.SliceCount, SpreadMax); } FOutput.SliceCount = 0; for (int i = 0; i < SpreadMax; i++) { if (FNew[i]) { var message = new Message(); message.Topic = FTopic[i]; foreach (string name in FPins.Keys) { var pin = FPins[name].ToISpread(); if (pin.SliceCount > 0) { message.AssignFrom(name, pin[i] as ISpread); } else { message[name] = BinFactory.New(Formular[name].Type); // will do empty spreads as well, but ignore faults } } FOutput.Add(message); } } FOutput.Flush(); if (RemovePinsFirst) { RetryConfig(); } }
protected Bin BinFromCurrent(Unpacker unpacker) { var data = unpacker.LastReadData; if (data.IsArray || data.IsList) { throw new ParseMessageException("Message cannot handle nested arrays or lists."); } if (data.IsNil) { throw new ParseMessageException("Message cannot infer type for Nil."); } var type = data.UnderlyingType; Bin bin = null; if (type == typeof(byte[])) { var ext = (MessagePackExtendedTypeObject)data; var binType = ( from mapping in Code where mapping.Value == ext.TypeCode let t = TypeIdentity.Instance[mapping.Key]?.Type where t != null select t ).FirstOrDefault(); if (binType == null) { new ParseMessageException("No matching extension deserializer found in the SerializationContext"); } bin = BinFactory.New(binType); } else { bin = type.IsPrimitive && AsInt.Contains(type) ? BinFactory.New <int>() : BinFactory.New(type); // check if small ints were converted down for saving traffic } if (bin == null) { throw new TypeNotSupportedException("Cannot find out type from msgpack"); } var alias = TypeIdentity.Instance[bin.GetInnerType()].Alias; bin.Add(FromCurrent(unpacker, alias)); return(bin); }
public void SetIllegalName() { var name = "illegal field name"; var m = new Message("topic"); try { m[name] = BinFactory.New(1, 2, 3); Assert.Fail("Illegal Field name should throw exception"); } catch (ParseFormularException) { //ok } }
public void RenameTest() { var name = "field"; var m = new Message("topic"); var data = Enumerable.Repeat(4, 4); m.AssignFrom(name, data); m.Commit(this); Assert.IsFalse(m.IsChanged); m.Rename(name, "newName"); Assert.IsTrue(m.IsChanged); Assert.AreEqual(m["newName"], BinFactory.New(4, 4, 4, 4)); Assert.AreEqual(m["newName"].Count, 4); }
public void RenameTestOverwrite() { var name = "field"; var newName = "newName"; var m = new Message("topic"); m.Init(newName, 1); m.Init(name, 4, 4, 4, 4); m.Commit(this); Assert.IsFalse(m.IsChanged); m.Rename(name, newName, true); Assert.IsTrue(m.IsChanged); Assert.AreEqual(m[newName], BinFactory.New(4, 4, 4, 4)); Assert.AreEqual(m[newName].Count, 4); }
public void AssignFromTest() { var name = "field"; var m = new Message("topic"); m.Sync(); Assert.IsFalse(m.IsChanged); var data = Enumerable.Repeat(4, 4); m.AssignFrom(name, data); Assert.IsTrue(m.IsChanged); Assert.AreEqual(m[name], BinFactory.New(4, 4, 4, 4)); Assert.AreEqual(m[name].Count, 4); }
public void Set() { var name = "field"; var m = new Message("topic"); var data = Enumerable.Repeat(4, 4); m.Commit(this); Assert.IsFalse(m.IsChanged); m[name] = BinFactory.New(data); Assert.IsTrue(m.IsChanged); m.Commit(this); Assert.AreEqual(m[name], BinFactory.New(4, 4, 4, 4)); Assert.AreEqual(m[name].Count, 4); Assert.IsFalse(m.IsChanged); }
public void ChangeBinFirst() { var bin = BinFactory.New <int>(1, 2, 3, 4); bin.IsChanged = false; Assert.AreEqual(1, bin.First); Assert.IsFalse(bin.IsChanged); bin.First = 1; Assert.AreEqual(1, bin.First); Assert.IsTrue(bin.IsChanged); bin.IsChanged = false; bin.First = 42; Assert.AreEqual(42, bin.First); Assert.IsTrue(bin.IsChanged); }
public void ChangeBinIndex() { var bin = BinFactory.New <int>(1, 2, 3, 4); bin.IsChanged = false; Assert.AreEqual(2, bin[1]); Assert.IsFalse(bin.IsChanged); bin[1] = 1; Assert.IsTrue(bin.IsChanged); Assert.AreEqual(1, bin[1]); bin.IsChanged = false; bin[4] = 1; // add one more Assert.IsTrue(bin.IsChanged); Assert.AreEqual(1, bin[1]); }
private Bin <T> BinCreationWithMultiples <T>(T itemA, T itemB, T itemC) { var bin = BinFactory.New <T>(itemA, itemB, itemC); Assert.AreEqual(bin.GetInnerType(), typeof(T)); Assert.IsInstanceOfType(bin, typeof(Bin <T>)); Assert.AreEqual(bin.Count, 3); Assert.IsInstanceOfType(bin[0], typeof(T)); Assert.IsInstanceOfType(bin[1], typeof(T)); Assert.IsInstanceOfType(bin[2], typeof(T)); Assert.AreEqual(bin[0], itemA); Assert.AreEqual(bin[1], itemB); Assert.AreEqual(bin[2], itemC); Assert.IsInstanceOfType(bin.First, typeof(T)); Assert.AreEqual(bin.IsChanged, true); return(bin); }
protected bool CopyFromPins(Message message, int index, bool checkPinForChange = false) { var hasCopied = false; foreach (string name in FPins.Keys) { // don't change if pin data still the same if (!checkPinForChange || FPins[name].ToISpread().IsChanged) { var pinSpread = FPins[name].ToISpread(); var type = Formular[name].Type; IEnumerable bin; if (pinSpread.IsAnyInvalid()) { bin = Enumerable.Empty <object>(); } else { bin = pinSpread[index] as IEnumerable; } // don't change if pin data equals the message data if (!message.Fields.Contains(name)) { message[name] = BinFactory.New(type); hasCopied = true; } if (!message[name].Equals(bin)) { message.AssignFrom(name, bin, type); hasCopied = true; } } } return(hasCopied); }
protected Message MatchByField(Message message, IEnumerable <string> idFields) { // make sure all messages have the field var missingFields = from fieldName in idFields.Distinct() where fieldName != TOPIC where !message.Fields.Contains(fieldName) select fieldName; foreach (var fieldName in missingFields) { message[fieldName] = BinFactory.New(Formular[fieldName].Type); } var bins = ( from fieldName in idFields.Distinct() where fieldName != TOPIC // where message.Fields.Contains(fieldName) select fieldName ).ToArray(); bool includeTopic = idFields.Contains(TOPIC); // bool isCompatible = compatibleBins.Count() == idFields.Distinct().Count() - (includeTopic ? 1 : 0); var match = ( from keep in Keep // where isCompatible where !includeTopic || keep.Topic.Equals(message.Topic) where bins.Length == 0 || ( from fieldName in bins select(keep[fieldName] as Bin).Equals(message[fieldName] as Bin) ).All(x => x) select keep ).DefaultIfEmpty(null).First(); return(match); }
private void LazyInsert(Message message, string fieldName, ISpread spread) { if (!message.Fields.Contains(fieldName)) { message[fieldName] = BinFactory.New(TargetDynamicType); } if (spread.SliceCount > 0) { if (message[fieldName].GetInnerType().IsAssignableFrom(TargetDynamicType)) { // check if any relevant change occurred if (!message[fieldName].Equals(spread as IEnumerable)) { message.AssignFrom(fieldName, spread); } } else { var targetType = message[fieldName].GetInnerType(); var newBin = BinFactory.New(targetType, spread.SliceCount); for (int k = 0; k < spread.SliceCount; k++) // iterate all elements in a field { newBin[k] = Convert.ChangeType(spread[k], targetType); } if (!message[fieldName].Equals(newBin)) { message.AssignFrom(fieldName, newBin); } } } else { message[fieldName].Clear(); } }
public void SetFirstInvalidObject() { Bin bin = BinFactory.New(1, 2, 3); bin.First = 1.0; }
public void SetFirstUnregistered() { Bin bin = BinFactory.New(1, 2, 3); bin.First = new object(); }
public void SetFirstNull() { Bin bin = BinFactory.New(1, 2, 3); bin.First = null; }
/// <summary> /// Utility method to unpack from msgpack. /// </summary> /// <remarks>Will be used recursively to parse nested messages</remarks> /// <param name="unpacker"></param> /// <returns></returns> /// <exception cref="TypeNotSupportedException">Thrown, when a datatype of msgpack is not supported, e.g. enums</exception> /// <exception cref="ParseMessageException">Generic exception </exception> /// <exception cref="OverflowException" >Thrown from msgpack, if a received long does not fit into an int.</exception> protected override Message UnpackFromCore(Unpacker unpacker) { var message = new Message(); if (!unpacker.IsMapHeader) { throw new ParseMessageException("Incoming msgpack stream does not seem to be a Map, only Maps can be transcoded to Message. Did you rewind Position?"); } var count = unpacker.ItemsCount; while (count > 0 && AssertSuccess(unpacker.Read())) { count--; if (!unpacker.LastReadData.IsRaw) { throw new ParseMessageException("Only strings can be keys of supported dictionaries. Sorry, only Json style here"); } string fieldName = unpacker.LastReadData.AsString(); if (fieldName == "Topic") { string topic; unpacker.ReadString(out topic); message.Topic = topic; continue; } if (fieldName == "Stamp") { MessagePackExtendedTypeObject ext; unpacker.ReadMessagePackExtendedTypeObject(out ext); message.TimeStamp = TimeSerializer.UnpackSingleObject(ext.GetBody()); continue; } Bin bin; AssertSuccess(unpacker.Read()); if (unpacker.IsMapHeader) // single Message { bin = BinFactory.New(UnpackFromCore(unpacker)); } else if (unpacker.IsArrayHeader) // multiples! { long binCount = unpacker.LastReadData.AsInt64(); if (binCount <= 0) { continue; // cannot infer type, so skip } AssertSuccess(unpacker.Read()); // populates a new MessagePackObject, GC ahoy if (unpacker.IsMapHeader) // multiple nested messages { bin = BinFactory.New <Message>(UnpackFromCore(unpacker)); for (int i = 1; i < binCount; i++) { AssertSuccess(unpacker.Read()); bin.Add(UnpackFromCore(unpacker)); } } else // multiple slices { bin = BinFromCurrent(unpacker); var alias = TypeIdentity.Instance[bin.GetInnerType()].Alias; for (int i = 1; i < binCount; i++) { AssertSuccess(unpacker.Read()); var item = FromCurrent(unpacker, alias); bin.Add(item); } } } else // single slice of non-Message { bin = BinFromCurrent(unpacker); } message[fieldName] = bin; } return(message); }
public override void Evaluate(int SpreadMax) { // graceful fallback when being fed bad data if (FNew.IsAnyInvalid() || FTopic.IsAnyInvalid() || FSpreadCount.IsAnyInvalid()) { FOutput.FlushNil(); return; } if (!FNew.Any() && !ForceNewDefaults) { FOutput.FlushNil(); return; } SpreadMax = FFormularSelection.SliceCount; // numbers of supported Formulars FOutput.SliceCount = SpreadMax; var counter = 0; for (int i = 0; i < SpreadMax; i++) { var formularName = FFormularSelection[i].Name; var formular = MessageFormularRegistry.Context[formularName]; FOutput[i].SliceCount = 0; if (formular == null) { continue; } var count = FSpreadCount[i]; for (int j = 0; j < count; j++) { if (FNew[counter] || ForceNewDefaults) { Message message = new Message(); message.Topic = FTopic[counter]; foreach (var field in formular.FieldNames) { int binsize = formular[field].DefaultSize; binsize = binsize > 0 ? binsize : 1; var type = formular[field].Type; message[field] = BinFactory.New(type, binsize); for (int slice = 0; slice < binsize; slice++) { message[field].Add(TypeIdentity.Instance.NewDefault(type)); } } FOutput[i].Add(message); } counter++; } } FOutput.Flush(); ForceNewDefaults = false; }
public void FailChangeBinIndexAbove() { Bin bin = BinFactory.New(1, 2, 3); bin[0] = null; }
public static Message FromOSC(Stream stream, Dictionary <string, IEnumerable <FormularFieldDescriptor> > parser, bool extendedMode = false) { if (stream == null || stream.Length == 0) { return(null); } var size = stream.Length; var bytes = new byte[size]; stream.Position = 0; stream.Read(bytes, 0, (int)size); OSCPacket oscMessage = OSCPacket.Unpack(bytes, extendedMode); // seems slightly slower. //OSCPacket oscMessage; //var reader = new BinaryReader(stream); //{ // var bytes = reader.ReadBytes((int)stream.Length); // oscMessage = OSCPacket.Unpack(bytes, extendedMode); //} if (oscMessage == null || oscMessage.IsBundle()) { return(null); } if (!parser.ContainsKey(oscMessage.Address)) { return(null); // skip if unknown address } Message message = new Message(); message.TimeStamp = Time.CurrentTime(); message.Topic = AsTopic(oscMessage.Address); var fields = parser[oscMessage.Address].ToList(); int pointer = 0; for (int i = 0; i < fields.Count(); i++) { var field = fields[i]; var count = field.DefaultSize; // todo: how to deal with -1 ? if (count < 0) { count = 1; } var bin = BinFactory.New(field.Type, count); for (int j = 0; (j < count) && (pointer < oscMessage.Values.Count); j++, pointer++) // stop short if running out of parser fields OR data from osc { bin.Add(oscMessage.Values[pointer]); // implicit conversion } message[field.Name] = bin; } return(message); }
public static Message FromOSC(Stream stream, bool extendedMode = false, string messagePrefix = "", int contractAddress = 1) { if (stream == null || stream.Length <= 0) { return(null); } stream.Position = 0; byte[] bytes = new byte[stream.Length]; stream.Read(bytes, 0, (int)stream.Length); if (bytes.Length == 0) { return(null); } Message message = new Message(); var pack = OSCPacket.Unpack(bytes, extendedMode); bool useNesting; OSCBundle bundle; if (pack.IsBundle()) { bundle = (OSCBundle)pack; message.TimeStamp = bundle.getTimeStamp(); // if not set, will be 1.1.1900 useNesting = true; } else { bundle = new OSCBundle(extendedMode); var m = (OSCMessage)pack; bundle.Append(m); message.TimeStamp = Time.CurrentTime(); useNesting = false; } foreach (OSCMessage m in bundle.Values) { string[] address = m.Address.Trim(new char[] { '/' }).Split('/'); string messageAddress = string.Join(".", address.Take(Math.Max(1, address.Length - contractAddress)).ToArray()); if (messagePrefix.Trim() == "") { message.Topic = messageAddress; } else { message.Topic = messagePrefix + "." + messageAddress; } // empty messages are usually used for requesting data if (m.Values.Count <= 0) { // leave message emtpy, cannot infer type. } else { var usedTypes = ( from v in m.Values.ToArray() select v.GetType() ).Distinct(); string attribName = string.Join(".", address.Skip(Math.Max(0, address.Length - contractAddress)).ToArray()); if (usedTypes.Count() > 1) { var inner = new Message(message.Topic + "." + attribName); var max = m.Values.Count; for (int i = 0; i < max; i++) { var item = m.Values[i]; var num = i.ToString(); inner[num] = BinFactory.New(item.GetType()); inner[num].Add(item); } if (useNesting) { message[attribName] = BinFactory.New(inner); } else { message = inner; } } else { var bin = BinFactory.New(usedTypes.First()); bin.AssignFrom(m.Values); message[attribName] = bin; } } } return(message); }