You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
5.2 KiB

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