mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 21:21:17 +01:00
Many changes to add in support for Unreal RHI This is the first step. Afterwords we need more changes such as finalizing the for_unreal switch to premake. Diffs= 1cc5f2b6f Prep for rhi (#8270) Co-authored-by: Jonathon Copeland <jcopela4@gmail.com>
118 lines
3.4 KiB
C++
118 lines
3.4 KiB
C++
/*
|
|
* Copyright 2024 Rive
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "common/tcp_client.hpp"
|
|
#include "common/queue.hpp"
|
|
#include "write_png_file.hpp"
|
|
#include <array>
|
|
#include <cassert>
|
|
#include <string>
|
|
#include <thread>
|
|
#include <vector>
|
|
#include <filesystem>
|
|
|
|
struct ImageSaveArgs
|
|
{
|
|
std::string name;
|
|
uint32_t width;
|
|
uint32_t height;
|
|
std::vector<uint8_t> pixels;
|
|
bool quit = false;
|
|
};
|
|
|
|
// Attempts to connect to the python server, and if successful, pipes stdout and
|
|
// stderr to the server. Also provides utilities for encoding & uploading PNGs, and
|
|
// notifying the server when the application crashes.
|
|
class TestHarness
|
|
{
|
|
public:
|
|
static TestHarness& Instance();
|
|
~TestHarness() { shutdown(); }
|
|
|
|
bool initialized() const { return m_initialized; }
|
|
void init(std::unique_ptr<TCPClient>, size_t pngThreadCount);
|
|
void init(std::filesystem::path, size_t pngThreadCount);
|
|
|
|
bool hasTCPConnection() const { return m_primaryTCPClient != nullptr; }
|
|
|
|
void setPNGCompression(PNGCompression compression) { m_pngCompression = compression; }
|
|
|
|
void savePNG(ImageSaveArgs args)
|
|
{
|
|
assert(m_initialized);
|
|
m_encodeQueue.push(std::move(args));
|
|
}
|
|
|
|
// Only returns true the on the first server request for a given name.
|
|
// Prevents gms from running more than once in a multi-process execution.
|
|
bool claimGMTest(const std::string&);
|
|
|
|
// Downloads the next .riv file to test. (Must only be run on the main thread.)
|
|
bool fetchRivFile(std::string& name, std::vector<uint8_t>& bytes);
|
|
|
|
// Returns true if there is an input character to process from the server.
|
|
bool peekChar(char& key);
|
|
|
|
void shutdown();
|
|
|
|
void onApplicationCrash(const char* message);
|
|
|
|
private:
|
|
TestHarness();
|
|
|
|
// Adheres to a quick-and-dirty protocol for sending a PNG image back to the python harness.
|
|
void sendImage(const std::string& remoteDestination,
|
|
uint32_t width,
|
|
uint32_t height,
|
|
uint8_t* imageDataRGBA);
|
|
|
|
// Print a message on the server-side console.
|
|
void sendConsoleMessage(const char* message, uint32_t messageLength);
|
|
|
|
void shutdownStdioThread();
|
|
void shutdownInputPumpThread();
|
|
|
|
// Forwards stdout and stderr to the server.
|
|
static void MonitorStdIOThread(void* thisPtr)
|
|
{
|
|
reinterpret_cast<TestHarness*>(thisPtr)->monitorStdIOThread();
|
|
}
|
|
void monitorStdIOThread();
|
|
|
|
// Encodes PNGS and sends them to the server.
|
|
static void EncodePNGThread(void* thisPtr)
|
|
{
|
|
reinterpret_cast<TestHarness*>(thisPtr)->encodePNGThread();
|
|
}
|
|
void encodePNGThread();
|
|
|
|
// Receives standard input from the server and queues it up.
|
|
static void InputPumpThread(void* thisPtr)
|
|
{
|
|
reinterpret_cast<TestHarness*>(thisPtr)->inputPumpThread();
|
|
}
|
|
void inputPumpThread();
|
|
|
|
bool m_initialized = false;
|
|
std::unique_ptr<TCPClient> m_primaryTCPClient;
|
|
std::filesystem::path m_outputDir;
|
|
|
|
// Forwarding stdout and stderr to the server.
|
|
int m_savedStdout = 0;
|
|
int m_savedStderr = 0;
|
|
std::array<int, 2> m_stdioPipe = {0, 0};
|
|
std::thread m_stdioThread;
|
|
|
|
// PNG image encode queue.
|
|
queue<ImageSaveArgs> m_encodeQueue{1};
|
|
PNGCompression m_pngCompression = PNGCompression::compact;
|
|
std::vector<std::thread> m_encodeThreads;
|
|
|
|
// Standard input from the server.
|
|
queue<char> m_inputQueue{128};
|
|
std::thread m_inputPumpThread;
|
|
};
|