void FSlateTextureAtlas::DestroyNodes( FAtlasedTextureSlot* StartNode ) { if (StartNode->Left) { DestroyNodes(StartNode->Left); } if (StartNode->Right) { DestroyNodes(StartNode->Right); } delete StartNode; }
void FSlateTextureAtlas::Empty() { // Remove all nodes DestroyNodes( RootNode ); RootNode = nullptr; STAT(uint32 MemoryBefore = AtlasData.GetAllocatedSize()); // Clear all raw data AtlasData.Empty(); STAT(uint32 MemoryAfter = AtlasData.GetAllocatedSize()); DEC_MEMORY_STAT_BY(STAT_SlateTextureAtlasMemory, MemoryBefore-MemoryAfter); }
// Read a command from the CRS uint8_t ReadCmd(void) { Command Cmd; uint32_t *NewNodeNames; pEdgeArray NewEdges; uint32_t i; pNode NewNode; pEdge NewEdge; pEdge ExistingEdge; uint8_t NodeCount; uint32_t *SPT; // read in the basic command header if (ReadBytes((unsigned char *)&Cmd, sizeof(Command)) != sizeof(Command)) { return(0); } if (Cmd.Action == CMD_SEND_NODES) { // read in the indicated number of Nodes #ifdef PATCHED_1 if ((Cmd.NumElements + NumNodes) > MAX_NODES) { #else if (Cmd.NumElements > MAX_NODES) { #endif ReadNull(sizeof(uint32_t)*Cmd.NumElements); SendErrorResponse(RESP_ERROR_TOO_MANY_NODES); return(0); } if ((NewNodeNames = (uint32_t *)calloc(sizeof(uint32_t)*Cmd.NumElements)) == NULL) { DestroyNodes(); DestroyEdges(); _terminate(1); } if (ReadBytes((unsigned char *)NewNodeNames, sizeof(uint32_t)*Cmd.NumElements) != sizeof(uint32_t)*Cmd.NumElements) { free(NewNodeNames); return(0); } // make sure none of the new node names exist already for (i = 0; i < Cmd.NumElements; i++) { if (FindNode(NewNodeNames[i]) != NULL) { free(NewNodeNames); SendErrorResponse(RESP_ERROR_DUPLICATE_NODE); return(0); } } // Create the new nodes for (i = 0; i < Cmd.NumElements; i++) { // create a new node if ((NewNode = (pNode)calloc(sizeof(Node))) == NULL) { free(NewNodeNames); DestroyNodes(); DestroyEdges(); _terminate(1); } NewNode->Name = NewNodeNames[i]; NewNode->Distance = SIZE_MAX; // Add it to the graph if (!AddNode(NewNode)) { free(NewNodeNames); DestroyNodes(); DestroyEdges(); _terminate(1); } } // done creating new nodes free(NewNodeNames); } else if (Cmd.Action == CMD_SEND_EDGES) { // read in the indicated number of Edges if ((Cmd.NumElements + NumEdges) > MAX_EDGES) { ReadNull(sizeof(EdgeArray)*Cmd.NumElements); SendErrorResponse(RESP_ERROR_TOO_MANY_EDGES); return(0); } if ((NewEdges = (pEdgeArray)calloc(sizeof(EdgeArray)*Cmd.NumElements)) == NULL) { DestroyNodes(); DestroyEdges(); _terminate(1); } if (ReadBytes((unsigned char *)NewEdges, sizeof(EdgeArray)*Cmd.NumElements) != sizeof(EdgeArray)*Cmd.NumElements) { free(NewEdges); return(0); } // Create the new edges for (i = 0; i < Cmd.NumElements; i++) { // create a new Edge if ((NewEdge = (pEdge)calloc(sizeof(Edge))) == NULL) { free(NewEdges); DestroyNodes(); DestroyEdges(); _terminate(1); } // make sure the starting and ending nodes exist if ((NewEdge->NodeA = FindNode(NewEdges[i].NodeA)) == NULL) { SendErrorResponse(RESP_ERROR_INVALID_NODE); free(NewEdge); free(NewEdges); DestroyNodes(); DestroyEdges(); _terminate(1); } if ((NewEdge->NodeZ = FindNode(NewEdges[i].NodeZ)) == NULL) { SendErrorResponse(RESP_ERROR_INVALID_NODE); free(NewEdge); free(NewEdges); DestroyNodes(); DestroyEdges(); _terminate(1); } // offset the weight by a fixed magic_page-based value NewEdge->Weight = NewEdges[i].Weight + rand_page[NumNodes]; // see if one already exists if ((ExistingEdge = FindEdge(NewEdge->NodeA, NewEdge->NodeZ)) != NULL) { if (ExistingEdge->Weight > NewEdge->Weight) { ExistingEdge->Weight = NewEdge->Weight; } // keep the existing edge free(NewEdge); continue; } // Add it to the graph if (!AddEdge(NewEdge)) { free(NewEdge); free(NewEdges); DestroyNodes(); DestroyEdges(); _terminate(1); } } } else if (Cmd.Action == CMD_RUN_SPT) { if ((SPT = FindSpt(Cmd.StartingNode, Cmd.EndingNode, &NodeCount)) == NULL) { // unable to find SPT SendErrorResponse(RESP_ERROR_SPT_FAIL); return(0); } SendResponse(RESP_NODE_SET, NodeCount, SPT); free(SPT); } else { SendErrorResponse(RESP_ERROR_INVALID_CMD); return(0); } return(1); }