Skip to content

Commit 77193ad

Browse files
authored
Merge pull request #117 from pkeir/master
Added a C++ version of raylib's loading thread example.
2 parents 4452398 + c753294 commit 77193ad

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*******************************************************************************
2+
*
3+
* raylib example - loading thread
4+
*
5+
* This example has been created using raylib-cpp (www.raylib.com)
6+
* raylib is licensed under an unmodified zlib/libpng license
7+
* (View raylib.h for details)
8+
*
9+
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
10+
* Copyright (c) 2021 Paul Keir (University of the West of Scotland)
11+
*
12+
*******************************************************************************/
13+
14+
#include "raylib-cpp.hpp"
15+
#include <thread> // C++11 standard library threads
16+
#include <atomic> // C++ atomic data types
17+
#include <chrono> // For: chrono::steady_clock::now()
18+
#include <system_error> // May be thrown by thread c'tor
19+
20+
// Using C++ std::atomic_bool (aka. std::atomic<bool>) for synchronization.
21+
// n.b. A plain built-in type can't be used for inter-thread synchronization
22+
std::atomic_bool dataLoaded{false};
23+
static void LoadDataThread(); // Loading data thread function declaration
24+
static int dataProgress = 0; // Data progress accumulator
25+
26+
int main(void)
27+
{
28+
// Initialization
29+
//--------------------------------------------------------------------------
30+
const int screenWidth = 800;
31+
const int screenHeight = 450;
32+
33+
raylib::Window window(screenWidth, screenHeight,
34+
"raylib [core] example - loading thread");
35+
36+
std::thread threadId; // Loading data thread id
37+
38+
enum { STATE_WAITING, STATE_LOADING, STATE_FINISHED } state = STATE_WAITING;
39+
int framesCounter = 0;
40+
41+
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
42+
//--------------------------------------------------------------------------
43+
44+
// Main game loop
45+
while (!window.ShouldClose()) // Detect window close button or ESC key
46+
{
47+
// Update
48+
//----------------------------------------------------------------------
49+
switch (state)
50+
{
51+
case STATE_WAITING:
52+
if (IsKeyPressed(KEY_ENTER))
53+
{
54+
try {
55+
threadId = std::thread(LoadDataThread);
56+
TraceLog(LOG_INFO,
57+
"Loading thread initialized successfully");
58+
} catch (std::system_error e) {
59+
TraceLog(LOG_ERROR, "Error: %s", e.what());
60+
}
61+
62+
state = STATE_LOADING;
63+
}
64+
break;
65+
66+
case STATE_LOADING:
67+
framesCounter++;
68+
if (dataLoaded.load())
69+
{
70+
framesCounter = 0;
71+
state = STATE_FINISHED;
72+
}
73+
break;
74+
75+
case STATE_FINISHED:
76+
if (IsKeyPressed(KEY_ENTER))
77+
{
78+
// Reset everything to launch again
79+
dataLoaded = false;
80+
dataProgress = 0;
81+
state = STATE_WAITING;
82+
}
83+
break;
84+
85+
default:
86+
break;
87+
}
88+
//----------------------------------------------------------------------
89+
90+
// Draw
91+
//----------------------------------------------------------------------
92+
BeginDrawing();
93+
94+
ClearBackground(RAYWHITE);
95+
96+
switch (state)
97+
{
98+
case STATE_WAITING:
99+
DrawText("PRESS ENTER to START LOADING DATA",
100+
150, 170, 20, DARKGRAY);
101+
break;
102+
103+
case STATE_LOADING:
104+
DrawRectangle(150, 200, dataProgress, 60, SKYBLUE);
105+
if ((framesCounter/15)%2)
106+
DrawText("LOADING DATA...", 240, 210, 40, DARKBLUE);
107+
break;
108+
109+
case STATE_FINISHED:
110+
DrawRectangle(150, 200, 500, 60, LIME);
111+
DrawText("DATA LOADED!", 250, 210, 40, GREEN);
112+
break;
113+
114+
default:
115+
break;
116+
}
117+
118+
DrawRectangleLines(150, 200, 500, 60, DARKGRAY);
119+
120+
EndDrawing();
121+
//----------------------------------------------------------------------
122+
}
123+
124+
if (threadId.joinable()) // The user might quit without creating a thread.
125+
threadId.join(); // Good etiquette, but may take a second.
126+
127+
return 0;
128+
}
129+
130+
// Loading data thread function definition
131+
static void LoadDataThread()
132+
{
133+
using namespace std::chrono;
134+
int timeCounter = 0; // Time counted in ms
135+
136+
auto prevTime = steady_clock::now();
137+
138+
// We simulate data loading with a time counter for 5 seconds
139+
while (timeCounter < 5000)
140+
{
141+
auto currentTime = steady_clock::now() - prevTime;
142+
timeCounter = duration_cast<milliseconds>(currentTime).count();
143+
144+
// We accumulate time over a global variable to be used in
145+
// main thread as a progress bar
146+
dataProgress = timeCounter/10;
147+
}
148+
149+
// When data has finished loading, we set global variable
150+
dataLoaded = true;
151+
}

0 commit comments

Comments
 (0)