예제 #1
0
        public static void Restore(ZComponent newObj, ZComponent oldObj)
        {
            if (newObj == null || oldObj == null) return;
            //Console.WriteLine("Restore: {0}({1}) -> {2}({3})", oldObj.GetType().Name, oldObj.Name ?? "", newObj.GetType().Name, newObj.Name ?? "");

            MemberwiseCopy(newObj, newObj.GetType(), oldObj, oldObj.GetType());

            // A reference to oldObj should be updated to newObj in its Children
            foreach (ZComponent child in newObj.Children)
            {
                if (child.Owner == oldObj) child.ReplaceOwner(newObj);
            }

            // If it is NOT a ZApplication
            if (typeof(ZApplication).IsAssignableFrom(newObj.GetType()) == false)
            {
                ZComponent.App.RemoveComponent(oldObj);     // remove the old component
                //ZComponent.App.AddNewComponent(newObj);        // add the new component
                
                // We should always set the Owner <= old Owner has been copied to newObj
                
                if (newObj.OwnerList != null)  // replace old object in OwnerList
                {
                    //newObj.OwnerList = oldObj.OwnerList;
                    int idx = newObj.OwnerList.IndexOf(oldObj);
                    if (idx != -1) newObj.OwnerList[idx] = newObj;
                }
                else if (newObj.Owner != null) // replace old object among Owner's Children
                {
                    int idx = newObj.Owner.Children.IndexOf(oldObj);
                    if (idx != -1) newObj.Owner.Children[idx] = newObj;
                }
                oldObj.ReplaceOwner(null);
                

                if (typeof(Model).IsAssignableFrom(newObj.GetType()))
                {
                    ZComponent.App.RemoveModel(oldObj as Model);
                    Model newMod = newObj as Model;
                    // Find named reference in App (only necessary for GameObjects)
                    if (newMod != null && newMod.Prototype == false && newMod.HasName())
                    {
                        FieldInfo fi = ZComponent.App.GetType().GetField(newMod.Name, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
                        if (fi != null && fi.FieldType == newObj.GetType())
                        {
                            //Console.WriteLine("Setting named reference {0} / {1}", fi.Name, fi.FieldType.Name);
                            fi.SetValue(ZComponent.App, newObj);
                        }
                    }
                    // Clear the static CustomGame reference 'App' in the old model classes
                    // It is enough to do this for the prototypes (there is one prototype for each class)
                    // If we don't null this, the old application will never be finalized
                    if (newMod.Prototype)
                    {
                        FieldInfo fi = oldObj.GetType().GetField("App", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
                        if (fi != null)
                        {
                            //Console.WriteLine("Setting named reference {0} / {1}", fi.Name, fi.FieldType.Name);
                            fi.SetValue(oldObj, null);
                        }
                    }
                }
            }           
            
            // Correct the Treeview tags
            ZNodeProperties props = newObj.Tag as ZNodeProperties;
            if (props != null)
            {
                props.Component = newObj;          

                TreeNode treeNode = props.treeNode;
                if (treeNode != null)
                    foreach (TreeNode childNode in treeNode.Nodes)
                    {
                        ZNodeProperties props1 = childNode.Tag as ZNodeProperties;
                        // Clear the reference to oldObj in the ZNodeProperties of all children / member lists
                        if (props1 != null && props1.Parent == oldObj)
                        {
                            props1.Parent = newObj;                            
                        }
                        /*foreach (TreeNode grandchildNode in childNode.Nodes)
                        {
                            ZNodeProperties props2 = grandchildNode.Tag as ZNodeProperties;
                            if (props2 != null && props2.parent_component == oldObj)
                            {
                                props2.parent_component = newObj;
                                // oldObj can also be the Owner of its grandchildren (in various member lists)
                                // this reference must be updated to newObj 
                                ZComponent grandchild = props2.component as ZComponent;
                                if (grandchild != null && grandchild.Owner == oldObj) grandchild.Owner = newObj;
                            }
                        }*/
                    }
            }

            // oldObj can also be the Owner of its grandchildren (in various member lists)
            // the Owner reference must be updated to newObj in all components 
            foreach(ZComponent comp in ZComponent.App.GetAllComponents())
                if (comp.Owner == oldObj) comp.ReplaceOwner(newObj);

            // oldObj can also be the Owner of ZEvent instances
            // update the Owner reference to newObj
            foreach (ZEvent ev in ZComponent.App.FindEvents(oldObj))
                ev.Owner = newObj;

            // If it is a ZApplication
            if (typeof(ZApplication).IsAssignableFrom(newObj.GetType()))
            {
                // Check named references in CustomGame                
                foreach(FieldInfo fi in newObj.GetType().GetFields(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
                {
                    // If the named reference is null, then try to find the component
                    // This is necessary for all newly-added or renamed components
                    if (fi.GetValue(newObj) == null)                       
                    {
                        ZComponent comp = ZComponent.App.Find(fi.Name);
                        if (comp != null && fi.FieldType == comp.GetType())
                        {
                            Console.WriteLine("Setting new named reference {0} / {1}", fi.Name, fi.FieldType.Name);
                            fi.SetValue(newObj, comp);
                        }                        
                    } 
                }               
            }

            // If the oldObj was selected in the editor, then we have to replace it with newObj 
            if (editor.SelectedComponent == oldObj)
            {
                editor.SelectedComponent = newObj;
                //Console.WriteLine("SelectedComponent changed to {0}", newObj.GetType().AssemblyQualifiedName);
            }                       
        }
예제 #2
0
        public void AddNewComponent(ZComponent comp)
        {
            Type type = comp.GetType();
            // Do NOT register ZApplication and its derived classes
            if (typeof(ZApplication).IsAssignableFrom(type)) return;
            allComponents.Add(comp);
            // Store the name in the name cache
            if (comp.HasName()) nameCache[comp.Name] = comp;

            // TODO: consider all ancestor types
            if (!typeMap.ContainsKey(type))
                typeMap[type] = new HashSet<ZComponent>();            
             typeMap[type].Add(comp);
        }
예제 #3
0
        public void RemoveComponent(ZComponent comp)
        {
            Type type = comp.GetType();
            // Do NOT register ZApplication and its derived classes
            if (typeof(ZApplication).IsAssignableFrom(type)) return;
            allComponents.Remove(comp);
            //if (comp.HasName()) nameCache.Remove(comp.Name);
            // Remove the component from the nameMap - if necessary
            foreach (var item in nameCache.Where(kvp => kvp.Value == comp).ToList())
            {
                nameCache.Remove(item.Key);
            }

            // TODO: consider all ancestor types
            if (typeMap.ContainsKey(type))
            {
                typeMap[type].Remove(comp);
                if (typeMap[type].Count == 0)
                    typeMap.Remove(type);
            }
        }
예제 #4
0
        private void AddElementToTree(ZComponent component, TreeNodeCollection nodes)
        {
            //  Add the element.
            TreeNode newNode = new TreeNode()
            {
                Tag = component
            };
            newNode.Text = component.GetType().Name;
            if (component.HasName())
                newNode.Text = newNode.Text + ": " + component.Name;
            else
                newNode.Text += " (No name)";
            nodes.Add(newNode);

            //  Add each child.
            //if (component.GetType() == typeof(Model))
            foreach (var element in component.Children)
                AddElementToTree(element, newNode.Nodes);
        }
예제 #5
0
        private static void ProcessNode(ZComponent parent, IList parent_list, TreeNodeCollection parent_nodes, XmlNode xmlNode)
        {
            if (xmlNode == null) return;
            //Console.WriteLine("Processing: {0}", xmlNode.Name);

            ZComponent comp = parent;
            IList list = null;
            if (xmlNode.Name == "ZApplication")
            {
                SetFields(comp, xmlNode);
            }
            else
            {
                // Check if this node is a List property of the parent
                FieldInfo fi = parent.GetType().GetField(xmlNode.Name, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
                //if (pi != null) Console.WriteLine(" Parent property found: {0}", pi.PropertyType.Name);
                if (parent is ZComponent && fi != null && typeof(IList).IsAssignableFrom(fi.FieldType))
                {
                    //Console.WriteLine("List found: {0}", xmlNode.Name);
                    list = (IList) fi.GetValue(parent);
                }
                // Check if this node is a ZCode property of the parent
                else if (parent is ZComponent && fi != null && typeof(CodeLike).IsAssignableFrom(fi.FieldType))
                {
                    CodeLike code = (CodeLike) fi.GetValue(parent); // Activator.CreateInstance(fi.FieldType);
                    code.Text = xmlNode.InnerText;
                    //code.Owner = parent;
                    Console.WriteLine("Code Text:\n{0}", code.Text);
                    fi.SetValue(comp, code);
                    //ZComponent.App.AddComponent(code);
                    return; //no TreeNode should be created for this
                }
                else
                {
                    comp = CreateComponent(xmlNode.Name, xmlNode, parent, parent_list);
                    if (comp == null)
                    {
                        Console.WriteLine("SKIPPING subtree - Cannot find type: {0}", xmlNode.Name);
                        return;
                    }                    
                }
            }

            TreeNode treeNode = null;
            if (parent_nodes != null)
            {
                string displayName = xmlNode.Name;
                XmlAttribute attribute = xmlNode.Attributes["Name"];
                if (attribute != null)
                    displayName = displayName + " - " + attribute.Value;
            
                treeNode = new TreeNode(displayName);
                parent_nodes.Add(treeNode);

                // clear subtree
                if (treeNode != null) treeNode.Nodes.Clear();
            }

            
            // recursively build SubTree
            foreach (XmlNode childNode in xmlNode.ChildNodes)
            {
                if (childNode.NodeType == XmlNodeType.Element)
                {                   
                    if (treeNode != null)
                        ProcessNode(comp, list, treeNode.Nodes, childNode);
                    else
                        ProcessNode(comp, list, null, childNode);
                }
            }
            // construct ZNodeProperties object for the TreeNode and assign it to Tag property            
            object target = (object) list ?? (object) comp;
            object parentObj = (object) parent_list ?? (object) parent;
            ZNodeProperties props = new ZNodeProperties(target, parentObj, xmlNode, treeNode);
            if (list == null) comp.Tag = props;

            if (_treeView != null)
            {
                treeNode.Tag = props;
                ZTreeView.HighlightTreeNode(treeNode, props);
                //props.XmlNodePropertyChanged += new XmlNodePropertyChangedEventHandler(_treeView.UpdateNodeText);
            }
        }
예제 #6
0
 private static void SetFields(ZComponent comp, XmlNode xmlNode)
 {
     Type type = comp.GetType();
     // Add attributes to the properties
     if (xmlNode.Attributes != null)
     {
         foreach (XmlAttribute attribute in xmlNode.Attributes)
         {
             string val = attribute.Value;
             FieldInfo fi = type.GetField(attribute.Name, BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
             if (fi != null)
             {
                 //Console.WriteLine(" Field found: {0}", attribute.Name);
                 
                 object obj = Deserialize(val, fi.FieldType);
                 if (obj != null)
                     fi.SetValue(comp, obj);
                 /*else if (typeof(ZCode).IsAssignableFrom(fi.FieldType))  //CODE CANNOT BE STORED AS A PROPERTY
                 {
                     ZCode code = (ZCode)Activator.CreateInstance(fi.FieldType);
                     code.Text = val;
                     code.Owner = comp;
                     //Console.WriteLine("Code Text:\n{0}", code.Text);
                     fi.SetValue(comp, code);
                     //ZComponent.App.AddComponent(code);
                 }*/
                 else if (fi.FieldType.IsSubclassOf(typeof(ZComponent)))
                 {
                     _unresolved.Add(new Unresolved { comp = comp, prop = fi, value = val });
                 }
                 else
                     Console.WriteLine(" Unsupported field: {0}-{1}", attribute.Name, val);
             }
             else
                 Console.WriteLine(" Field not found: {0}-{1}", attribute.Name, val);
             //properties.Add(new CustomProperty(attribute.Name, attribute.Value, typeof(string), false, true));
         }
     }
 }
예제 #7
0
        private int ProcessNode(ZComponent parent, IList parent_list, int next_index, TreeNodeCollection parent_nodes, XmlNode xmlNode)
        {
            //if (xmlNode == null) return;
            //Console.WriteLine("Processing: {0}", xmlNode.Name);

            ZComponent comp = parent;
            IList list = null;
            if (xmlNode.Name == "ZApplication")
            {
                //SetFields(comp, xmlNode);                
            }
            else
            {
                // Check if this node is a List property of the parent
                FieldInfo fi = CodeGenerator.GetField(parent.GetType(), xmlNode.Name);
                //if (pi != null) Console.WriteLine(" Parent property found: {0}", pi.PropertyType.Name);
                if (fi != null && typeof(IList).IsAssignableFrom(fi.FieldType))
                {
                    //Console.WriteLine("List found: {0}", xmlNode.Name);
                    list = (IList) fi.GetValue(parent);
                }
                    // Check if this node is an event of the parent
                else if (fi != null && typeof(Delegate).IsAssignableFrom(fi.FieldType))
                {
                    return next_index; //no TreeNode was created for this event
                }
                // Check if this node is a ZCode property of the parent
                else if (fi != null && typeof(CodeLike).IsAssignableFrom(fi.FieldType))
                {
                    return next_index; //no TreeNode was created for this CodeLike component
                }
                else
                {
                    // Find the component in the list or among the children
                    comp = null;
                    IList findList = (IList) parent.Children;
                    if (parent_list != null) findList = parent_list; // parent_list has the priority

                    for (int index = next_index; index < findList.Count; index++)
                    {
                        ZComponent candidate = findList[index] as ZComponent;
                        if (IsCompatibleType(candidate, xmlNode))
                        {
                            comp = candidate;
                            next_index = index + 1;
                            break;
                        }
                    }

                    if (comp == null)
                    {
                        Console.WriteLine("SKIPPING subtree - Cannot find matching component: {0}", xmlNode.Name);
                        return next_index;
                    }
                }
            }

            TreeNode treeNode = null;
            if (parent_nodes != null)
            {
                string displayName = xmlNode.Name;
                XmlAttribute attribute = xmlNode.Attributes["Name"];
                if (attribute != null)
                    displayName = displayName + " - " + attribute.Value;

                treeNode = new TreeNode(displayName);
                parent_nodes.Add(treeNode);

                // clear subtree
                if (treeNode != null) treeNode.Nodes.Clear();
            }

            // recursively build SubTree
            int i = 0;
            foreach (XmlNode childNode in xmlNode.ChildNodes)
            {
                if (childNode.NodeType == XmlNodeType.Element)
                {
                    i = ProcessNode(comp, list, i, treeNode.Nodes, childNode);
                }
            }
            // construct ZNodeProperties object for the TreeNode and assign it to Tag property
            object target = (object) list ?? (object) comp;
            object parentObj = (object) parent_list ?? (object) parent;
            ZNodeProperties props = new ZNodeProperties(target, parentObj, xmlNode, treeNode);
            if (list == null) comp.Tag = props;

            if (treeView != null)
            {
                treeNode.Tag = props;
                ZTreeView.HighlightTreeNode(treeNode, props);
                //props.XmlNodePropertyChanged += new XmlNodePropertyChangedEventHandler(treeView.UpdateNodeText);
            }
            return next_index;
        }
예제 #8
0
 public bool IsCompatibleType(ZComponent comp, XmlNode xmlNode)
 {
     Type type = comp.GetType();
     if (type.Name == xmlNode.Name) return true;
     if (xmlNode.Name == "Model" || xmlNode.Name == "GameObject")
     {
         if (typeof(Model).IsAssignableFrom(type)) return true;
     }
     return false;
 }