Member Controls

Developers > Help needed: just getting to grips with how SimPe works
pljonesLink to postposted: Sun Apr 03, 2005 6:30 pm

Member since:
 2005-04-02
Posts:
 616
While I'm resyncing with CVS (after installing that styles library), I thought I'd post what I've been hacking at for the last couple of days.

I'm new to C#, so this is my first ever attempt at writing new code in it. It's a lot more like C than Java is, which helped. I grabbed the first bit of the program that interested me and decided to see what I could do with it just to get a feel for both the language and for how SimPe works.

This replaces the experimental sort with a different algorithm.

I've got a problem. Even though the BHAV is displayed correctly after sorting, saving and then reloading the package reveals I've not updated the underlying data correctly. Any pointers to what I've not understood would be helpful as I expect the same issues arise throughout the application.

(The patch applies cleanly against current CVS HEAD, I just checked.)
Index: SimPe BHAV/PackedFileForm.cs
===================================================================
RCS file: /cvsroot/simpe/fullsimpe/SimPe BHAV/PackedFileForm.cs,v
retrieving revision 1.2
diff -u -r1.2 PackedFileForm.cs
--- SimPe BHAV/PackedFileForm.cs 24 Mar 2005 02:29:05 -0000 1.2
+++ SimPe BHAV/PackedFileForm.cs 3 Apr 2005 16:13:56 -0000
@@ -31,6 +31,7 @@
  /// </summary>
  public class BhavForm : System.Windows.Forms.Form
  {
+ #region Form variables
  internal System.Windows.Forms.Panel wrapperPanel;
  private System.Windows.Forms.Panel panel3;
  private System.Windows.Forms.Label label1;
@@ -206,7 +207,8 @@
  private System.Windows.Forms.Label label45;
  internal System.Windows.Forms.TextBox tbmv;
  private System.ComponentModel.IContainer components;
-
+ #endregion
+        
  public BhavForm()
  {
  //
@@ -5215,7 +5217,6 @@
  cb.Text = "0x"+Helper.HexString((ushort)sel);
  }
 
-
  private void ItemMouseMove(object sender, MouseEventArgs e)
  {
  if (e.Button == MouseButtons.Left) 
@@ -5359,7 +5360,6 @@
  ShowActivePanel();
  }
 
-
  protected void DrawConnectors()
  {
  try 
@@ -5545,6 +5545,7 @@
  }
  }
 
+#if QUAXI
  private void SortInstructions(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
  {
  ushort last = 0;
@@ -5588,6 +5589,202 @@
  CreateFlowPanel(InstructionItem.Instructions(flowitems));
  wrapper.Changed = true;
  }
+#endif
+
+ internal class treeNode 
+ {
+ public treeNode(treeNode p, Instruction i)
+ {
+ instruction = i;
+ parent = p;
+ TrueChild = null;
+ FalseChild = null;
+ }
+ public Instruction instruction;
+ public treeNode parent;
+ private bool refTrueTarget;
+ private bool refFalseTarget;
+ private treeNode trueChild;
+ public treeNode TrueChild 
+ {
+ get 
+ {
+ if (refTrueTarget) return null;
+ if (instruction.Target1 >= 0xfffc) return null;
+ return trueChild;
+ }
+ set 
+ {
+ trueChild = value;
+ refTrueTarget = (trueChild == null);
+ }
+ }
+ private treeNode falseChild;
+ public treeNode FalseChild 
+ {
+ get 
+ {
+ if (refFalseTarget) return null;
+ if (instruction.Target2 >= 0xfffc) return null;
+ return falseChild;
+ }
+ set 
+ {
+ falseChild = value;
+ refFalseTarget = (falseChild == null);
+ }
+ }
+ protected void removeChild(treeNode child)
+ {
+ if ((trueChild != null) && trueChild.Equals(child))
+ TrueChild = null;
+ if ((falseChild != null) && falseChild.Equals(child))
+ FalseChild = null;
+ child.parent = null;
+ }
+
+ protected treeNode findInTree(treeNode root, ushort target)
+ {
+ if (root == null)
+ return null;
+ if (root.instruction.Index == target)
+ return root;
+ treeNode child;
+ child = findInTree(root.TrueChild, target);
+ if (child != null) return child;
+ child = findInTree(root.FalseChild, target);
+ if (child != null) return child;
+ return null;
+ }
+
+ public void fillTree(treeNode treeRoot, InstructionItem[] flowitems)
+ {
+ if (instruction == null) return;
+
+ if (instruction.Target1 < 0xfffc)
+ {
+ treeNode child = findInTree(treeRoot, instruction.Target1);
+ if (child == null)
+ {
+ TrueChild = new treeNode(this, flowitems[instruction.Target1].instruction);
+ TrueChild.fillTree(treeRoot, flowitems);
+ }
+ else
+ {
+ if (!child.Equals(this) && (child.parent != null)) 
+ {
+ child.parent.removeChild(child);
+ TrueChild = child;
+ TrueChild.parent = this;
+ }
+ }
+ }
+
+ if (instruction.Target2 < 0xfffc)
+ {
+ treeNode child = findInTree(treeRoot, instruction.Target2);
+ if (child == null)
+ {
+ FalseChild = new treeNode(this, flowitems[instruction.Target2].instruction);
+ FalseChild.fillTree(treeRoot, flowitems);
+ }
+ else
+ {
+ if (!child.Equals(this) && (child.parent != null)) 
+ {
+ child.parent.removeChild(child);
+ FalseChild = child;
+ FalseChild.parent = this;
+ }
+ }
+ }
+ }
+ }
+
+ private bool findInstruction(InstructionItem[] tree, ushort last, ushort target, ushort current)
+ {
+ for (ushort i = 0; i <= last; i++)
+ if ((i != current) && (tree[i].index == target))
+ return true;
+ for (ushort i = 0; i <= last; i++)
+ if (i != current) 
+ {
+ if (tree[i].instruction.Target1 == target)
+ return true;
+ if (tree[i].instruction.Target2 == target)
+ return true;
+ }
+ return false;
+ }
+
+ private ushort treeWalk(InstructionItem[] newFlowItems, ushort last, treeNode root)
+ {
+ if (root == null) return last;
+
+ newFlowItems[last] = new InstructionItem();
+ newFlowItems[last].instruction = root.instruction;
+ if (root.TrueChild != null)
+ last = treeWalk(newFlowItems, (ushort)(last+1), root.TrueChild);
+ if (root.FalseChild != null)
+ last = treeWalk(newFlowItems, (ushort)(last+1), root.FalseChild);
+
+ return last;
+ }
+
+ private ushort findItem(InstructionItem[] iis, ushort target)
+ {
+ for(ushort i = 0; i < iis.Length; i++) 
+ if (iis[i].instruction.Index == target) return i;
+ return (ushort)iis.Length;
+ }
+
+ private void SortInstructions(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
+ {
+ treeNode treeRoot = new treeNode(null, flowitems[0].instruction);
+ treeRoot.fillTree(treeRoot, flowitems);
+
+ InstructionItem[] newFlowItems = new InstructionItem[flowitems.Length];
+ ushort last = treeWalk(newFlowItems, 0, treeRoot);
+
+ // That may have missed some entries because they're not used, so...
+ foreach(InstructionItem item in flowitems)
+ {
+ bool found = false;
+ if (item != null)
+ for (ushort j = 0; !found && (j < newFlowItems.Length); j++) 
+ {
+ InstructionItem jtem = newFlowItems[j];
+ if ((jtem != null) && (item.instruction.Equals(jtem.instruction))) found = true;
+ }
+ if (!found) 
+ {
+ last++;
+ newFlowItems[last] = new InstructionItem();
+ newFlowItems[last].instruction = item.instruction;
+ }
+ }
+ // Now, if (last+1) != newFlowItems.Length we have a problem!
+ for(ushort i = 0; i < newFlowItems.Length; i++)
+ {
+ if (newFlowItems[i].instruction.Target1 < 0xfffc)
+ newFlowItems[i].instruction.Target1 = findItem(newFlowItems, newFlowItems[i].instruction.Target1);
+ if (newFlowItems[i].instruction.Target2 < 0xfffc)
+ newFlowItems[i].instruction.Target2 = findItem(newFlowItems, newFlowItems[i].instruction.Target2);
+ Instruction x = newFlowItems[i].instruction;
+ newFlowItems[i] = new InstructionItem();
+ newFlowItems[i].instruction = x;
+ }
+ for(ushort i = 0; i < newFlowItems.Length; i++)
+ {
+ newFlowItems[i].instruction.Index = (ushort)i;
+ newFlowItems[i].index = (ushort)i;
+ }
+ csel = -1;
+ this.llcommit.Enabled = false;
+ this.lldel.Enabled = false;
+ CreateFlowPanel(InstructionItem.Instructions(newFlowItems));
+ wrapper.Changed = true;
+ }
 
  private void OpenOperandWiz(object sender, System.EventArgs e)
  {
quaxiLink to postposted: Sun Apr 03, 2005 6:59 pm
Avator for quaxi

Member since:
 2006-04-28
Posts:
 3154
When you change a PackedFile (like a BHAV), the UserData is only stored in the Memory of the currently active Plugin.

If you want the changed data to be in the pacakge Memory, you have to call the SynchronizeUserData() Method of the wrapper you are working with, or you set the Changed Property of the Wrapper to true (prefered approach).
When this Property is set to true, SimPE will ask the User if he want's to save or discard the changes, when the user is about to cloes the Plugin View and did not press the Commit Button (which is basically calling SynchronizeUserData()).
quaxiLink to postposted: Sun Apr 03, 2005 7:22 pm
Avator for quaxi

Member since:
 2006-04-28
Posts:
 3154
Ah, i think i know the Problem. You are creating new Instances of the InstructionItem class for the newFlowItems Array.

But that Array contains Pointers to the original Instances, which are part of the BHAV Memory.

So if you create new Instances, you also have to tell the BHAV Wrapper that you want to replace the existing Instance, like this:


Bhav wrp = (Bhav)wrapper;   
for (ushort i=0; i<flowitems.Length; i++) wrp.Instructions[i] = flowitems[i].instruction;


But as far as I can see, the Targets are not updated correct.
pljonesLink to postposted: Sun Apr 03, 2005 7:31 pm

Member since:
 2005-04-02
Posts:
 616
Ah, I thought it must be something like that I was missing. I must admit I didn't really look that hard for how the original flowitems got populated!

PackedFileWrapper can have its array of Instruction[]s set directly. Can I use the static Instruction[] Instructions method on InstructionItem to pass the entries straight across (so both arrays are pointing to the same instructions)?

Actually, the instructions should be the same - I didn't think I'd created any. As you say, I create new InstructionItems -- otherwise, I couldn't get the Connector()s to re-initialise correctly -- but they should be refering to the same Instruction objects as the original and as the wrapper...

(I can't update in place like SortSwap does, either, as the algorithm would get confused...)
quaxiLink to postposted: Tue Apr 05, 2005 1:58 pm
Avator for quaxi

Member since:
 2006-04-28
Posts:
 3154
"pljones" wrote:
Can I use the static Instruction[] Instructions method on InstructionItem to pass the entries straight across (so both arrays are pointing to the same instructions)?



Yes
pljonesLink to postposted: Sat Apr 09, 2005 2:26 pm

Member since:
 2005-04-02
Posts:
 616
Okay, two patches against the latest CVS.

The first does the array assignment. (The version in CVS didn't work as the assignment to the Bhav wrapper was from flowitems rather than newFlowItems.) It also moves all my code into the #if-#else-#endif block. I've commented out the "#define QUAXI" at the top of the file in my build but not included that in the patch. This now appears to work.
File attachment - content:
Index: SimPe BHAV/PackedFileForm.cs
===================================================================
RCS file: /cvsroot/simpe/fullsimpe/SimPe BHAV/PackedFileForm.cs,v
retrieving revision 1.3
diff -u -r1.3 PackedFileForm.cs
--- SimPe BHAV/PackedFileForm.cs 7 Apr 2005 17:08:22 -0000 1.3
+++ SimPe BHAV/PackedFileForm.cs 9 Apr 2005 12:15:19 -0000
@@ -5590,8 +5590,8 @@
  CreateFlowPanel(InstructionItem.Instructions(flowitems));
  wrapper.Changed = true;
  }
-#endif
 
+#else
       internal class treeNode
       {
          public treeNode(treeNode p, Instruction i)
@@ -5739,8 +5739,6 @@
          return (ushort)iis.Length;
       }
 
-#if QUAXI
-#else
       private void SortInstructions(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
       {
   
@@ -5786,13 +5784,12 @@
             newFlowItems[i].index = (ushort)i;
          }
 
-  Bhav wrp = (Bhav)wrapper;   
-  for (ushort i=0; i<flowitems.Length; i++) wrp.Instructions[i] = flowitems[i].instruction;
 
          csel = -1;
          this.llcommit.Enabled = false;
          this.lldel.Enabled = false;
          CreateFlowPanel(InstructionItem.Instructions(newFlowItems));
+  ((Bhav)wrapper).Instructions = InstructionItem.Instructions(newFlowItems);
          wrapper.Changed = true;  
       }
 #endif


The second fixes up a typo "exerimental" should be "experimental".
File attachment - content:
Index: SimPe BHAV/PackedFileForm.resx
===================================================================
RCS file: /cvsroot/simpe/fullsimpe/SimPe BHAV/PackedFileForm.resx,v
retrieving revision 1.2
diff -u -r1.2 PackedFileForm.resx
--- SimPe BHAV/PackedFileForm.resx 24 Mar 2005 02:29:04 -0000 1.2
+++ SimPe BHAV/PackedFileForm.resx 9 Apr 2005 12:11:28 -0000
@@ -1109,7 +1109,7 @@
     <value />
   </data>
   <data name="llsort.Text">
-    <value>exerimental sort</value>
+    <value>experimental sort</value>
   </data>
   <data name="cbunk2.AccessibleName" type="System.Resources.ResXNullRef, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value />
@@ -4334,7 +4334,7 @@
     <value />
   </data>
   <data name="llsort.LinkArea" type="System.Windows.Forms.LinkArea, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
-    <value>12, 4</value>
+    <value>13, 4</value>
   </data>
   <data name="tbdelta.AutoSize" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
     <value>True</value>
Index: SimPe BHAV New/Bhav2Form.cs
===================================================================
RCS file: /cvsroot/simpe/fullsimpe/SimPe BHAV New/Bhav2Form.cs,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Bhav2Form.cs
--- SimPe BHAV New/Bhav2Form.cs 20 Mar 2005 14:53:50 -0000 1.1.1.1
+++ SimPe BHAV New/Bhav2Form.cs 9 Apr 2005 12:11:29 -0000
@@ -194,13 +194,13 @@
  this.llsort.Enabled = false;
  this.llsort.Font = new System.Drawing.Font("Verdana", 8.25F, System.Drawing.FontStyle.Bold);
  this.llsort.ImeMode = System.Windows.Forms.ImeMode.NoControl;
- this.llsort.LinkArea = new System.Windows.Forms.LinkArea(12, 4);
+ this.llsort.LinkArea = new System.Windows.Forms.LinkArea(13, 4);
  this.llsort.Location = new System.Drawing.Point(16, 336);
  this.llsort.Name = "llsort";
  this.llsort.Size = new System.Drawing.Size(110, 17);
  this.llsort.TabIndex = 40;
  this.llsort.TabStop = true;
- this.llsort.Text = "exerimental sort";
+ this.llsort.Text = "experimental sort";
  // 
  // label16
  // 


viewpost, 2858, 0