//=-------------------------------------------------------------------------=// // Arrows management module // // // // Copyright © 2021 Libre en Communs (contact@a-lec.org) // // Copyright © 2021 Adrien Bourmault (neox@a-lec.org) // // // // This file is part of gem-graph. // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU Affero General Public License as // // published by the Free Software Foundation, either version 3 of the // // License, or (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU Affero General Public License for more details. // // // // You should have received a copy of the GNU Affero General Public License // // along with this program. If not, see . // //=-------------------------------------------------------------------------=// #include "../include/base.h" #include "../include/arrows.h" /* -------------------------------------------------------------------------- */ static inline int location(Space_t *space, int x, int y, int z) { return x + y * (space->xMax+1) + z * (space->xMax+1) * (space->zMax+1); } Arrow_t *ArrowAdd(Scheduler_t *scheduler, int x, int y, int z, int siteId, int weight) { ArrowArray_t *arrowArray = scheduler->arrowArray; Space_t *drawingSpace = scheduler->globalDrawingSpace; Site_t *currentSite = &drawingSpace->space[ location(drawingSpace, x, y, z) ].sites[siteId]; Arrow_t *curArrow; // Check if there is a free slot to store the a new arrow if (arrowArray->freeSlotCount == 0) { // Realloc array to create free slot arrowArray->array = realloc(arrowArray->array, arrowArray->size + 1); curArrow = &arrowArray->array[arrowArray->size + 1]; arrowArray->size++; } else { // Reuse an unused free slot curArrow = arrowArray->freeSlots[0]; // Delete the free slot reference (it's our *PROPERTY* now !) if (!(memmove(&arrowArray->freeSlots[0], &arrowArray->freeSlots[0] + sizeof(arrowArray->freeSlots[0]), arrowArray->freeSlotCount - 1 ))) return NULL; arrowArray->freeSlotCount--; } // Assign values to the new arrow curArrow->x = x; curArrow->y = y; curArrow->z = z; curArrow->siteId = siteId; // Store a reference of this new arrow in space (to find it quickly later) currentSite->arrowsPtr = curArrow; currentSite->nArrow++; return curArrow; } bool ArrowRemove(Scheduler_t *scheduler, int x, int y, int z, int siteId, int weight) { ArrowArray_t *arrowArray = scheduler->arrowArray; Space_t *drawingSpace = scheduler->globalDrawingSpace; Site_t *currentSite = &drawingSpace->space[ location(drawingSpace, x, y, z) ].sites[siteId]; Arrow_t *curArrow; // Look for a corresponding arrow in that site if (currentSite->nArrow) { // Get an arrow from space unit at siteId curArrow = currentSite->arrowsPtr; // Mark arrow for deletion arrowArray->freeSlots = realloc(arrowArray->freeSlots, arrowArray->freeSlotCount + 1); if (!arrowArray->freeSlots) return false; arrowArray->freeSlots[arrowArray->freeSlotCount] = curArrow; arrowArray->freeSlotCount++; currentSite->arrowsPtr = NULL; currentSite->nArrow--; } return false; }