1/*******************************************************************************************
2*
3* raylib example - loading thread
4*
5* NOTE: This example requires linking with pthreads library,
6* on MinGW, it can be accomplished passing -static parameter to compiler
7*
8* This example has been created using raylib 2.5 (www.raylib.com)
9* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
10*
11* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
12*
13********************************************************************************************/
14
15#include "raylib.h"
16
17#include "pthread.h" // POSIX style threads management
18
19#include <stdatomic.h> // C11 atomic data types
20
21#include <time.h> // Required for: clock()
22
23// Using C11 atomics for synchronization
24// NOTE: A plain bool (or any plain data type for that matter) can't be used for inter-thread synchronization
25static atomic_bool dataLoaded = ATOMIC_VAR_INIT(false); // Data Loaded completion indicator
26static void *LoadDataThread(void *arg); // Loading data thread function declaration
27
28static int dataProgress = 0; // Data progress accumulator
29
30int main(void)
31{
32 // Initialization
33 //--------------------------------------------------------------------------------------
34 const int screenWidth = 800;
35 const int screenHeight = 450;
36
37 InitWindow(screenWidth, screenHeight, "raylib [core] example - loading thread");
38
39 pthread_t threadId; // Loading data thread id
40
41 enum { STATE_WAITING, STATE_LOADING, STATE_FINISHED } state = STATE_WAITING;
42 int framesCounter = 0;
43
44 SetTargetFPS(60); // Set our game to run at 60 frames-per-second
45 //--------------------------------------------------------------------------------------
46
47 // Main game loop
48 while (!WindowShouldClose()) // Detect window close button or ESC key
49 {
50 // Update
51 //----------------------------------------------------------------------------------
52 switch (state)
53 {
54 case STATE_WAITING:
55 {
56 if (IsKeyPressed(KEY_ENTER))
57 {
58 int error = pthread_create(&threadId, NULL, &LoadDataThread, NULL);
59 if (error != 0) TraceLog(LOG_ERROR, "Error creating loading thread");
60 else TraceLog(LOG_INFO, "Loading thread initialized successfully");
61
62 state = STATE_LOADING;
63 }
64 } break;
65 case STATE_LOADING:
66 {
67 framesCounter++;
68 if (atomic_load(&dataLoaded))
69 {
70 framesCounter = 0;
71 state = STATE_FINISHED;
72 }
73 } break;
74 case STATE_FINISHED:
75 {
76 if (IsKeyPressed(KEY_ENTER))
77 {
78 // Reset everything to launch again
79 atomic_store(&dataLoaded, false);
80 dataProgress = 0;
81 state = STATE_WAITING;
82 }
83 } break;
84 default: break;
85 }
86 //----------------------------------------------------------------------------------
87
88 // Draw
89 //----------------------------------------------------------------------------------
90 BeginDrawing();
91
92 ClearBackground(RAYWHITE);
93
94 switch (state)
95 {
96 case STATE_WAITING: DrawText("PRESS ENTER to START LOADING DATA", 150, 170, 20, DARKGRAY); break;
97 case STATE_LOADING:
98 {
99 DrawRectangle(150, 200, dataProgress, 60, SKYBLUE);
100 if ((framesCounter/15)%2) DrawText("LOADING DATA...", 240, 210, 40, DARKBLUE);
101
102 } break;
103 case STATE_FINISHED:
104 {
105 DrawRectangle(150, 200, 500, 60, LIME);
106 DrawText("DATA LOADED!", 250, 210, 40, GREEN);
107
108 } break;
109 default: break;
110 }
111
112 DrawRectangleLines(150, 200, 500, 60, DARKGRAY);
113
114 EndDrawing();
115 //----------------------------------------------------------------------------------
116 }
117
118 // De-Initialization
119 //--------------------------------------------------------------------------------------
120 CloseWindow(); // Close window and OpenGL context
121 //--------------------------------------------------------------------------------------
122
123 return 0;
124}
125
126// Loading data thread function definition
127static void *LoadDataThread(void *arg)
128{
129 int timeCounter = 0; // Time counted in ms
130 clock_t prevTime = clock(); // Previous time
131
132 // We simulate data loading with a time counter for 5 seconds
133 while (timeCounter < 5000)
134 {
135 clock_t currentTime = clock() - prevTime;
136 timeCounter = currentTime*1000/CLOCKS_PER_SEC;
137
138 // We accumulate time over a global variable to be used in
139 // main thread as a progress bar
140 dataProgress = timeCounter/10;
141 }
142
143 // When data has finished loading, we set global variable
144 atomic_store(&dataLoaded, true);
145
146 return NULL;
147}
148