Thread overview
Threading with SDL
Nov 19
user1234
November 19

Hey,

I'm looking at D right now because I find it much easier to create native applications as opposed to C++.

I have the following project structure:

    - main.d (Booting)
    - client.d
    - Renderer.d
        - Manager
            - SDL2.d
            - GLFW.d
        - RenderingTargets
            - DirectX.d
            - Vulkan.d
            - OpenGL.d

A new client instance is created in main.d. This will later serve as the “main game” instance.

A new instance of Renderer.d is created here. This contains the window manager (e.g. via SDL2 or GLFW) and the respective rendering engine (Vulkan, DirectX, OpenGL, etc.).

However, as soon as I initialize the window in SDL2.d and then want to render it, the whole thing blocks the client.

The RenderingTarget must create SDL2 or GLFW as an instance here, as there are differences between the individual graphics interfaces and GLFW, for example, does not support DirectX.

How can I implement the whole thing thread-based so that the client functions are executed as soon as SDL2 blocks the application?

November 19

On Tuesday, 19 November 2024 at 09:08:46 UTC, Adrian Preuß wrote:

>

Hey,

I'm looking at D right now because I find it much easier to create native applications as opposed to C++.

I have the following project structure:

    - main.d (Booting)
    - client.d
    - Renderer.d
        - Manager
            - SDL2.d
            - GLFW.d
        - RenderingTargets
            - DirectX.d

Well given the informations> - Vulkan.d

>
        - OpenGL.d

A new client instance is created in main.d. This will later serve as the “main game” instance.

A new instance of Renderer.d is created here. This contains the window manager (e.g. via `SDL2` or `GLFW`) and the respective rendering engine (`Vulkan`, `DirectX`, `OpenGL`, etc.).

However, as soon as I initialize the window in SDL2.d and then want to render it, the whole thing blocks the client.

The RenderingTarget must create `SDL2` or `GLFW` as an instance here, as there are differences between the individual graphics interfaces and `GLFW`, for example, does not support DirectX.

How can I implement the whole thing thread-based so that the client functions are executed as soon as `SDL2` blocks the application?

Given the information it's hard to reply but I'd say pass a delegate instead of using static constructors, so that when the basement is there, the basement can launch what depends on it.

November 19

On Tuesday, 19 November 2024 at 09:08:46 UTC, Adrian Preuß wrote:

>

I have the following project structure:

    - main.d (Booting)
    - client.d
    - Renderer.d
        - Manager
            - SDL2.d
            - GLFW.d
        - RenderingTargets
            - DirectX.d
            - Vulkan.d
            - OpenGL.d
module game.main;

import core.thread;
import core.sync.semaphore;
import std.stdio;
import std.concurrency;

// Renderer interface
abstract class Renderer {
    private bool isRunning = true;
    protected Tid mainThreadId;

    this(Tid mainThreadId) {
        this.mainThreadId = mainThreadId;
    }

    void initialize() {
        // Initialization logic
    }

    void run() {
        while (isRunning) {
            // Rendering loop
            renderFrame();
        }
    }

    protected void renderFrame() {
        // Implement rendering logic
    }

    void stop() {
        isRunning = false;
    }
}

// SDL2 Specific Renderer
class SDL2Renderer : Renderer {
    this(Tid mainThreadId) {
        super(mainThreadId);
    }

    override void initialize() {
        // SDL2 specific initialization
        import derelict.sdl2.sdl;
        DerelictSDL2.load();

        SDL_Init(SDL_INIT_VIDEO);
        // Create window, context, etc.
    }

    override protected void renderFrame() {
        import derelict.sdl2.sdl;

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
                case SDL_QUIT:
                    send(mainThreadId, "renderer_stopped");
                    stop();
                    break;
                default:
                    break;
            }
        }

        // Actual rendering logic
        // SDL_GL_SwapWindow(), etc.
    }
}

// Game Client
class GameClient {
    private Renderer renderer;
    private Tid rendererThread;

    this() {
        // Create a thread for rendering
        rendererThread = spawn(&rendererLoop, thisTid);
    }

    private void rendererLoop() {
        // Initialize renderer on its own thread
        auto sdlRenderer = new SDL2Renderer(thisTid);
        sdlRenderer.initialize();
        sdlRenderer.run();
    }

    void run() {
        // Main game loop
        while (true) {
            // Non-blocking game logic
            updateGameState();

            // Check for renderer messages
            receiveTimeout(
                dur!"msecs"(10),
                (string msg) {
                    if (msg == "renderer_stopped") {
                        break;
                    }
                }
            );
        }
    }

    private void updateGameState() {
        // Game state update logic
        // This runs independently of rendering
    }

    void shutdown() {
        // Send stop signal to renderer thread
        send(rendererThread, "stop");
    }
}

// Main entry point
void main() {
    auto game = new GameClient();
    game.run();
}

SDB@79

November 20

I think I have found the problem: SDL2 for window creation.

Now I implemented my own window manager with contextual graphics bindings for Vulkan, OpenGL and DirectX (9/10/11/12) with a focus on threading and it seems that this is a good solution now.

Predefined libs/dubs like SDL2 or GLFW assume that the main handling exists on a static basis. I've spent hours trying to make it asynchronous, but it doesn't really work and only causes problems.

November 20

On Wednesday, 20 November 2024 at 11:53:09 UTC, Adrian Preuß wrote:

>

I think I have found the problem: SDL2 for window creation.

Now I implemented my own window manager with contextual graphics bindings for Vulkan, OpenGL and DirectX (9/10/11/12)
...

It seems like it can complicate things when you want to use multiple threads for rendering and window management. I hope that your own solution will overcome the limitations of SDL2 with messaging and stateful control. Good luck...

SDB@79