예제 #1
0
void FogWorker::FloodFill(int32 x, int32 y)
{
    if(x < 0 || x >= TextureSize || y < 0 || y >= TextureSize)
    {
        return;
    }

    // Wikipedia
    // Flood-fill (node, target-color, replacement-color):
    // 1. If target - color is equal to replacement - color, return.
    // 2. If color of node is not equal to target - color, return.
    if(FMath::IsNearlyEqual(UnfoggedData[x + y * TextureSize], 1.0f))
    {
        return;
    }
    // 3. Set Q to the empty queue.
    TQueue<FIntVector> Q;
    // 4. Add node to Q.
    Q.Enqueue(FIntVector(x, y, 0));

    FIntVector N;
    // 5. For each element N of Q :
    while(Q.Dequeue(N))
    {
        // 6. Set w and e equal to N.
        auto w = N, e = N;
        // 7. Move w to the west until the color of the node to the west of w no longer matches target - color.
        while(w.X - 1 > 0 && !FMath::IsNearlyEqual(UnfoggedData[w.X - 1 + w.Y * TextureSize], 1.0f))
        {
            w.X--;
        }
        // 8. Move e to the east until the color of the node to the east of e no longer matches target - color.
        while(e.X + 1 < TextureSize && !FMath::IsNearlyEqual(UnfoggedData[e.X + 1 + e.Y * TextureSize], 1.0f))
        {
            e.X++;
        }
        // 9. For each node n between w and e :
        for(auto i = w.X; i <= e.X; ++i)
        {
            FIntVector n(i, N.Y, 0);
            // 10. Set the color of n to replacement - color.
            UnfoggedData[n.X + n.Y * TextureSize] = 1.0f;
            // 11. If the color of the node to the north of n is target - color, add that node to Q.
            if(n.Y + 1 < TextureSize && !FMath::IsNearlyEqual(UnfoggedData[n.X + (n.Y + 1) * TextureSize], 1.0f))
                Q.Enqueue(FIntVector(n.X, n.Y + 1, 0));
            // 12. If the color of the node to the south of n is target - color, add that node to Q.
            if(n.Y - 1 > 0 && !FMath::IsNearlyEqual(UnfoggedData[n.X + (n.Y - 1) * TextureSize], 1.0f))
            {
                Q.Enqueue(FIntVector(n.X, n.Y - 1, 0));
            }
        }
        // 13. Continue looping until Q is exhausted.
    }
    // 14. Return.
}
예제 #2
0
bool FAppEventManager::WaitForEventInQueue(EAppEventState InState, double TimeoutSeconds)
{
	bool FoundEvent = false;
	double StopTime = FPlatformTime::Seconds() + TimeoutSeconds;

	TQueue<FAppEventData, EQueueMode::Spsc> HoldingQueue;
	while (!FoundEvent)
	{
		int rc = pthread_mutex_lock(&QueueMutex);
		check(rc == 0);

		// Copy the existing queue (and check for our event)
		while (!Queue.IsEmpty())
		{
			FAppEventData OutData;
			Queue.Dequeue(OutData);

			if (OutData.State == InState)
				FoundEvent = true;

			HoldingQueue.Enqueue(OutData);
		}

		if (FoundEvent)
			break;

		// Time expired?
		if (FPlatformTime::Seconds() > StopTime)
			break;

		// Unlock for new events and wait a bit before trying again
		rc = pthread_mutex_unlock(&QueueMutex);
		check(rc == 0);
		FPlatformProcess::Sleep(0.01f);
	}

	// Add events back to queue from holding
	while (!HoldingQueue.IsEmpty())
	{
		FAppEventData OutData;
		HoldingQueue.Dequeue(OutData);
		Queue.Enqueue(OutData);
	}

	int rc = pthread_mutex_unlock(&QueueMutex);
	check(rc == 0);

	return FoundEvent;
}