ecere/containers/Array: Implemented faster deserialization
[sdk] / ecere / src / com / containers / Array.ec
index 2aac35a..5079f7d 100644 (file)
@@ -1,8 +1,15 @@
 namespace com;
 
+import "instance"
 import "Container"
 
-#define Tsize ((class(T).type == noHeadClass || class(T).type == normalClass) ? sizeof(void *) : class(T).typeSize)
+#ifdef _DEBUG
+// #define MEMTRACKING
+#endif
+
+default:
+extern int __ecereVMethodID_class_OnUnserialize;
+private:
 
 public class Array : Container
 {
@@ -18,6 +25,22 @@ public:
       delete array;
    }
 
+   void OnUnserialize(IOChannel channel)
+   {
+      Array array = eInstance_New(_class.fullName);
+      uint count, c;
+      Class Dclass = class(D);
+      channel.Get(count);
+      //printf("%d %ss\n", count, Dclass.name);
+      if(count > 10000)
+         printf("Bug");
+      array.size = count;
+      for(c = 0; c < count; c++)
+         ((void (*)(void *, void *, void *))(void *)Dclass._vTbl[__ecereVMethodID_class_OnUnserialize])
+            (Dclass, ((byte *)array.array) + Dclass.typeSize * c, channel);
+      this = array;
+   }
+
    // Generic iterator support
    IteratorPointer GetFirst() { return (IteratorPointer)array; }
    IteratorPointer GetLast() { return (IteratorPointer)(array ? (array + (count - 1)) : null); }
@@ -42,13 +65,14 @@ public:
       *item = value;
       return true;
    }
-   IteratorPointer GetAtPosition(const I pos, bool create)
+   IteratorPointer GetAtPosition(const I pos, bool create, bool * justAdded)
    {
       if((int)pos > count && create)
       {
          if((int)pos + 1 > minAllocSize)
             array = renew array T[(int)pos + 1];
          count = (int)pos + 1;
+         if(justAdded) *justAdded = true;
       }
       return ((int)pos < count && array) ? (IteratorPointer)(array + (int)pos) : null;
    }
@@ -62,7 +86,7 @@ public:
          array = renew array T[count + 1];
          if(after) after = array + offset;
       }
-      memmove(after ? (after + 2) : (array + 1), after ? (after + 1) : array, (count - offset) * Tsize);
+      memmove(after ? (after + 2) : (array + 1), after ? (after + 1) : array, (count - offset) * class(T).typeSize);
       if(after)
          after[1] = value;
       else
@@ -70,7 +94,7 @@ public:
       count++;
       return (IteratorPointer)(after ? (after + 1) : array);
 */
-      uint tsize = Tsize;
+      uint tsize = class(T).typeSize;
       byte * pos = ip ? ((byte *)ip + tsize) : (byte *)array;
       if(count+1 > minAllocSize)
       {
@@ -94,7 +118,7 @@ public:
    void Remove(IteratorPointer ip)
    {
       T * it = (T *)ip;
-      memmove(it, it + 1, (count - (it - array) - 1) * Tsize);
+      memmove(it, it + 1, (count - (it - array) - 1) * class(T).typeSize);
       count--;
       if(count + 1 > minAllocSize)
          array = renew array T[count];
@@ -129,8 +153,27 @@ public:
             if(value > minAllocSize)
                array = renew0 array T[value];
             else if(value > count)
-               memset(array + count, 0, (value - count) * Tsize);
+            {
+               /*
+               void * a = array + count;
+               void * b = (byte *)array + count * class(T).typeSize;
+
+               if(a != b)
+                  printf("Oh");
+               */
+               //memset(array + count, 0, (value - count) * class(T).typeSize);
+               /*if(!strcmp(class(T).name, "TessPrim"))
+                  printf("Memsetting to 0 from %d for %d bytes\n", count * class(T).typeSize, (value - count) * class(T).typeSize);*/
+               memset((byte *)array + count * class(T).typeSize, 0, (value - count) * class(T).typeSize);
+            }
             count = value;
+#if defined(_DEBUG) && !defined(MEMINFO) && defined(MEMTRACKING)
+            if(array)
+            {
+               MemBlock block = (MemBlock)((byte *)array - sizeof(class MemBlock));
+               block._class = class(T);
+            }
+#endif
          }
       }
    }
@@ -159,7 +202,7 @@ public:
       if((source._class == class(BuiltInContainer) && ((struct BuiltInContainer *)source)->type.type != structClass ) ||
          eClass_IsDerived(source._class, class(Array)))
       {
-         memcpy(array, ((Array)source).array, count * Tsize);
+         memcpy(array, ((Array)source).array, count * class(T).typeSize);
       }
       else
       {