Switched scene update to state event
This commit is contained in:
@ -36,8 +36,8 @@ void Scene::update() {
|
||||
// TODO: Cleanup old scene items
|
||||
|
||||
// TODO: Tick scene items(?)
|
||||
this->eventSceneUpdate.invoke();
|
||||
if(!this->game->timeManager.isPaused) this->eventSceneUnpausedUpdate.invoke();
|
||||
this->eventSceneUpdate.invoke(game->timeManager.delta);
|
||||
if(!this->game->timeManager.isPaused) this->eventSceneUnpausedUpdate.invoke(game->timeManager.delta);
|
||||
}
|
||||
|
||||
SceneItem * Scene::createSceneItem() {
|
||||
|
@ -21,7 +21,7 @@ namespace Dawn {
|
||||
template<class T>
|
||||
T * _sceneForwardGetComponent(SceneItem *item);
|
||||
|
||||
class Scene : public StateOwner {
|
||||
class Scene {
|
||||
private:
|
||||
sceneitemid_t nextId;
|
||||
std::map<sceneitemid_t, SceneItem*> items;
|
||||
@ -30,8 +30,8 @@ namespace Dawn {
|
||||
public:
|
||||
DawnGame *game;
|
||||
ScenePhysicsManager *physics;
|
||||
Event<> eventSceneUpdate;
|
||||
Event<> eventSceneUnpausedUpdate;
|
||||
StateEvent<float_t> eventSceneUpdate;
|
||||
StateEvent<float_t> eventSceneUnpausedUpdate;
|
||||
|
||||
/**
|
||||
* Construct a new Scene instance.
|
||||
|
@ -22,10 +22,10 @@ void AnimationController::addAnimation(Animation *animation) {
|
||||
void AnimationController::onStart() {
|
||||
SceneItemComponent::onStart();
|
||||
|
||||
useEventLegacy([&]{
|
||||
useEvent([&](float_t delta){
|
||||
auto it = this->animations.begin();
|
||||
while(it != this->animations.end()) {
|
||||
(*it)->tick(this->getGame()->timeManager.delta);
|
||||
(*it)->tick(delta);
|
||||
++it;
|
||||
}
|
||||
}, getScene()->eventSceneUnpausedUpdate);
|
||||
|
@ -28,11 +28,11 @@ ExampleSpin::ExampleSpin(SceneItem *item) :
|
||||
}
|
||||
|
||||
void ExampleSpin::onStart() {
|
||||
useEventLegacy([&]{
|
||||
useEvent([&](float_t delta){
|
||||
auto quat = this->transform->getLocalRotation();
|
||||
quat = glm::rotate(quat, getGame()->timeManager.delta, glm::vec3(0, 1, 0));
|
||||
quat = glm::rotate(quat, getGame()->timeManager.delta / 2.0f, glm::vec3(1, 0, 0));
|
||||
quat = glm::rotate(quat, getGame()->timeManager.delta / 4.0f, glm::vec3(0, 0, 1));
|
||||
quat = glm::rotate(quat, delta, glm::vec3(0, 1, 0));
|
||||
quat = glm::rotate(quat, delta / 2.0f, glm::vec3(1, 0, 0));
|
||||
quat = glm::rotate(quat, delta / 4.0f, glm::vec3(0, 0, 1));
|
||||
this->transform->setLocalRotation(quat);
|
||||
}, getScene()->eventSceneUnpausedUpdate);
|
||||
}
|
@ -14,13 +14,13 @@ SubSceneController::SubSceneController(SceneItem *i) : SceneItemComponent(i) {
|
||||
void SubSceneController::onStart() {
|
||||
auto myScene = this->getScene();
|
||||
|
||||
useEventLegacy([&]{
|
||||
useEvent([&](float_t d){
|
||||
if(!this->onlyUpdateUnpaused) return;
|
||||
if(this->subScene == nullptr) return;
|
||||
this->subScene->update();
|
||||
}, myScene->eventSceneUnpausedUpdate);
|
||||
|
||||
useEventLegacy([&]{
|
||||
useEvent([&](float_t d){
|
||||
if(this->onlyUpdateUnpaused) return;
|
||||
if(this->subScene == nullptr) return;
|
||||
this->subScene->update();
|
||||
|
@ -67,7 +67,7 @@ void UICanvas::onStart() {
|
||||
}, this->currentMenu);
|
||||
|
||||
// Scene Update
|
||||
useEventLegacy([&]{
|
||||
useEvent([&](float_t delta){
|
||||
if(this->currentMenu == nullptr) return;
|
||||
this->currentMenu->onTick();
|
||||
}, getScene()->eventSceneUpdate);
|
||||
|
@ -8,7 +8,10 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
AudioSource::AudioSource(SceneItem *i) : SceneItemComponent(i) {
|
||||
AudioSource::AudioSource(SceneItem *i) :
|
||||
SceneItemComponent(i),
|
||||
playMode(AUDIO_PLAY_MODE_UNPAUSED)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@ -107,8 +110,113 @@ void AudioSource::onStart() {
|
||||
this->ready = true;
|
||||
|
||||
// Listen for events
|
||||
this->transform->eventTransformUpdated.addListener(this, &AudioSource::onTransformUpdate);
|
||||
this->getScene()->eventSceneUpdate.addListener(this, &AudioSource::onSceneUpdate);
|
||||
useEventLegacy([&]{
|
||||
glm::vec3 position = this->transform->getWorldPosition();
|
||||
alSource3f(this->source, AL_POSITION, position.x, position.y, position.z);
|
||||
}, this->transform->eventTransformUpdated);
|
||||
|
||||
useEvent([&](float_t delta){
|
||||
ALuint bufferId;
|
||||
ALint buffersProcessed;
|
||||
|
||||
assertTrue(this->ready);
|
||||
|
||||
// What is the user trying to do?
|
||||
if(this->state == AUDIO_SOURCE_STATE_PLAYING) {
|
||||
assertTrue(this->data != nullptr);
|
||||
assertTrue(this->data->loaded);
|
||||
|
||||
// Handle the special game-paused music-paused state.
|
||||
if(this->playMode == AUDIO_PLAY_MODE_UNPAUSED && this->getGame()->timeManager.isPaused) {
|
||||
if(this->internalState == AUDIO_SOURCE_STATE_PLAYING) {
|
||||
// Functionally, this is the same as pausing
|
||||
alSourcePause(this->source);
|
||||
this->internalState = AUDIO_SOURCE_STATE_PAUSED;
|
||||
}
|
||||
return;// Do nothing else, at all.
|
||||
}
|
||||
|
||||
// They are trying to play. We need to check if we are already playing
|
||||
if(this->internalState == AUDIO_SOURCE_STATE_PLAYING) {
|
||||
// We are good to continue buffering audio data.
|
||||
buffersProcessed = 0;
|
||||
alGetSourcei(this->source, AL_BUFFERS_PROCESSED, &buffersProcessed);
|
||||
|
||||
while(buffersProcessed > 0) {
|
||||
alSourceUnqueueBuffers(this->source, 1, &bufferId);
|
||||
this->fillBuffer(bufferId);
|
||||
alSourceQueueBuffers(this->source, 1, &bufferId);
|
||||
buffersProcessed--;
|
||||
|
||||
// Now, before we go to the next buffer let's see if we need to
|
||||
// update the internal state
|
||||
if(this->bufferPosition != 0) continue;
|
||||
|
||||
// We reached the end of the buffer whilst filling. What to do now?
|
||||
if(this->loop) {
|
||||
// We're looping so it's fine
|
||||
this->eventLooped.invoke();
|
||||
continue;
|
||||
}
|
||||
|
||||
// We are NOT looping, so we need to finish here.
|
||||
this->state = AUDIO_SOURCE_STATE_STOPPED;
|
||||
this->eventFinished.invoke();
|
||||
this->bufferPosition = 0;
|
||||
buffersProcessed = 0;
|
||||
}
|
||||
} else if(this->internalState == AUDIO_SOURCE_STATE_STOPPED) {
|
||||
// Not yet playing. First thing we need to do is fill the buffers.
|
||||
for(int32_t i = 0; i < AUDIO_SOURCE_BUFFER_COUNT; i++) {
|
||||
this->fillBuffer(this->buffers[i]);
|
||||
}
|
||||
|
||||
// Now attach the buffers
|
||||
this->attachBuffers();
|
||||
|
||||
// And begin playing
|
||||
alSourcePlay(this->source);
|
||||
this->internalState = AUDIO_SOURCE_STATE_PLAYING;
|
||||
this->eventPlaying.invoke();
|
||||
|
||||
} else if(AUDIO_SOURCE_STATE_PAUSED) {
|
||||
// Request to resume
|
||||
alSourcePlay(this->source);
|
||||
this->eventResumed.invoke();
|
||||
this->internalState = AUDIO_SOURCE_STATE_PLAYING;
|
||||
|
||||
} else {
|
||||
assertUnreachable();
|
||||
}
|
||||
} else if(this->state == AUDIO_SOURCE_STATE_PAUSED) {
|
||||
assertTrue(this->data != nullptr);
|
||||
assertTrue(this->data->loaded);
|
||||
|
||||
// Pause has been requested.
|
||||
if(this->internalState != AUDIO_SOURCE_STATE_PLAYING) return;
|
||||
|
||||
// We are playing something, pause it
|
||||
alSourcePause(this->source);
|
||||
this->internalState = AUDIO_SOURCE_STATE_PAUSED;
|
||||
this->eventPaused.invoke();
|
||||
|
||||
} else if(this->state == AUDIO_SOURCE_STATE_STOPPED) {
|
||||
if(this->internalState == AUDIO_SOURCE_STATE_STOPPED) return;
|
||||
|
||||
assertTrue(this->data != nullptr);
|
||||
assertTrue(this->data->loaded);
|
||||
|
||||
// Release the buffers
|
||||
alSourceStop(this->source);
|
||||
this->detatchBuffers();
|
||||
this->internalState = AUDIO_SOURCE_STATE_STOPPED;
|
||||
this->eventStopped.invoke();
|
||||
this->bufferPosition = 0;
|
||||
|
||||
} else {
|
||||
assertUnreachable();
|
||||
}
|
||||
}, getScene()->eventSceneUpdate);
|
||||
}
|
||||
|
||||
AudioSourceState AudioSource::getRealState() {
|
||||
@ -128,14 +236,6 @@ void AudioSource::setAudioData(AudioAsset *data) {
|
||||
this->rewind();
|
||||
}
|
||||
|
||||
enum AudioSourcePlayMode AudioSource::getPlayMode() {
|
||||
return this->playMode;
|
||||
}
|
||||
|
||||
void AudioSource::setPlayMode(enum AudioSourcePlayMode playMode) {
|
||||
this->playMode = playMode;
|
||||
}
|
||||
|
||||
void AudioSource::stop() {
|
||||
this->state = AUDIO_SOURCE_STATE_STOPPED;
|
||||
}
|
||||
@ -152,117 +252,6 @@ void AudioSource::onDispose() {
|
||||
assertTrue(this->ready);
|
||||
this->ready = false;
|
||||
|
||||
this->getScene()->eventSceneUpdate.removeListener(this, &AudioSource::onSceneUpdate);
|
||||
this->transform->eventTransformUpdated.removeListener(this, &AudioSource::onTransformUpdate);
|
||||
|
||||
alDeleteSources((ALuint)1, &this->source);
|
||||
alDeleteBuffers((ALuint)AUDIO_SOURCE_BUFFER_COUNT, this->buffers);
|
||||
}
|
||||
|
||||
void AudioSource::onSceneUpdate() {
|
||||
ALuint bufferId;
|
||||
ALint buffersProcessed;
|
||||
|
||||
assertTrue(this->ready);
|
||||
|
||||
// What is the user trying to do?
|
||||
if(this->state == AUDIO_SOURCE_STATE_PLAYING) {
|
||||
assertTrue(this->data != nullptr);
|
||||
assertTrue(this->data->loaded);
|
||||
|
||||
// Handle the special game-paused music-paused state.
|
||||
if(this->playMode == AUDIO_PLAY_MODE_UNPAUSED && this->getGame()->timeManager.isPaused) {
|
||||
if(this->internalState == AUDIO_SOURCE_STATE_PLAYING) {
|
||||
// Functionally, this is the same as pausing
|
||||
alSourcePause(this->source);
|
||||
this->internalState = AUDIO_SOURCE_STATE_PAUSED;
|
||||
}
|
||||
return;// Do nothing else, at all.
|
||||
}
|
||||
|
||||
// They are trying to play. We need to check if we are already playing
|
||||
if(this->internalState == AUDIO_SOURCE_STATE_PLAYING) {
|
||||
// We are good to continue buffering audio data.
|
||||
buffersProcessed = 0;
|
||||
alGetSourcei(this->source, AL_BUFFERS_PROCESSED, &buffersProcessed);
|
||||
|
||||
while(buffersProcessed > 0) {
|
||||
alSourceUnqueueBuffers(this->source, 1, &bufferId);
|
||||
this->fillBuffer(bufferId);
|
||||
alSourceQueueBuffers(this->source, 1, &bufferId);
|
||||
buffersProcessed--;
|
||||
|
||||
// Now, before we go to the next buffer let's see if we need to
|
||||
// update the internal state
|
||||
if(this->bufferPosition != 0) continue;
|
||||
|
||||
// We reached the end of the buffer whilst filling. What to do now?
|
||||
if(this->loop) {
|
||||
// We're looping so it's fine
|
||||
this->eventLooped.invoke();
|
||||
continue;
|
||||
}
|
||||
|
||||
// We are NOT looping, so we need to finish here.
|
||||
this->state = AUDIO_SOURCE_STATE_STOPPED;
|
||||
this->eventFinished.invoke();
|
||||
this->bufferPosition = 0;
|
||||
buffersProcessed = 0;
|
||||
}
|
||||
} else if(this->internalState == AUDIO_SOURCE_STATE_STOPPED) {
|
||||
// Not yet playing. First thing we need to do is fill the buffers.
|
||||
for(int32_t i = 0; i < AUDIO_SOURCE_BUFFER_COUNT; i++) {
|
||||
this->fillBuffer(this->buffers[i]);
|
||||
}
|
||||
|
||||
// Now attach the buffers
|
||||
this->attachBuffers();
|
||||
|
||||
// And begin playing
|
||||
alSourcePlay(this->source);
|
||||
this->internalState = AUDIO_SOURCE_STATE_PLAYING;
|
||||
this->eventPlaying.invoke();
|
||||
|
||||
} else if(AUDIO_SOURCE_STATE_PAUSED) {
|
||||
// Request to resume
|
||||
alSourcePlay(this->source);
|
||||
this->eventResumed.invoke();
|
||||
this->internalState = AUDIO_SOURCE_STATE_PLAYING;
|
||||
|
||||
} else {
|
||||
assertUnreachable();
|
||||
}
|
||||
} else if(this->state == AUDIO_SOURCE_STATE_PAUSED) {
|
||||
assertTrue(this->data != nullptr);
|
||||
assertTrue(this->data->loaded);
|
||||
|
||||
// Pause has been requested.
|
||||
if(this->internalState != AUDIO_SOURCE_STATE_PLAYING) return;
|
||||
|
||||
// We are playing something, pause it
|
||||
alSourcePause(this->source);
|
||||
this->internalState = AUDIO_SOURCE_STATE_PAUSED;
|
||||
this->eventPaused.invoke();
|
||||
|
||||
} else if(this->state == AUDIO_SOURCE_STATE_STOPPED) {
|
||||
if(this->internalState == AUDIO_SOURCE_STATE_STOPPED) return;
|
||||
|
||||
assertTrue(this->data != nullptr);
|
||||
assertTrue(this->data->loaded);
|
||||
|
||||
// Release the buffers
|
||||
alSourceStop(this->source);
|
||||
this->detatchBuffers();
|
||||
this->internalState = AUDIO_SOURCE_STATE_STOPPED;
|
||||
this->eventStopped.invoke();
|
||||
this->bufferPosition = 0;
|
||||
|
||||
} else {
|
||||
assertUnreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSource::onTransformUpdate() {
|
||||
glm::vec3 position = this->transform->getWorldPosition();
|
||||
alSource3f(this->source, AL_POSITION, position.x, position.y, position.z);
|
||||
}
|
@ -34,7 +34,6 @@ namespace Dawn {
|
||||
enum AudioSourceState internalState = AUDIO_SOURCE_STATE_STOPPED;
|
||||
int32_t layer = 0;
|
||||
AudioAsset *data = nullptr;
|
||||
AudioSourcePlayMode playMode = AUDIO_PLAY_MODE_UNPAUSED;
|
||||
|
||||
/**
|
||||
* Internally update the audio's state based on the current settings.
|
||||
@ -47,11 +46,11 @@ namespace Dawn {
|
||||
|
||||
// Events
|
||||
void onSceneUpdate();
|
||||
void onTransformUpdate();
|
||||
|
||||
public:
|
||||
bool_t loop = false;
|
||||
enum AudioSourceState state = AUDIO_SOURCE_STATE_STOPPED;
|
||||
AudioSourcePlayMode playMode;
|
||||
|
||||
Event<> eventPlaying;
|
||||
Event<> eventResumed;
|
||||
@ -98,20 +97,6 @@ namespace Dawn {
|
||||
*/
|
||||
void setAudioData(AudioAsset *data);
|
||||
|
||||
/**
|
||||
* Returns the play mode for the source.
|
||||
*
|
||||
* @return Current play mode.
|
||||
*/
|
||||
enum AudioSourcePlayMode getPlayMode();
|
||||
|
||||
/**
|
||||
* Sets the play mode for the source.
|
||||
*
|
||||
* @param mode Play Mode to use.
|
||||
*/
|
||||
void setPlayMode(enum AudioSourcePlayMode mode);
|
||||
|
||||
/**
|
||||
* Stop playing this audio source. Shorthand for setting the state.
|
||||
*/
|
||||
|
@ -14,73 +14,67 @@ TicTacToeGame::TicTacToeGame(SceneItem *item) : SceneItemComponent(item) {}
|
||||
|
||||
void TicTacToeGame::onStart() {
|
||||
// Map tiles by tile number = tile
|
||||
auto tiles = getScene()->findComponents<TicTacToeTile>();
|
||||
auto itTiles = tiles.begin();
|
||||
while(itTiles != tiles.end()) {
|
||||
auto ts = getScene()->findComponents<TicTacToeTile>();
|
||||
auto itTiles = ts.begin();
|
||||
while(itTiles != ts.end()) {
|
||||
this->tiles[(*itTiles)->tile] = *itTiles;
|
||||
++itTiles;
|
||||
}
|
||||
|
||||
// Listen
|
||||
getScene()->eventSceneUpdate.addListener(this, &TicTacToeGame::onSceneUpdate);
|
||||
}
|
||||
useEvent([&](float_t delta) {
|
||||
// Get mouse in screen space.
|
||||
auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y);
|
||||
mouse *= 2.0f;
|
||||
mouse -= glm::vec2(1, 1);
|
||||
|
||||
void TicTacToeGame::onDispose() {
|
||||
getScene()->eventSceneUpdate.removeListener(this, &TicTacToeGame::onSceneUpdate);
|
||||
}
|
||||
Camera *camera = getScene()->findComponent<Camera>();
|
||||
if(camera == nullptr) return;
|
||||
|
||||
void TicTacToeGame::onSceneUpdate() {
|
||||
// Get mouse in screen space.
|
||||
auto mouse = getGame()->inputManager.getAxis2D(INPUT_BIND_MOUSE_X, INPUT_BIND_MOUSE_Y);
|
||||
mouse *= 2.0f;
|
||||
mouse -= glm::vec2(1, 1);
|
||||
|
||||
Camera *camera = getScene()->findComponent<Camera>();
|
||||
if(camera == nullptr) return;
|
||||
|
||||
struct Ray3D ray;
|
||||
ray.origin = camera->transform->getWorldPosition();
|
||||
ray.direction = camera->getRayDirectionFromScreenSpace(mouse);
|
||||
struct Ray3D ray;
|
||||
ray.origin = camera->transform->getWorldPosition();
|
||||
ray.direction = camera->getRayDirectionFromScreenSpace(mouse);
|
||||
|
||||
|
||||
// Find the hovered tile (if any)
|
||||
TicTacToeTile *hovered = nullptr;
|
||||
auto results = getPhysics()->raycast3DAll(ray);
|
||||
auto itResult = results.begin();
|
||||
while(itResult != results.end()) {
|
||||
auto result = *itResult;
|
||||
auto tile = result.collider->item->getComponent<TicTacToeTile>();
|
||||
if(tile == nullptr) {
|
||||
++itResult;
|
||||
continue;
|
||||
}
|
||||
|
||||
hovered = tile;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now update the state of each tile, also get the state while we are at it
|
||||
std::map<uint8_t, enum TicTacToeTileState> tileMap;
|
||||
|
||||
auto itTiles = tiles.begin();
|
||||
while(itTiles != tiles.end()) {
|
||||
auto t = itTiles->second;
|
||||
|
||||
if(t == hovered) {
|
||||
if(t->tileState == TIC_TAC_TOE_EMPTY && getGame()->inputManager.isPressed(INPUT_BIND_MOUSE_CLICK)) {
|
||||
t->tileState = nextMove;
|
||||
nextMove = nextMove == TIC_TAC_TOE_NOUGHT ? TIC_TAC_TOE_CROSS : TIC_TAC_TOE_NOUGHT;
|
||||
} else if(t->tileState == TIC_TAC_TOE_EMPTY) {
|
||||
t->hovered = true;
|
||||
// Find the hovered tile (if any)
|
||||
TicTacToeTile *hovered = nullptr;
|
||||
auto results = getPhysics()->raycast3DAll(ray);
|
||||
auto itResult = results.begin();
|
||||
while(itResult != results.end()) {
|
||||
auto result = *itResult;
|
||||
auto tile = result.collider->item->getComponent<TicTacToeTile>();
|
||||
if(tile == nullptr) {
|
||||
++itResult;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
t->hovered = false;
|
||||
}
|
||||
tileMap[itTiles->second->tile] = itTiles->second->tileState;
|
||||
++itTiles;
|
||||
}
|
||||
|
||||
// Determine winner
|
||||
std::vector<uint8_t> winningCombo;
|
||||
auto winner = ticTacToeDetermineWinner(tileMap, &winningCombo);
|
||||
hovered = tile;
|
||||
break;
|
||||
}
|
||||
|
||||
// Now update the state of each tile, also get the state while we are at it
|
||||
std::map<uint8_t, enum TicTacToeTileState> tileMap;
|
||||
|
||||
auto itTiles = tiles.begin();
|
||||
while(itTiles != tiles.end()) {
|
||||
auto t = itTiles->second;
|
||||
|
||||
if(t == hovered) {
|
||||
if(t->tileState == TIC_TAC_TOE_EMPTY && getGame()->inputManager.isPressed(INPUT_BIND_MOUSE_CLICK)) {
|
||||
t->tileState = nextMove;
|
||||
nextMove = nextMove == TIC_TAC_TOE_NOUGHT ? TIC_TAC_TOE_CROSS : TIC_TAC_TOE_NOUGHT;
|
||||
} else if(t->tileState == TIC_TAC_TOE_EMPTY) {
|
||||
t->hovered = true;
|
||||
}
|
||||
} else {
|
||||
t->hovered = false;
|
||||
}
|
||||
tileMap[itTiles->second->tile] = itTiles->second->tileState;
|
||||
++itTiles;
|
||||
}
|
||||
|
||||
// Determine winner
|
||||
std::vector<uint8_t> winningCombo;
|
||||
auto winner = ticTacToeDetermineWinner(tileMap, &winningCombo);
|
||||
}, getScene()->eventSceneUpdate);
|
||||
}
|
@ -17,8 +17,5 @@ namespace Dawn {
|
||||
TicTacToeGame(SceneItem *item);
|
||||
|
||||
void onStart() override;
|
||||
void onDispose() override;
|
||||
|
||||
void onSceneUpdate();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user