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