public FieldModel(InstanceModel instance, FieldModel parent, RowTypes type) { Instance = instance; RowType = type; Nodes = new List<IFieldModel>(); Cells = new List<string>(); ID = Instance.RndGen.Next(); Instance.FieldMap[ID] = this; if (parent == null) return; ParentField = parent; Instances = parent.Instances; }
public FieldModel(InstanceModel grid, FieldModel parent, RowTypes rowType, Type type) : this(grid, parent, rowType) { FieldType = type; }
public object GetFieldValue(object rootInstanceValue) { object current = rootInstanceValue; object found = null; // dont need to traverse type chain for static types FieldModel[] chain = TypeChain; if (TypeInfo != null && TypeInfo.IsStatic) chain = new FieldModel[] { this }; foreach (var link in chain) { // if has index value, get that if (link.RowType == RowTypes.Element) { int i = 0; var e = (current as ICollection).GetEnumerator(); while (e.MoveNext()) { if (i == link.ElementIndex) { current = e.Current; break; } i++; } } else if (link.RowType == RowTypes.Field) { if (!link.TypeInfo.IsStatic && current == null) return ""; // "<not static>"; current = link.TypeInfo.GetValue(current); // current can be null for first lookup (static, but after that needs a value) if (current == null) { found = current; break; } } // check if at end of chain if (link == this || (RowType == RowTypes.Enumerate && ParentField == link)) { found = current; break; } } //return debugChain; return found; }
public void BeginUpdateTree(bool refresh) { if (SelectedNode == null) return; if (XRay.RemoteViewer) { if (XRay.Remote.ServerConnection == null) { DetailsLabel = "Not connected to server to get instance information"; return; } // send request for initial table data if (!refresh) { var packet = new GenericPacket("RequestInstance"); packet.Data = new Dictionary<string, string> { {"ThreadID", Thread.CurrentThread.ManagedThreadId.ToString()}, {"NodeID", SelectedNode.ID.ToString()} }; if (FieldFilter != null) packet.Data["Filter"] = FieldFilter; XRay.RunInCoreAsync(() => XRay.Remote.ServerConnection.SendPacket(packet)); } // else send request to refresh table data else { var packet = new GenericPacket("RequestInstanceRefresh"); packet.Data = new Dictionary<string, string> { {"ThreadID", Thread.CurrentThread.ManagedThreadId.ToString()} }; XRay.RunInCoreAsync(() => XRay.Remote.ServerConnection.SendPacket(packet)); } return; } var nodeTypeName = SelectedNode.UnformattedName; var record = SelectedNode.Record; if (record == null) { if (SelectedNode.External) DetailsLabel = "Not XRayed"; else DetailsLabel = "No record of being created"; return; } DetailsLabel = String.Format("Active: {0}, Created: {1}, Deleted: {2}", record.Active.Count, record.Created, record.Deleted); // rebuild each list cause instances may be added or removed foreach (var recordList in GenericMap.Values) recordList.Item2.Clear(); if (record != null && record.Active.Count > 0) { lock (record.Active) { // traverse up the record's base types until we match the type for the class node selected in the UI // (cant show a debug matrix for types with different properties) // for example we click on the TreeView class, but the record type is of BuddyTreeView for (int i = 0; i < record.Active.Count && i < MaxInstances; i++) { var instance = record.Active[i]; if (!instance.IsStatic && instance.Ref.Target == null) continue; Type recordType = instance.InstanceType; string recordTypeName = ""; while (recordType != null) { recordTypeName = recordType.ToString(); if (recordTypeName.Contains(nodeTypeName)) break; recordType = recordType.BaseType; } if (recordType == null) throw new Exception(string.Format("record type not found for node type {0} and instance type {1}", nodeTypeName, recordType.ToString())); // if we're looking at a template class, then each root node is a diff type of template List<int>, List<string> etc.. recordTypeName = recordType.ToString(); string genericName = SelectedNode.Name; if (recordTypeName.Contains('`')) genericName = recordTypeName.Substring(recordTypeName.IndexOf('`')); if (!GenericMap.ContainsKey(genericName)) GenericMap[genericName] = new Tuple<Type, List<ActiveRecord>>(recordType, new List<ActiveRecord>()); List<ActiveRecord> recordList = GenericMap[genericName].Item2; if (!recordList.Contains(instance)) recordList.Add(instance); } } } // add columns for each intance int instanceCount = 0; if (GenericMap.Count > 0) instanceCount = GenericMap.Values.Max(v => v.Item2.Count); ColumnsUpdated = false; var newColumns = new List<string>(); for (int i = 0; i < instanceCount; i++) if (Columns.Count <= 2 + i) { var col = "Instance " + i.ToString(); newColumns.Add(col); Columns.Add(col); ColumnsUpdated = true; } while (Columns.Count > 2 + instanceCount) { Columns.RemoveAt(Columns.Count - 1); ColumnsUpdated = true; } UpdatedFields = new HashSet<int>(); foreach (var recordInstance in GenericMap) { var model = RootNodes.Cast<FieldModel>().FirstOrDefault(r => r.GenericName == recordInstance.Key); if (model != null) { model.RefreshField(); continue; } model = new FieldModel(this, null, RowTypes.Root); model.GenericName = recordInstance.Key; model.FieldType = recordInstance.Value.Item1; // instance type that matches selected node model.Instances = recordInstance.Value.Item2; // list of instances if (model.Instances.Count > 0 && model.Instances[0].IsStatic) Columns[2] = "Static"; RootNodes.Add(model); model.Init(); model.ExpandField(FieldFilter); } if(UpdatedTree != null) UpdatedTree(); }
public void ExpandField(string fieldFilter = null) { if (Expanded) { if(Instance.ExpandedField != null) Instance.ExpandedField(this); return; } Expanded = true; Nodes.Clear(); if (FieldType != null) { if (RowType == RowTypes.Root && fieldFilter == null) { AddRow(new FieldModel(Instance, this, RowTypes.Declared)); AddRow(new FieldModel(Instance, this, RowTypes.Selected, FieldType)); AddRow(new FieldModel(Instance, this, RowTypes.Number)); AddRow(new FieldModel(Instance, this, RowTypes.Age)); } if (fieldFilter == null) AddFieldMembers(); else { var field = FieldType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).FirstOrDefault(f => f.Name == fieldFilter); if (field != null) { XRay.LogError("Field " + fieldFilter + " found on " + FieldType.ToString()); var row = new FieldModel(Instance, this, RowTypes.Field, field); AddRow(row); row.ExpandField(); } else XRay.LogError("Field " + fieldFilter + " not found on " + FieldType.ToString()); } } RefreshField(); if (Instance.ExpandedField != null) Instance.ExpandedField(this); }
public void AddRow(FieldModel row) { Nodes.Add(row); row.Init(); }
public FieldModel(InstanceModel grid, FieldModel parent, RowTypes rowType, FieldInfo info) : this(grid, parent, rowType, info.FieldType) { TypeInfo = info; }
public FieldModel(InstanceModel grid, FieldModel parent, RowTypes rowType, Type type, int elementIndex) : this(grid, parent, rowType, type) { ElementIndex = elementIndex; }
public FieldModel(InstanceModel grid, FieldModel parent, RowTypes rowType, PropertyInfo info) : this(grid, parent, rowType, info.PropertyType) { PropertyInfo = info; }