Make xSpriteAnimation orchestrable and register every animation into the app when started
This commit is contained in:
parent
2cbf3bc91b
commit
57025d9ef3
|
@ -1,6 +1,7 @@
|
||||||
#ifndef DEF_XSDL_H
|
#ifndef DEF_XSDL_H
|
||||||
#define DEF_XSDL_H
|
#define DEF_XSDL_H
|
||||||
|
|
||||||
|
#include "../xSDL/xOrchestrable.h"
|
||||||
#include "../xSDL/xApplication.h"
|
#include "../xSDL/xApplication.h"
|
||||||
#include "../xSDL/xController.h"
|
#include "../xSDL/xController.h"
|
||||||
#include "../xSDL/xElement.h"
|
#include "../xSDL/xElement.h"
|
||||||
|
|
|
@ -303,7 +303,18 @@ void xApplication::schedule(){
|
||||||
// poll events
|
// poll events
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while( SDL_PollEvent(&event) != 0 )
|
while( SDL_PollEvent(&event) != 0 )
|
||||||
this->_controller.handleEvent(&event);
|
_controller.handleEvent(&event);
|
||||||
|
|
||||||
|
const uint32_t ticks = SDL_GetTicks();
|
||||||
|
|
||||||
|
// trigger tick() on registered orchestrables
|
||||||
|
_mutex_orchestrate.try_lock();
|
||||||
|
set<xOrchestrable*>::iterator it;
|
||||||
|
for( it = _orchestrables.begin() ; it != _orchestrables.end() ; it++ ){
|
||||||
|
xOrchestrable* orchestrable = *it;
|
||||||
|
orchestrable->tick(ticks);
|
||||||
|
}
|
||||||
|
_mutex_orchestrate.unlock();
|
||||||
|
|
||||||
// wait to satisfy FPS
|
// wait to satisfy FPS
|
||||||
this->syncFps();
|
this->syncFps();
|
||||||
|
@ -312,6 +323,18 @@ void xApplication::schedule(){
|
||||||
this->render();
|
this->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xApplication::addOrchestrable(xOrchestrable* o){
|
||||||
|
_mutex_orchestrate.try_lock();
|
||||||
|
_orchestrables.insert(o);
|
||||||
|
_mutex_orchestrate.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void xApplication::removeOrchestrable(xOrchestrable* o){
|
||||||
|
_mutex_orchestrate.try_lock();
|
||||||
|
_orchestrables.erase(o);
|
||||||
|
_mutex_orchestrate.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
/** synchronizes according to FPS
|
/** synchronizes according to FPS
|
||||||
* to be used at the end of the UI loop */
|
* to be used at the end of the UI loop */
|
||||||
void xApplication::syncFps(){
|
void xApplication::syncFps(){
|
||||||
|
|
|
@ -4,13 +4,14 @@
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_image.h"
|
#include "SDL_image.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "xElement.h"
|
#include "xElement.h"
|
||||||
#include "xController.h"
|
#include "xController.h"
|
||||||
|
#include "xOrchestrable.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
enum xAppState {
|
enum xAppState {
|
||||||
|
@ -19,8 +20,6 @@
|
||||||
STOPPED
|
STOPPED
|
||||||
};
|
};
|
||||||
|
|
||||||
#define EventListener void(*)(SDL_Event*)
|
|
||||||
|
|
||||||
class xApplication{
|
class xApplication{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -52,6 +51,10 @@
|
||||||
void setFps(const uint32_t fps=0);
|
void setFps(const uint32_t fps=0);
|
||||||
void schedule();
|
void schedule();
|
||||||
|
|
||||||
|
// manage orchestrables
|
||||||
|
void addOrchestrable(xOrchestrable* o);
|
||||||
|
void removeOrchestrable(xOrchestrable* o);
|
||||||
|
|
||||||
xAppState state;
|
xAppState state;
|
||||||
private:
|
private:
|
||||||
/** Singleton */
|
/** Singleton */
|
||||||
|
@ -70,6 +73,9 @@
|
||||||
// sprites
|
// sprites
|
||||||
set<xElement*> _sprites;
|
set<xElement*> _sprites;
|
||||||
|
|
||||||
|
// execution pool
|
||||||
|
set<xOrchestrable*> _orchestrables;
|
||||||
|
|
||||||
// sdl objects
|
// sdl objects
|
||||||
SDL_Window *_window;
|
SDL_Window *_window;
|
||||||
SDL_Rect _winrect;
|
SDL_Rect _winrect;
|
||||||
|
@ -79,6 +85,7 @@
|
||||||
|
|
||||||
// thread safety
|
// thread safety
|
||||||
mutex _mutex_draw;
|
mutex _mutex_draw;
|
||||||
|
mutex _mutex_orchestrate;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1 @@
|
||||||
|
#include "xOrchestrable.h"
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef DEF_XORCHESTRABLE_H
|
||||||
|
#define DEF_XORCHESTRABLE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// abstract class for orchestrables
|
||||||
|
struct xOrchestrable {
|
||||||
|
virtual void tick(const uint32_t ticks) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,11 +8,9 @@ xSpriteAnimation::~xSpriteAnimation(){
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** builds an animation */
|
/** builds an animation */
|
||||||
xSpriteAnimation::xSpriteAnimation(const char *url, SDL_Rect dest)
|
xSpriteAnimation::xSpriteAnimation(const char *url, SDL_Rect dest)
|
||||||
: xSprite( url ){
|
: xSprite( url ){
|
||||||
|
|
||||||
this->dimensions(dest);
|
this->dimensions(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,24 +21,23 @@ xSpriteAnimation::xSpriteAnimation(SDL_Surface *s, SDL_Rect dest)
|
||||||
this->dimensions(dest);
|
this->dimensions(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** adds an animation frame */
|
/** adds an animation frame */
|
||||||
void xSpriteAnimation::addFrame(SDL_Rect clip){
|
void xSpriteAnimation::addFrame(SDL_Rect clip){
|
||||||
_mutex.try_lock();
|
_mutex_frames.try_lock();
|
||||||
_frames.push_back( (SDL_Rect){
|
_frames.push_back( (SDL_Rect){
|
||||||
clip.x,
|
clip.x,
|
||||||
clip.y,
|
clip.y,
|
||||||
clip.w,
|
clip.w,
|
||||||
clip.h
|
clip.h
|
||||||
} );
|
} );
|
||||||
_mutex.unlock();
|
_mutex_frames.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** clears all frames */
|
/** clears all frames */
|
||||||
void xSpriteAnimation::clearFrames(){
|
void xSpriteAnimation::clearFrames(){
|
||||||
_mutex.try_lock();
|
_mutex_frames.try_lock();
|
||||||
_frames.erase(_frames.begin(), _frames.end());
|
_frames.erase(_frames.begin(), _frames.end());
|
||||||
_mutex.unlock();
|
_mutex_frames.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** draw to scene */
|
/** draw to scene */
|
||||||
|
@ -56,61 +53,24 @@ void xSpriteAnimation::draw(SDL_Renderer* renderer){
|
||||||
}
|
}
|
||||||
|
|
||||||
/** animation process */
|
/** animation process */
|
||||||
void xSpriteAnimationProcess(xSpriteAnimation *xSA, uint32_t t, int flags){
|
void xSpriteAnimation::tick(const uint32_t ticks){
|
||||||
uint32_t timer = 0;
|
_mutex_frames.try_lock();
|
||||||
bool way = true;
|
uint32_t time_index = ticks / _interval;
|
||||||
uint32_t start = 0;
|
size_t frame_index = time_index % _frames.size();
|
||||||
|
|
||||||
while( flags&SPRITE_ANIM_INFINITE ){
|
// update current frame clip
|
||||||
|
_src = _frames.at(frame_index);
|
||||||
// for every frame (sprite)
|
_mutex_frames.unlock();
|
||||||
for( uint32_t i = start ; i != xSA->_frames.size() ; i+=(way?1:-1) ){
|
|
||||||
timer = SDL_GetTicks();
|
|
||||||
|
|
||||||
// update current frame clip
|
|
||||||
// xSA->_mutex.try_lock();
|
|
||||||
xSA->_src = xSA->_frames.at(i);
|
|
||||||
// xSA->_mutex.unlock();
|
|
||||||
|
|
||||||
// xSA->manager()->update();
|
|
||||||
|
|
||||||
if( SDL_GetTicks()-timer < t )
|
|
||||||
SDL_Delay( t - (SDL_GetTicks()-timer) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// manage reverse flag
|
|
||||||
if( flags&SPRITE_ANIM_REVERSE ){
|
|
||||||
way = !way;
|
|
||||||
start = (way) ? 0 : xSA->_frames.size()-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// end thread
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** adds the animation to the render */
|
/** adds the animation to the render */
|
||||||
void xSpriteAnimation::start(int t, int flags){
|
void xSpriteAnimation::start(uint32_t interval){
|
||||||
_timeout = t;
|
_interval = interval;
|
||||||
_flags = flags;
|
xApplication::get()->addOrchestrable(this);
|
||||||
|
|
||||||
// launch animation
|
|
||||||
_animation = new thread(xSpriteAnimationProcess, this, t, flags);
|
|
||||||
|
|
||||||
// don't wait for the thread to end
|
|
||||||
_animation->detach();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** stops the animation */
|
/** stops the animation */
|
||||||
void xSpriteAnimation::stop(){
|
void xSpriteAnimation::stop(){
|
||||||
// stop animation thread
|
xApplication::get()->removeOrchestrable(this);
|
||||||
delete _animation;
|
|
||||||
if( _animation->joinable() )
|
|
||||||
_animation->join();
|
|
||||||
|
|
||||||
_animation = NULL;
|
|
||||||
}
|
}
|
|
@ -2,18 +2,14 @@
|
||||||
#define DEF_XSPRITEANIMATION_H
|
#define DEF_XSPRITEANIMATION_H
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
#include <vector>
|
||||||
#include "xSprite.h"
|
#include "xSprite.h"
|
||||||
#include "xApplication.h"
|
#include "xApplication.h"
|
||||||
#include "xElement.h"
|
#include "xElement.h"
|
||||||
#include <vector>
|
#include "xOrchestrable.h"
|
||||||
#include <thread>
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define SPRITE_ANIM_ONCE 0b1
|
class xSpriteAnimation : public xSprite, public xOrchestrable {
|
||||||
#define SPRITE_ANIM_INFINITE 0b10
|
|
||||||
#define SPRITE_ANIM_REVERSE 0b100
|
|
||||||
|
|
||||||
class xSpriteAnimation : public xSprite {
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// spritesheet with sprite size
|
// spritesheet with sprite size
|
||||||
|
@ -25,22 +21,20 @@
|
||||||
void clearFrames();
|
void clearFrames();
|
||||||
|
|
||||||
// animation control handles
|
// animation control handles
|
||||||
void start(int t, int flags=SPRITE_ANIM_ONCE);
|
void start(uint32_t delay);
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
// implement xElement
|
// implement xElement
|
||||||
void draw(SDL_Renderer* renderer) override;
|
void draw(SDL_Renderer* renderer) override;
|
||||||
|
|
||||||
|
// implement xOrchestrable
|
||||||
|
void tick(const uint32_t ticks);
|
||||||
protected:
|
protected:
|
||||||
vector<SDL_Rect> _frames;
|
vector<SDL_Rect> _frames;
|
||||||
|
mutex _mutex_frames;
|
||||||
|
|
||||||
// animation
|
// animation
|
||||||
int _timeout;
|
uint32_t _interval;
|
||||||
int _flags;
|
|
||||||
|
|
||||||
// animation thread
|
|
||||||
thread *_animation;
|
|
||||||
friend void xSpriteAnimationProcess(xSpriteAnimation *xSA, uint32_t t, int flags);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue