FabGL
ESP32 Display Controller and Graphics Library
scene.cpp
1 /*
2  Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
3  Copyright (c) 2019-2020 Fabrizio Di Vittorio.
4  All rights reserved.
5 
6  This file is part of FabGL Library.
7 
8  FabGL is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  FabGL is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with FabGL. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 
23 #include "freertos/FreeRTOS.h"
24 #include "freertos/task.h"
25 #include "freertos/semphr.h"
26 
27 #include "fabutils.h"
28 #include "scene.h"
29 
30 
31 
32 
33 
34 
35 namespace fabgl {
36 
37 
38 Scene::Scene(int maxSpritesCount, int updateTimeMS, int width, int height, int stackSize)
39  : m_width(width),
40  m_height(height),
41  m_updateTimeMS(updateTimeMS),
42  m_collisionDetector(maxSpritesCount, width, height),
43  m_suspendedTask(nullptr),
44  m_running(false)
45 {
46  m_mutex = xSemaphoreCreateMutex();
47  xSemaphoreTake(m_mutex, portMAX_DELAY); // suspend update task
48  xTaskCreate(updateTask, "", FABGL_DEFAULT_SCENETASK_STACKSIZE, this, 5, &m_updateTaskHandle);
49 }
50 
51 
52 Scene::~Scene()
53 {
54  stop();
55  xSemaphoreTake(m_mutex, portMAX_DELAY); // suspend update task
56  vTaskDelete(m_updateTaskHandle);
57  vSemaphoreDelete(m_mutex);
58 }
59 
60 
61 void Scene::start(bool suspendTask)
62 {
63  if (!m_running) {
64  m_running = true;
65  m_updateCount = 0;
66  init();
67  xSemaphoreGive(m_mutex); // resume update task
68  if (suspendTask) {
69  m_suspendedTask = xTaskGetCurrentTaskHandle();
70  vTaskSuspend(m_suspendedTask);
71  } else
72  m_suspendedTask = nullptr;
73  }
74 }
75 
76 
78 {
79  if (m_running) {
80  // are we inside update task?
81  if (xTaskGetCurrentTaskHandle() != m_updateTaskHandle)
82  xSemaphoreTake(m_mutex, portMAX_DELAY); // no, suspend update task
83  m_running = false;
84  if (m_suspendedTask)
85  vTaskResume(m_suspendedTask);
86  }
87 }
88 
89 
90 void Scene::updateTask(void * pvParameters)
91 {
92  Scene * scene = (Scene*) pvParameters;
93 
94  while (true) {
95 
96  xSemaphoreTake(scene->m_mutex, portMAX_DELAY);
97 
98  int64_t t0 = esp_timer_get_time(); // us
99 
100  if (scene->m_running) {
101  scene->m_updateCount += 1;
102  scene->update(scene->m_updateCount);
103  }
104 
105  xSemaphoreGive(scene->m_mutex);
106 
107  int64_t t1 = esp_timer_get_time(); // us
108  int delayMS = (scene->m_updateTimeMS - (t1 - t0) / 1000);
109  if (delayMS > 0)
110  vTaskDelay(delayMS / portTICK_PERIOD_MS);
111  }
112 }
113 
114 
115 void collisionDetectionCallback(void * callbackObj, Sprite * spriteA, Sprite * spriteB, Point collisionPoint)
116 {
117  ((Scene*)callbackObj)->collisionDetected(spriteA, spriteB, collisionPoint);
118 }
119 
120 
122 {
123  m_collisionDetector.updateAndDetectCollision(sprite, collisionDetectionCallback, this);
124 }
125 
126 
127 
128 
129 } // end of namespace
Represents a sprite.
This file contains fabgl::Scene definition.
Scene is an abstract class useful to encapsulate functionalities of a scene (sprites, collision detector and updates).
Definition: scene.h:51
Scene(int maxSpritesCount, int updateTimeMS, int width, int height, int stackSize=FABGL_DEFAULT_SCENETASK_STACKSIZE)
The Scene constructor.
Definition: scene.cpp:38
This file contains some utility classes and functions.
Definition: canvas.cpp:31
virtual void init()=0
This is an abstract method called when the scene needs to be initialized.
Sprite * updateAndDetectCollision(Sprite *sprite, bool removeCollidingSprites=true)
Updates collision detector and detect collision with the specified sprite.
void updateSpriteAndDetectCollisions(Sprite *sprite)
Updates collision detector and generate collision events.
Definition: scene.cpp:121
uint8_t height
void start(bool suspendTask=true)
Starts scene updates and suspends current task.
Definition: scene.cpp:61
void stop()
Stops scene updates and resumes suspended task.
Definition: scene.cpp:77
uint8_t width
virtual void update(int updateCount)=0
This is an abstract method called whenever the scene needs to be updated.