int fc_solve_PQueuePop( PQUEUE *pq, fcs_state_extra_info_t * * val)
{
    int32 i;
    int32 child;
    pq_element_t * Elements = pq->Elements;
    int32 CurrentSize = pq->CurrentSize;

    pq_element_t pMaxElement;
    pq_element_t pLastElement;

    if( PQueueIsEmpty( pq ) )
    {
        *val = NULL;
        return 1;
    }

    pMaxElement = Elements[PQ_FIRST_ENTRY];

    /* get pointer to last element in tree */
    pLastElement = Elements[ CurrentSize-- ];

    {

        /* code to pop an element from an ascending (top to bottom) pqueue */

        /*  UNTESTED */

        for( i=PQ_FIRST_ENTRY; (child = PQ_LEFT_CHILD_INDEX(i)) <= CurrentSize; i=child )
        {
            /* set child to the smaller of the two children... */

            if( (child != CurrentSize) &&
                (PGetRating(Elements[child + 1]) > PGetRating(Elements[child])) )
            {
                child ++;
            }

            if( PGetRating( pLastElement ) < PGetRating( Elements[ child ] ) )
            {
                Elements[ i ] = Elements[ child ];
            }
            else
            {
                break;
            }
        }
    }

    Elements[i] = pLastElement;
    pq->CurrentSize = CurrentSize;

    *val = pMaxElement.val;
    return 0;
}
Exemple #2
0
static void ip_noise_delayer_check_pq(ip_noise_delayer_t * delayer)
{
    ip_noise_delayer_pq_element_t current_time_pseudo_msg;
#ifndef __KERNEL__
    ip_noise_delayer_pq_element_t * msg;
#else
    ip_noise_delayer_pq_element_t msg;
#endif

#ifndef __KERNEL__
    gettimeofday(&(current_time_pseudo_msg.tv), &tz);
#else
    current_time_pseudo_msg.tv = jiffies;
#endif

    while (!PQueueIsEmpty(&(delayer->pq)))
    {
        /* See if the message should have been sent by now. */
        msg = PQueuePeekMinimum(&(delayer->pq));
#ifndef __KERNEL__
        if (msg == NULL)
#else
        if (msg.tv == 0)
#endif
        {
            break;
        }
        if (ip_noise_timeval_cmp(msg, current_time_pseudo_msg, NULL) <= 0)
        {
            delayer->release_callback(&(msg.m), delayer->release_callback_context);
            PQueuePop(&(delayer->pq));
#ifndef __KERNEL__
            free(msg)
#endif
        }
        else
        {
            break;
Exemple #3
0
/**
 * @brief Tries to find a path from the given actor(-position) to a given target position
 *
 * Unlike Grid_CalcPathing, this function does not neccessarily calculate the TU values for
 * all positions reachable from 'from'. Instead it tries to find the shortest/fastest path to
 * the target position. There is no limit to maxTUs.
 *
 * @param[in] routing Reference to client or server side routing table (clMap, svMap)
 * @param[in] actorSize The size of thing to calc the move for (e.g. size=2 means 2x2).
 * The plan is to have the 'origin' in 2x2 units in the bottom-left (towards the lower coordinates) corner of the 2x2 square.
 * @param[in,out] path Pointer to client or server side pathing table (clMap, svMap)
 * @param[in] from The position to start the calculation from.
 * @param[in] targetPos The position where we want to end up.
 * @param[in] maxTUs The maximum TUs away from 'from' to calculate move-information for
 * @param[in] crouchingState Whether the actor is currently crouching, 1 is yes, 0 is no.
 * @param[in] fb_list Forbidden list (entities are standing at those points)
 * @param[in] fb_length Length of forbidden list
 * @sa G_MoveCalc
 * @sa CL_ConditionalMoveCalc
 */
bool Grid_FindPath (const Routing &routing, const actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, const pos3_t targetPos, byte crouchingState, int maxTUs, byte ** fb_list, int fb_length)
{
	bool found = false;
	int count;
	priorityQueue_t pqueue;
	pos4_t epos; /**< Extended position; includes crouching state */
	pos3_t pos;
	/* this is the position of the current actor- so the actor can stand in the cell it is in when pathfinding */
	pos3_t excludeFromForbiddenList;

	/* Confirm bounds */
	assert((from[2]) < PATHFINDING_HEIGHT);
	assert(crouchingState == 0 || crouchingState == 1);	/* s.a. ACTOR_MAX_STATES */

	/* reset move data */
	OBJSET(path->area,     ROUTING_NOT_REACHABLE);
	OBJSET(path->areaFrom, ROUTING_NOT_REACHABLE);
	path->fblist = fb_list;
	path->fblength = fb_length;

	/* Prepare exclusion of starting-location (i.e. this should be ent-pos or le-pos) in Grid_CheckForbidden */
	VectorCopy(from, excludeFromForbiddenList);
	/* set starting position to 0 TUs.*/
	RT_AREA_POS(path, from, crouchingState) = 0;

	PQueueInitialise(&pqueue, 1024);
	Vector4Set(epos, from[0], from[1], from[2], crouchingState);
	PQueuePush(&pqueue, epos, 0);

	count = 0;
	while (!PQueueIsEmpty(&pqueue)) {
		PQueuePop(&pqueue, epos);
		VectorCopy(epos, pos);
		count++;

		/* if reaching that square already took too many TUs,
		 * don't bother to reach new squares *from* there. */
		const byte usedTUs = RT_AREA_POS(path, pos, crouchingState);
		if (usedTUs >= maxTUs)
			continue;

		for (int dir = 0; dir < PATHFINDING_DIRECTIONS; dir++) {
			Step step(routing, pos, actorSize, crouchingState, dir);
			/* Directions 12, 14, and 15 are currently undefined. */
			if (dir == 12 || dir == 14 || dir == 15)
				continue;
			/* If this is a crouching or crouching move, forget it. */
			if (dir == DIRECTION_STAND_UP || dir == DIRECTION_CROUCH)
				continue;

			if (!step.init())
				continue;		/* either dir is irrelevant or something worse happened */

			if (!step.isPossible(path))
				continue;

			/* Is this a better move into this cell? */
			RT_AREA_TEST_POS(path, step.toPos, step.crouchingState);
			if (RT_AREA_POS(path, step.toPos, step.crouchingState) <= step.TUsAfter) {
				continue;	/* This move is not optimum. */
			}

			/* Test for forbidden (by other entities) areas. */
			/* Do NOT check the forbiddenList. We might find a multi-turn path. */
#if 0
			if (Grid_CheckForbidden(excludeFromForbiddenList, step.actorSize, path, step.toPos[0], step.toPos[1], step.toPos[2])) {
				continue;		/* That spot is occupied. */
			}
#endif

			/* Store move in pathing table. */
			Grid_SetMoveData(path, step.toPos, step.crouchingState, step.TUsAfter, step.dir, step.fromPos[2]);

			pos4_t dummy;
			const int dist = step.TUsAfter + (int) (2 * VectorDist(step.toPos, targetPos));
			Vector4Set(dummy, step.toPos[0], step.toPos[1], step.toPos[2], step.crouchingState);
			PQueuePush(&pqueue, dummy, dist);

			if (VectorEqual(step.toPos, targetPos)) {
				found = true;
				break;
			}
		}
		if (found)
			break;
	}
	/* Com_Printf("Loop: %i", count); */
	PQueueFree(&pqueue);
	return found;
}
Exemple #4
0
/**
 * @brief Recalculate the pathing table for the given actor(-position)
 *
 * We calculate the table for ALL possible movement states (atm stand and crouch)
 * to be able to propose smart things like autostand.
 * @param[in] routing Reference to client or server side routing table (clMap, svMap)
 * @param[in] actorSize The size of thing to calc the move for (e.g. size=2 means 2x2).
 * The plan is to have the 'origin' in 2x2 units in the bottom-left (towards the lower coordinates) corner of the 2x2 square.
 * @param[in,out] path Pointer to client or server side pathing table (clMap, svMap)
 * @param[in] from The position to start the calculation from.
 * @param[in] maxTUs The maximum TUs away from 'from' to calculate move-information for
 * @param[in] fb_list Forbidden list (entities are standing at those points)
 * @param[in] fb_length Length of forbidden list
 * @sa G_MoveCalc
 * @sa CL_ConditionalMoveCalc
 */
void Grid_CalcPathing (const Routing &routing, const actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, int maxTUs, byte ** fb_list, int fb_length)
{
	priorityQueue_t pqueue;
	pos4_t epos; /**< Extended position; includes crouching state */
	pos3_t pos;
	int amst; /* acronym for actor movement state */
	/* this is the position of the current actor- so the actor can stand in the cell it is in when pathfinding */
	pos3_t excludeFromForbiddenList;

	/* Confirm bounds */
	assert((from[2]) < PATHFINDING_HEIGHT);

	/* reset move data */
	OBJSET(path->area,     ROUTING_NOT_REACHABLE);
	OBJSET(path->areaFrom, ROUTING_NOT_REACHABLE);
	path->fblist = fb_list;
	path->fblength = fb_length;

	maxTUs = std::min(maxTUs, MAX_ROUTE_TUS);

	/* Prepare exclusion of starting-location (i.e. this should be ent-pos or le-pos) in Grid_CheckForbidden */
	VectorCopy(from, excludeFromForbiddenList);

	for (amst = 0; amst < ACTOR_MAX_STATES; amst++) {
		/* set starting position to 0 TUs.*/
		RT_AREA_POS(path, from, amst) = 0;

		PQueueInitialise(&pqueue, 1024);
		Vector4Set(epos, from[0], from[1], from[2], amst);
		PQueuePush(&pqueue, epos, 0);

		int count = 0;
		while (!PQueueIsEmpty(&pqueue)) {
			int dir;
			PQueuePop(&pqueue, epos);
			VectorCopy(epos, pos);
			count++;

			/* if reaching that square already took too many TUs,
			 * don't bother to reach new squares *from* there. */
			const byte usedTUs = RT_AREA_POS(path, pos, amst);
			if (usedTUs >= maxTUs)
				continue;

			for (dir = 0; dir < PATHFINDING_DIRECTIONS; ++dir) {
				Step step(routing, pos, actorSize, amst, dir);
				/* Directions 12, 14, and 15 are currently undefined. */
				if (dir == 12 || dir == 14 || dir == 15)
					continue;
				/* If this is a crouching or crouching move, forget it. */
				if (dir == DIRECTION_STAND_UP || dir == DIRECTION_CROUCH)
					continue;

				if (!step.init())
					continue; /* either dir is irrelevant or something worse happened */

				if (step.isPossible(path)) {
					/* Is this a better move into this cell? */
					RT_AREA_TEST_POS(path, step.toPos, step.crouchingState);
					if (RT_AREA_POS(path, step.toPos, step.crouchingState) <= step.TUsAfter) {
						continue; /* This move is not optimum. */
					}

					/* Test for forbidden (by other entities) areas. */
					if (Grid_CheckForbidden(excludeFromForbiddenList, step.actorSize, path, step.toPos[0],
							step.toPos[1], step.toPos[2])) {
						continue; /* That spot is occupied. */
					}

					/* Store move in pathing table. */
					Grid_SetMoveData(path, step.toPos, step.crouchingState, step.TUsAfter, step.dir, step.fromPos[2]);

					pos4_t dummy;
					Vector4Set(dummy, step.toPos[0], step.toPos[1], step.toPos[2], step.crouchingState);
					PQueuePush(&pqueue, dummy, step.TUsAfter);
				}
			}
		}
		/* Com_Printf("Loop: %i", count); */
		PQueueFree(&pqueue);
	}
}
Exemple #5
0
/**
 * @brief Recalculate the pathing table for the given actor(-position)
 * @param[in] map Pointer to client or server side routing table (clMap, svMap)
 * @param[in] actorSize The size of thing to calc the move for (e.g. size=2 means 2x2).
 * The plan is to have the 'origin' in 2x2 units in the bottom-left (towards the lower coordinates) corner of the 2x2 square.
 * @param[in,out] path Pointer to client or server side pathing table (clMap, svMap)
 * @param[in] from The position to start the calculation from.
 * @param[in] distance The maximum TUs away from 'from' to calculate move-information for
 * @param[in] crouchingState Whether the actor is currently crouching, 1 is yes, 0 is no.
 * @param[in] fb_list Forbidden list (entities are standing at those points)
 * @param[in] fb_length Length of forbidden list
 * @sa Grid_MoveMark
 * @sa G_MoveCalc
 * @sa CL_ConditionalMoveCalc
 */
void Grid_MoveCalc (const routing_t *map, const actorSizeEnum_t actorSize, pathing_t *path, const pos3_t from, byte crouchingState, int distance, byte ** fb_list, int fb_length)
{
	int dir;
	int count;
	priorityQueue_t pqueue;
	pos4_t epos; /**< Extended position; includes crouching state */
	pos3_t pos;
	/* this is the position of the current actor- so the actor can stand in the cell it is in when pathfinding */
	pos3_t excludeFromForbiddenList;

	/* reset move data */
	OBJSET(path->area,     ROUTING_NOT_REACHABLE);
	OBJSET(path->areaFrom, ROUTING_NOT_REACHABLE);
	path->fblist = fb_list;
	path->fblength = fb_length;

	if (distance > MAX_ROUTE + 3)	/* +3 is added to calc at least one square (diagonal) more */
		distance = MAX_ROUTE + 3;	/* and later show one step beyond the walkable path in red */

	/* Prepare exclusion of starting-location (i.e. this should be ent-pos or le-pos) in Grid_CheckForbidden */
	VectorCopy(from, excludeFromForbiddenList);

	PQueueInitialise(&pqueue, 1024);
	Vector4Set(epos, from[0], from[1], from[2], crouchingState);
	PQueuePush(&pqueue, epos, 0);

	/* Confirm bounds */
	assert((from[2]) < PATHFINDING_HEIGHT);
	assert(crouchingState == 0 || crouchingState == 1);	/* s.a. ACTOR_MAX_STATES */

	/* set starting position to 0 TUs.*/
	RT_AREA_POS(path, from, crouchingState) = 0;

	Com_DPrintf(DEBUG_PATHING, "Grid_MoveCalc: Start at (%i %i %i) c:%i\n", from[0], from[1], from[2], crouchingState);

	count = 0;
	while (!PQueueIsEmpty(&pqueue)) {
		byte TUsSoFar;
		PQueuePop(&pqueue, epos);
		VectorCopy(epos, pos);
		count++;

		/**< if reaching that square already took too many TUs,
		 * don't bother to reach new squares *from* there. */
		TUsSoFar = RT_AREA_POS(path, pos, crouchingState);
		if (TUsSoFar >= distance || TUsSoFar >= MAX_MOVELENGTH)
			continue;

		for (dir = 0; dir < PATHFINDING_DIRECTIONS; dir++) {
			/* Directions 12, 14, and 15 are currently undefined. */
			if (dir == 12 || dir == 14 || dir == 15)
				continue;
			/* If this is a crouching or crouching move, forget it. */
			if (dir == DIRECTION_STAND_UP || dir == DIRECTION_CROUCH)
				continue;

			Grid_MoveMark(map, excludeFromForbiddenList, actorSize, path, pos, epos[3], dir, &pqueue);
		}
	}
	/* Com_Printf("Loop: %i", count); */
	PQueueFree(&pqueue);

	Com_DPrintf(DEBUG_PATHING, "Grid_MoveCalc: Done\n\n");
}
Exemple #6
0
pq_element_t PQueuePop( PQUEUE *pq)
{
    int32 i;
    int32 child;

    pq_element_t pMaxElement;
    pq_element_t pLastElement;
     
    if( PQueueIsEmpty( pq ) )
    {
#ifndef __KERNEL__
        return NULL;
#else
        pq_element_t ret;
        ret.tv = 0;
        return ret;
#endif
    }

    pMaxElement = pq->Elements[PQ_FIRST_ENTRY];

    /* get pointer to last element in tree */
    pLastElement = pq->Elements[ pq->CurrentSize-- ];

    if( pq->IsAscendingHeap == TRUE )
    {

        /* code to pop an element from an ascending (top to bottom) pqueue */

        /*  UNTESTED */

        for( i=PQ_FIRST_ENTRY; PQ_LEFT_CHILD_INDEX(i) <= pq->CurrentSize; i=child )
        {
            /* set child to the smaller of the two children... */
        
            child = PQ_LEFT_CHILD_INDEX(i);
        
            if( (child != pq->CurrentSize) &&
                /*(PGetRating(pq->Elements[child + 1]) > PGetRating(pq->Elements[child])) )*/
                (pq->cmp(pq->Elements[child + 1], pq->Elements[child], pq->context) > 0)
                )
            {
                child ++;
            }
        
            if( /*PGetRating( pLastElement ) < PGetRating( pq->Elements[ child ] ) */
                pq->cmp(pLastElement, pq->Elements[child], pq->context) < 0
                    )
            {
                pq->Elements[ i ] = pq->Elements[ child ];
            }
            else
            {
                break;
            }
        }
    }
    else
    {
        /* code to pop an element from a descending (top to bottom) pqueue */

        for( i=PQ_FIRST_ENTRY; PQ_LEFT_CHILD_INDEX(i) <= pq->CurrentSize; i=child )
        {
            /* set child to the larger of the two children... */
        
            child = PQ_LEFT_CHILD_INDEX(i);
        
            if( (child != pq->CurrentSize) &&
                /*(PGetRating(pq->Elements[child + 1]) < PGetRating(pq->Elements[child])) */ 
                pq->cmp(pq->Elements[child + 1], pq->Elements[child], pq->context) < 0
                    )
            {
                child ++;
            }
        
            if( /*PGetRating( pLastElement ) > PGetRating( pq->Elements[ child ] ) */
                pq->cmp(pLastElement, pq->Elements[child], pq->context) > 0    
                    )
            {
                pq->Elements[ i ] = pq->Elements[ child ];
            }
            else
            {
                break;
            }
        }
    }

    pq->Elements[i] = pLastElement;

    return pMaxElement;
}