mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 02:40:00 +01:00
Unified use of std::future for loading sessions in Mixer and
SessionSource.
This commit is contained in:
33
Mixer.cpp
33
Mixer.cpp
@@ -20,43 +20,15 @@ using namespace tinyxml2;
|
|||||||
#include "SystemToolkit.h"
|
#include "SystemToolkit.h"
|
||||||
//#include "GarbageVisitor.h"
|
//#include "GarbageVisitor.h"
|
||||||
#include "SessionVisitor.h"
|
#include "SessionVisitor.h"
|
||||||
#include "SessionCreator.h"
|
|
||||||
#include "SessionSource.h"
|
#include "SessionSource.h"
|
||||||
#include "MediaSource.h"
|
#include "MediaSource.h"
|
||||||
|
|
||||||
#include "Mixer.h"
|
#include "Mixer.h"
|
||||||
|
|
||||||
#define THREADED_LOADING
|
#define THREADED_LOADING
|
||||||
|
|
||||||
// static semaphore to prevent multiple threads for load / save
|
|
||||||
static std::atomic<bool> sessionThreadActive_ = false;
|
|
||||||
|
|
||||||
static std::vector< std::future<Session *> > sessionLoaders_;
|
static std::vector< std::future<Session *> > sessionLoaders_;
|
||||||
static std::vector< std::future<Session *> > sessionImporters_;
|
static std::vector< std::future<Session *> > sessionImporters_;
|
||||||
static std::chrono::milliseconds timeout_ = std::chrono::milliseconds(4);
|
const std::chrono::milliseconds timeout_ = std::chrono::milliseconds(4);
|
||||||
|
|
||||||
// static multithreaded session loading
|
|
||||||
static Session *loadSession_(const std::string& filename)
|
|
||||||
{
|
|
||||||
Session *s = new Session;
|
|
||||||
|
|
||||||
if (s) {
|
|
||||||
// actual loading of xml file
|
|
||||||
SessionCreator creator( s );
|
|
||||||
|
|
||||||
if (creator.load(filename)) {
|
|
||||||
// loaded ok
|
|
||||||
s->setFilename(filename);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// error loading
|
|
||||||
delete s;
|
|
||||||
s = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// static multithreaded session saving
|
// static multithreaded session saving
|
||||||
@@ -586,9 +558,6 @@ void Mixer::save()
|
|||||||
|
|
||||||
void Mixer::saveas(const std::string& filename)
|
void Mixer::saveas(const std::string& filename)
|
||||||
{
|
{
|
||||||
if (sessionThreadActive_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// optional copy of views config
|
// optional copy of views config
|
||||||
session_->config(View::MIXING)->copyTransform( mixing_.scene.root() );
|
session_->config(View::MIXING)->copyTransform( mixing_.scene.root() );
|
||||||
session_->config(View::GEOMETRY)->copyTransform( geometry_.scene.root() );
|
session_->config(View::GEOMETRY)->copyTransform( geometry_.scene.root() );
|
||||||
|
|||||||
24
Session.cpp
24
Session.cpp
@@ -6,6 +6,7 @@
|
|||||||
#include "Session.h"
|
#include "Session.h"
|
||||||
#include "GarbageVisitor.h"
|
#include "GarbageVisitor.h"
|
||||||
#include "Recorder.h"
|
#include "Recorder.h"
|
||||||
|
#include "SessionCreator.h"
|
||||||
|
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
|
||||||
@@ -303,3 +304,26 @@ void Session::unlock()
|
|||||||
access_.unlock();
|
access_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Session *loadSession_(const std::string& filename)
|
||||||
|
{
|
||||||
|
Session *s = new Session;
|
||||||
|
|
||||||
|
if (s) {
|
||||||
|
// actual loading of xml file
|
||||||
|
SessionCreator creator( s );
|
||||||
|
|
||||||
|
if (creator.load(filename)) {
|
||||||
|
// loaded ok
|
||||||
|
s->setFilename(filename);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// error loading
|
||||||
|
delete s;
|
||||||
|
s = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,4 +85,7 @@ protected:
|
|||||||
std::mutex access_;
|
std::mutex access_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Session *loadSession_(const std::string& filename);
|
||||||
|
|
||||||
#endif // SESSION_H
|
#endif // SESSION_H
|
||||||
|
|||||||
@@ -18,26 +18,26 @@
|
|||||||
#include "Mixer.h"
|
#include "Mixer.h"
|
||||||
|
|
||||||
|
|
||||||
void SessionSource::loadSession(const std::string& filename, SessionSource *source)
|
//void SessionSource::loadSession(const std::string& filename, SessionSource *source)
|
||||||
{
|
//{
|
||||||
source->loadFinished_ = false;
|
// source->loadFinished_ = false;
|
||||||
|
|
||||||
// actual loading of xml file
|
// // actual loading of xml file
|
||||||
SessionCreator creator( source->session_ );
|
// SessionCreator creator( source->session_ );
|
||||||
|
|
||||||
if (creator.load(filename)) {
|
// if (creator.load(filename)) {
|
||||||
// all ok, validate session filename
|
// // all ok, validate session filename
|
||||||
source->session_->setFilename(filename);
|
// source->session_->setFilename(filename);
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
// error loading
|
// // error loading
|
||||||
Log::Notify("Failed to load Session file %s.", filename.c_str());
|
// Log::Notify("Failed to load Session file %s.", filename.c_str());
|
||||||
source->loadFailed_ = true;
|
// source->failed_ = true;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// end thread
|
// // end thread
|
||||||
source->loadFinished_ = true;
|
// source->loadFinished_ = true;
|
||||||
}
|
//}
|
||||||
|
|
||||||
SessionSource::SessionSource() : Source(), path_("")
|
SessionSource::SessionSource() : Source(), path_("")
|
||||||
{
|
{
|
||||||
@@ -69,11 +69,9 @@ SessionSource::SessionSource() : Source(), path_("")
|
|||||||
overlays_[View::TRANSITION]->attach(center);
|
overlays_[View::TRANSITION]->attach(center);
|
||||||
groups_[View::TRANSITION]->attach(overlays_[View::TRANSITION]);
|
groups_[View::TRANSITION]->attach(overlays_[View::TRANSITION]);
|
||||||
|
|
||||||
loadFailed_ = false;
|
failed_ = false;
|
||||||
loadFinished_ = true;
|
|
||||||
wait_for_sources_ = false;
|
wait_for_sources_ = false;
|
||||||
|
session_ = nullptr;
|
||||||
session_ = new Session;
|
|
||||||
|
|
||||||
// create surface:
|
// create surface:
|
||||||
// - textured with original texture from session
|
// - textured with original texture from session
|
||||||
@@ -97,8 +95,7 @@ void SessionSource::load(const std::string &p)
|
|||||||
path_ = p;
|
path_ = p;
|
||||||
|
|
||||||
// launch a thread to load the session
|
// launch a thread to load the session
|
||||||
loadFinished_ = false;
|
sessionLoader_ = std::async(std::launch::async, loadSession_, path_);
|
||||||
std::thread ( SessionSource::loadSession, path_, this).detach();
|
|
||||||
|
|
||||||
Log::Notify("Opening %s", p.c_str());
|
Log::Notify("Opening %s", p.c_str());
|
||||||
}
|
}
|
||||||
@@ -113,14 +110,14 @@ Session *SessionSource::detach()
|
|||||||
|
|
||||||
// make disabled
|
// make disabled
|
||||||
initialized_ = false;
|
initialized_ = false;
|
||||||
loadFailed_ = true;
|
failed_ = true;
|
||||||
|
|
||||||
return giveaway;
|
return giveaway;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionSource::failed() const
|
bool SessionSource::failed() const
|
||||||
{
|
{
|
||||||
return loadFailed_;
|
return failed_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint SessionSource::texture() const
|
uint SessionSource::texture() const
|
||||||
@@ -137,66 +134,71 @@ void SessionSource::replaceRenderingShader()
|
|||||||
|
|
||||||
void SessionSource::init()
|
void SessionSource::init()
|
||||||
{
|
{
|
||||||
if (session_ == nullptr)
|
// init is first about getting the loaded session
|
||||||
return;
|
if (session_ == nullptr) {
|
||||||
|
// did the loader finish ?
|
||||||
|
if (sessionLoader_.wait_for(std::chrono::milliseconds(4)) == std::future_status::ready) {
|
||||||
|
session_ = sessionLoader_.get();
|
||||||
|
if (session_ == nullptr)
|
||||||
|
failed_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
if (wait_for_sources_) {
|
if (wait_for_sources_) {
|
||||||
|
|
||||||
// force update of of all sources
|
// force update of of all sources
|
||||||
active_ = true;
|
active_ = true;
|
||||||
touch();
|
touch();
|
||||||
|
|
||||||
// check that every source is ready..
|
// check that every source is ready..
|
||||||
bool ready = true;
|
bool ready = true;
|
||||||
for (SourceList::iterator iter = session_->begin(); iter != session_->end(); iter++)
|
for (SourceList::iterator iter = session_->begin(); iter != session_->end(); iter++)
|
||||||
{
|
{
|
||||||
// interrupt if any source is NOT ready
|
// interrupt if any source is NOT ready
|
||||||
if ( !(*iter)->ready() ){
|
if ( !(*iter)->ready() ){
|
||||||
ready = false;
|
ready = false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if all sources are ready, done with initialization!
|
||||||
|
if (ready) {
|
||||||
|
// remove the loading icon
|
||||||
|
Node *loader = overlays_[View::TRANSITION]->back();
|
||||||
|
overlays_[View::TRANSITION]->detatch(loader);
|
||||||
|
delete loader;
|
||||||
|
// done init
|
||||||
|
wait_for_sources_ = false;
|
||||||
|
initialized_ = true;
|
||||||
|
Log::Info("Source Session %s loaded %d sources.", path_.c_str(), session_->numSource());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if all sources are ready, done with initialization!
|
else if ( !failed_ ) {
|
||||||
if (ready) {
|
|
||||||
// remove the loading icon
|
// set resolution
|
||||||
Node *loader = overlays_[View::TRANSITION]->back();
|
session_->setResolution( session_->config(View::RENDERING)->scale_ );
|
||||||
overlays_[View::TRANSITION]->detatch(loader);
|
|
||||||
delete loader;
|
// deep update once to draw framebuffer
|
||||||
// done init
|
View::need_deep_update_ = true;
|
||||||
wait_for_sources_ = false;
|
session_->update(dt_);
|
||||||
initialized_ = true;
|
|
||||||
Log::Info("Source Session %s loaded %d sources.", path_.c_str(), session_->numSource());
|
// get the texture index from framebuffer of session, apply it to the surface
|
||||||
|
sessionsurface_->setTextureIndex( session_->frame()->texture() );
|
||||||
|
|
||||||
|
// create Frame buffer matching size of session
|
||||||
|
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution());
|
||||||
|
|
||||||
|
// set the renderbuffer of the source and attach rendering nodes
|
||||||
|
attach(renderbuffer);
|
||||||
|
|
||||||
|
// icon in mixing view
|
||||||
|
overlays_[View::MIXING]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||||
|
overlays_[View::LAYER]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||||
|
|
||||||
|
// wait for all sources to init
|
||||||
|
wait_for_sources_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( loadFinished_ && !loadFailed_ && session_ != nullptr) {
|
|
||||||
loadFinished_ = false;
|
|
||||||
|
|
||||||
// set resolution
|
|
||||||
session_->setResolution( session_->config(View::RENDERING)->scale_ );
|
|
||||||
|
|
||||||
// deep update once to draw framebuffer
|
|
||||||
View::need_deep_update_ = true;
|
|
||||||
session_->update(dt_);
|
|
||||||
|
|
||||||
// get the texture index from framebuffer of session, apply it to the surface
|
|
||||||
sessionsurface_->setTextureIndex( session_->frame()->texture() );
|
|
||||||
|
|
||||||
// create Frame buffer matching size of session
|
|
||||||
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution());
|
|
||||||
|
|
||||||
// set the renderbuffer of the source and attach rendering nodes
|
|
||||||
attach(renderbuffer);
|
|
||||||
|
|
||||||
// icon in mixing view
|
|
||||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
|
||||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
|
||||||
|
|
||||||
// wait for all sources to init
|
|
||||||
wait_for_sources_ = true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionSource::setActive (bool on)
|
void SessionSource::setActive (bool on)
|
||||||
@@ -212,7 +214,7 @@ void SessionSource::setActive (bool on)
|
|||||||
void SessionSource::update(float dt)
|
void SessionSource::update(float dt)
|
||||||
{
|
{
|
||||||
if (session_ == nullptr)
|
if (session_ == nullptr)
|
||||||
loadFailed_ = true;
|
return;
|
||||||
|
|
||||||
// update content
|
// update content
|
||||||
if (active_)
|
if (active_)
|
||||||
@@ -223,7 +225,7 @@ void SessionSource::update(float dt)
|
|||||||
session_->deleteSource(session_->failedSource());
|
session_->deleteSource(session_->failedSource());
|
||||||
// fail session if all sources failed
|
// fail session if all sources failed
|
||||||
if ( session_->numSource() < 1)
|
if ( session_->numSource() < 1)
|
||||||
loadFailed_ = true;
|
failed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Source::update(dt);
|
Source::update(dt);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define SESSIONSOURCE_H
|
#define SESSIONSOURCE_H
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <future>
|
||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
|
|
||||||
class SessionSource : public Source
|
class SessionSource : public Source
|
||||||
@@ -35,9 +36,9 @@ protected:
|
|||||||
std::string path_;
|
std::string path_;
|
||||||
Session *session_;
|
Session *session_;
|
||||||
|
|
||||||
std::atomic<bool> loadFailed_;
|
std::atomic<bool> failed_;
|
||||||
std::atomic<bool> loadFinished_;
|
|
||||||
std::atomic<bool> wait_for_sources_;
|
std::atomic<bool> wait_for_sources_;
|
||||||
|
std::future<Session *> sessionLoader_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user