/// <summary> /// AddEntityToScriptGuidsPool needs to be called from the RawFrameRender, /// otherwise it crashes, TLS issues I'm guessing /// so that's why we do this nasty workaround... /// </summary> private static void GetAllPickupsOnRawFrameRender(object sender, GraphicsEventArgs e) { Pool *pickupPool = PickupsPoolInstance; EntitiesScriptGuidsPool *entitiesPool = EntitiesScriptGuidsPoolInstance; List <uint> pickups = new List <uint>(); for (uint i = 0; i < pickupPool->size; i++) { if (entitiesPool->IsFull()) { break; } if (pickupPool->IsValid(i)) { IntPtr address = pickupPool->GetAddress(i); if (address != IntPtr.Zero) { pickups.Add(AddEntityToScriptGuidsPool(address)); } } } result = pickups; Game.RawFrameRender -= GetAllPickupsOnRawFrameRender; }
public static void Decon(Pool *self) { #if FDB Verify(self); #endif Mem.Free(self->arr); }
public static void Init(Pool *self, int len) { #if FDB Should.NotNull("self", self); Should.GreaterThanZero("len", len); self->type = Type; #endif self->len = len; byte *arr = self->arr = (byte *)Mem.Malloc(len); self->shift = 0; // sentinel int *head = (int *)arr; head[0] = -1; // sentinelHead.prev = -1; head[1] = HeadSize + TailSize; // sentinelhead.next = HeadSize + TailSize; head[2] = 0; // sentinelHead.size = 0; head[3] = -1; // sentinelTail.size = -1; // to prevent merging // Fdb.Dump(arr, len); // sentinel firstFree sentinel int size = len - HeadSize - TailSize - HeadSize - TailSize - HeadSize; SetFreeMeta((int *)(arr + HeadSize + TailSize), 0, -1, size); // sentinel head = (int *)(arr + len - HeadSize); head[0] = -1; // prev = -1 will prevent merging head[1] = -1; head[2] = 0; PtrLst.Init(&self->dependentLst); #if FDB Verify(self); #endif }
public void Dispose() { cmdQueue.Clear(); esJobList.Clear(); PtrIntDict.Decon(nodeDict); Mem.Free(nodeDict); nodeDict = null; Pool.Decon(spritePool); Mem.Free(spritePool); spritePool = null; PtrLst.Decon(spritePtrLst); Mem.Free(spritePtrLst); spritePtrLst = null; DrawCtx.Dispose(); Debug.Log("Clean up GPC"); }
public static void Free(Pool *self, void *ptr) { #if FDB Verify(self); Should.InRange("ptr", ptr, self->arr, self->arr + self->len); #endif byte *arr = self->arr; // Fdb.Dump(arr, self->len); int *head = (int *)ptr - 3; SetFreeMetaAndInsert(arr, head, head[2]); #if FDB Verify(self); #endif MergeRight(arr, head); #if FDB Verify(self); #endif MergeLeft(arr, head); #if FDB Verify(self); #endif }
public static void Clear(Pool *self) { int len = self->len; byte *arr = self->arr; // sentinel int *head = (int *)arr; head[0] = -1; // sentinelHead.prev = -1; head[1] = HeadSize + TailSize; // sentinelhead.next = HeadSize + TailSize; head[2] = 0; // sentinelHead.size = 0; head[3] = -1; // sentinelTail.size = -1; // to prevent merging // Fdb.Dump(arr, len); // sentinel firstFree sentinel int size = len - HeadSize - TailSize - HeadSize - TailSize - HeadSize; SetFreeMeta((int *)(arr + HeadSize + TailSize), 0, -1, size); // sentinel head = (int *)(arr + len - HeadSize); head[0] = -1; // prev = -1 will prevent merging head[1] = -1; head[2] = 0; }
void OnEnable() { Res.LoadAtlases(10); #if GPC_TEST nodePool = Pool.New(); nodeLst = PtrLst.New(); PtrLst.Push(&nodePool->dependentLst, nodeLst); var sprite = (TpSprite *)Pool.Alloc(nodePool, sizeof(TpSprite)); TpSprite.Init(sprite, Res.GetSpriteMeta(10001)); var container = (Group *)Pool.Alloc(nodePool, sizeof(Group)); Group.Init(container); PtrLst.Push(&nodePool->dependentLst, &container->childLst); PtrLst.Push(nodeLst, sprite); Vec4.Set(sprite->color, 1, 1, 1, 1); Vec2.Set(sprite->scl, .015f, .015f); DrawCtx.Start(); var arr = (TpSprite **)nodeLst->arr; for (int i = 0, len = nodeLst->count; i < len; i += 1) { Node.Draw(arr[i], null, false); } DrawCtx.Finish(); return; #endif gpc = new GpController(Camera.main); for (int i = 0; i < 5; i += 1) { gpc.SetCamAttr(CamAttr.Position, 0f, 0f); gpc.SetCamAttr(CamAttr.Zoom, 5f); gpc.AddImg(1, 10001); gpc.SetImgInteractable(1, (phase, x, y) => Debug.LogFormat("hit img1: phase {0}, x {1}, y {2}", phase, x, y)); gpc.SetImgAttr(1, ImgAttr.Position, 0f, 0f, 0f); gpc.SetImgAttr(1, ImgAttr.Rotation, 0f); gpc.SetImgAttr(1, ImgAttr.Alpha, 1f); gpc.SetImgAttrEased(1, ImgAttr.Scale, 1f, EsType.ElasticOut, 0.01f, 0.01f); gpc.Wait(.5f); gpc.SetImgAttrEased(1, ImgAttr.Tint, 1.5f, EsType.ElasticOut, 1f, 0.5f, 1f); gpc.SetImgAttrEased(1, ImgAttr.Position, 2f, EsType.ElasticOut, 2f, -1f, 0f); gpc.Wait(); gpc.SetImgAttrEased(1, ImgAttr.Tint, 1.5f, EsType.ElasticOut, 1f, 1f, 1f); gpc.SetImgAttrEased(1, ImgAttr.Position, 2f, EsType.ElasticOut, -2f, 2f, 0f); gpc.SetImgAttrEased(1, ImgAttr.Rotation, 1.5f, EsType.ElasticOut, Mathf.PI * 2.5f); gpc.SetCamAttrEased(CamAttr.Zoom, 1.5f, EsType.ElasticOut, 2f); gpc.SetCamAttrEased(CamAttr.Position, 2f, EsType.ElasticOut, -2f, 2f); gpc.Wait(.5f); gpc.AddImg(2, 10001); gpc.SetImgInteractable(2, (phase, x, y) => Debug.LogFormat("hit img2: phase {0}, x {1}, y {2}", phase, x, y)); gpc.SetImgAttr(2, ImgAttr.Position, 0f, 0f, -5f); gpc.SetImgAttr(2, ImgAttr.Rotation, 0f); gpc.SetImgAttr(2, ImgAttr.Scale, 0.1f, 0.1f); gpc.SetImgAttr(2, ImgAttr.Alpha, 1f); gpc.SetImgAttrEased(2, ImgAttr.Scale, 1f, EsType.ElasticOut, 0.006f, 0.006f); gpc.SetImgAttrEased(2, ImgAttr.Position, 4f, EsType.ElasticOut, -2f, 2f, 0f); gpc.SetImgInteractable(1, null); gpc.Wait(); gpc.SetImgId(2, 103); gpc.Wait(); gpc.SetImgAttrEased(1, ImgAttr.Tint, 1f, EsType.ElasticOut, 1.5f, 1.5f, 1.5f); gpc.Wait(); gpc.RmImg(1); gpc.RmImg(2); } Application.targetFrameRate = Screen.currentResolution.refreshRate; #if FDB Fdb.Test(); #endif }
public static void Verify(Pool *self) { Should.NotNull("self", self); Should.TypeEqual("self", self->type, Type); Should.GreaterThanZero("self->len", self->len); Should.Equal("self->HeadSize", HeadSize, 3 * sizeof(int)); Should.Equal("self->TailSize", TailSize, sizeof(int)); int len = Mem.Verify(self->arr); Should.Equal("self->len", self->len, len); // Fdb.Dump(self->arr, len); byte *arr = self->arr; int * head; head = (int *)(arr + self->len - HeadSize); Should.Equal("endHead->prev", head[0], -1); // head.prev = -1 Should.Equal("endHead->next", head[1], -1); // head.next = -1 Should.Equal("endHead->size", head[2], 0); // head.size = 0 head = (int *)arr; Should.Equal("firstHead->prev", head[0], -1); // head.prev = -1 Should.Equal("firstHead->size", head[2], 0); // head.size = 0 Should.Equal("firstTail->size", head[3], -1); // tail.size = -1 int curFree = head[1], lastFree = 0; var dict = new System.Collections.Generic.Dictionary <int, int>(); while (curFree != -1) { head = (int *)(arr + curFree); Should.Equal("head" + curFree + "->prev", head[0], lastFree); Should.Equal("tail->size", *(int *)((byte *)head + HeadSize + head[2]), head[2]); dict.Add(curFree, head[2]); lastFree = curFree; curFree = head[1]; } head = (int *)(arr + HeadSize + TailSize); int *end = (int *)(arr + self->len); while (head < end) { int pos = (int)((byte *)head - self->arr); int prev = head[0], next = head[1], size = head[2]; int *tail = (int *)((byte *)head + HeadSize + size); if (tail < end) { int tailVal = tail[0]; if (tailVal == -1) // in use { Should.False("dict.ContainsKey(pos)", dict.ContainsKey(pos)); Should.Equal("prev", prev, -1); Should.Equal("next", next, -1); Should.GreaterThanZero("size", size); } else // free { Should.True("dict.ContainsKey(pos)" + pos, dict.ContainsKey(pos)); Should.GreaterThanOrEqualTo("prev", prev, 0); Should.GreaterThanOrEqualTo("next", next, -1); Should.Equal("size", size, dict[pos]); dict.Remove(pos); } } else // head is end sentinel, no tail { Should.Equal("head", head, (int *)(arr + len - HeadSize)); Should.Equal("endHead->prev", head[0], -1); // head.prev = -1 Should.Equal("endHead->next", head[1], -1); // head.next = -1 Should.Equal("endHead->size", head[2], 0); // head.size = 0 } head = (int *)((byte *)head + HeadSize + size + TailSize); } Should.Zero("dict.Count", dict.Count); }
public static void Init(Pool *self) { Init(self, 64); }
public static void *Alloc(Pool *self, int size) { if ((size & 0x3) != 0) // align to 4 { size = (((size >> 2) + 1) << 2); } #if FDB Verify(self); Should.GreaterThanZero("size", size); #endif byte *arr = self->arr; int *head; int *freeHead; int freeSize; int curFree = 0; while (curFree != -1) // foreach free block { head = (int *)(arr + curFree); int blockSize = head[2]; if (blockSize >= size) // found a block that can fit // | head | data... | tail | // | blockSize | // | head | data... | tail | freeHead | data... | tail | // | size | | freeSize | { freeSize = blockSize - size - TailSize - HeadSize; if (freeSize > 0) // split { freeHead = (int *)((byte *)head + HeadSize + size + TailSize); SetFreeMetaAndInsert(arr, freeHead, freeSize); MergeRight(arr, freeHead); RemoveFromFreeList(arr, head); SetUsedMeta(head, size); } else { RemoveFromFreeList(arr, head); SetUsedMeta(head, blockSize); } #if FDB Verify(self); #endif return(head + 3); } curFree = head[1]; } // expand and split // | data... | endHead | // | data... | freeHead | data... | freeTail | head | data... | tail | endHead | // | len | // | oldLen | freeSize | | size | int oldLen = self->len, len = oldLen, minLen = oldLen + HeadSize + size + TailSize + HeadSize + TailSize; while (len < minLen) { len <<= 1; } self->len = len; // Fdb.Log("{0:X}", (long)arr); // Fdb.Log("len: {0}", Mem.Verify(arr)); byte *oldArr = arr; arr = self->arr = (byte *)Mem.Realloc(arr, len); long shift = self->shift = arr - oldArr; if (shift != 0) { var dependentLst = &self->dependentLst; void **dependentArr = dependentLst->arr; for (int i = 0, dependentLen = dependentLst->count; i < dependentLen; i += 1) { PtrCollection.ShiftBase(dependentArr[i], shift); } } // Fdb.Log("{0:X}", (long)arr); // Fdb.Log("len: {0}", Mem.Verify(self->arr)); freeHead = (int *)(arr + oldLen - HeadSize); freeSize = len - oldLen - TailSize - HeadSize - size - TailSize - HeadSize; SetFreeMetaAndInsert(arr, freeHead, freeSize); // Fdb.Dump(arr, len); MergeLeft(arr, freeHead); int *endHead = (int *)(arr + len - HeadSize); endHead[0] = -1; endHead[1] = -1; endHead[2] = 0; head = (int *)((byte *)freeHead + HeadSize + freeSize + TailSize); SetUsedMeta(head, size); #if FDB Verify(self); #endif return(head + 3); }