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