File: arg.cpp

package info (click to toggle)
hyprgraphics 0.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 940 kB
  • sloc: cpp: 1,639; sh: 9; makefile: 6
file content (139 lines) | stat: -rw-r--r-- 4,436 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <algorithm>
#include <print>
#include <format>
#include <filesystem>
#include <fstream>
#include <vector>
#include <hyprgraphics/resource/AsyncResourceGatherer.hpp>
#include <hyprgraphics/resource/resources/TextResource.hpp>
#include <hyprgraphics/resource/resources/ImageResource.hpp>
#include <hyprutils/memory/UniquePtr.hpp>
#include <hyprutils/memory/Atomic.hpp>
#include <hyprutils/math/Vector2D.hpp>
#include "shared.hpp"

using namespace Hyprutils::Memory;
using namespace Hyprutils::Math;
using namespace Hyprgraphics;

#define UP CUniquePointer

static UP<CAsyncResourceGatherer> g_asyncResourceGatherer;

static struct {
    std::mutex                                        wakeupMutex;
    std::condition_variable                           wakeup;

    bool                                              exit           = false;
    bool                                              needsToProcess = false;

    int                                               loadedAssets = 0;

    std::mutex                                        resourcesMutex;
    std::vector<CAtomicSharedPointer<IAsyncResource>> resources;
} state;

//

static bool renderText(const std::string& text, Vector2D max = {}) {
    // this stinks a bit but it's due to our ASP impl.
    auto resource =
        makeAtomicShared<CTextResource>(CTextResource::STextResourceData{.text = text, .fontSize = 72, .maxSize = max.x == 0 ? std::nullopt : std::optional<Vector2D>(max)});
    CAtomicSharedPointer<IAsyncResource> resourceGeneric(resource);

    g_asyncResourceGatherer->enqueue(resourceGeneric);

    state.resourcesMutex.lock();
    state.resources.emplace_back(std::move(resourceGeneric));
    state.resourcesMutex.unlock();

    resource->m_events.finished.listenStatic([]() {
        state.needsToProcess = true;
        state.wakeup.notify_all();
    });

    std::println("Enqueued \"{}\" successfully.", text);

    return true;
}

static bool renderImage(const std::string& path) {
    // this stinks a bit but it's due to our ASP impl.
    auto                                 resource = makeAtomicShared<CImageResource>(path);
    CAtomicSharedPointer<IAsyncResource> resourceGeneric(resource);

    g_asyncResourceGatherer->enqueue(resourceGeneric);

    state.resourcesMutex.lock();
    state.resources.emplace_back(std::move(resourceGeneric));
    state.resourcesMutex.unlock();

    resource->m_events.finished.listenStatic([]() {
        state.needsToProcess = true;
        state.wakeup.notify_all();
    });

    std::println("Enqueued \"{}\" successfully.", path);

    return true;
}

int main(int argc, char** argv, char** envp) {
    int ret = 0;

    g_asyncResourceGatherer = makeUnique<CAsyncResourceGatherer>();

    EXPECT(renderText("Hello World"), true);
    EXPECT(renderText("<b><i>Test markup</i></b>"), true);
    EXPECT(renderText("Test ellipsis!!!!!", {512, 190}),
           true);
    EXPECT(renderImage("./resource/images/hyprland.png"), true);

    while (!state.exit) {
        std::unique_lock lk(state.wakeupMutex);
        if (!state.needsToProcess) // avoid a lock if a thread managed to request something already since we .unlock()ed
            state.wakeup.wait_for(lk, std::chrono::seconds(5), [] { return state.needsToProcess; }); // wait for events

        if (state.exit)
            break;

        state.needsToProcess = false;

        state.resourcesMutex.lock();

        const bool SHOULD_EXIT = std::ranges::all_of(state.resources, [](const auto& e) { return !!e->m_ready; });

        state.resourcesMutex.unlock();

        if (SHOULD_EXIT)
            break;

        lk.unlock();
    }

    // all assets should be done, let's render them
    size_t idx = 0;
    for (const auto& r : state.resources) {
        const auto TEST_DIR = std::filesystem::current_path().string() + "/test_output";

        // try to write it for inspection
        if (!std::filesystem::exists(TEST_DIR))
            std::filesystem::create_directory(TEST_DIR);

        std::string name = std::format("render-arg-{}", idx);

        EXPECT(!!r->m_asset.cairoSurface->cairo(), true);

        //NOLINTNEXTLINE
        if (!r->m_asset.cairoSurface->cairo())
            continue;

        EXPECT(cairo_surface_write_to_png(r->m_asset.cairoSurface->cairo(), (TEST_DIR + "/" + name + ".png").c_str()), CAIRO_STATUS_SUCCESS);

        idx++;
    }

    g_asyncResourceGatherer.reset();

    return ret;
}