/* === H E A D E R S ======================================================= */
/* === H E A D E R S ======================================================= */
+#include <sigc++/signal.h>
#include "string_decl.h"
#include <utility>
//#include <list>
#include "string_decl.h"
#include <utility>
//#include <list>
typedef etl::loose_handle<Target> LooseHandle;
typedef etl::handle<const Target> ConstHandle;
typedef etl::loose_handle<Target> LooseHandle;
typedef etl::handle<const Target> ConstHandle;
+ /*
+ -- ** -- S I G N A L S -------------------------------------------------------
+ */
+
+private:
+
+ sigc::signal<void> signal_progress_;
+
+ /*
+ -- ** -- S I G N A L I N T E R F A C E -------------------------------------
+ */
+
+public:
+
+ sigc::signal<void>& signal_progress() { return signal_progress_; }
+
+ /*
+ -- ** -- C O N S T R U C T O R S ---------------------------------------------
+ */
+
+public:
typedef Target* (*Factory)(const char *filename);
//! A type for a map of targets, indexed by the name of the Target
typedef Target* (*Factory)(const char *filename);
//! A type for a map of targets, indexed by the name of the Target
add_tile_time+=timer();
}
tile_timer.reset();
add_tile_time+=timer();
}
tile_timer.reset();
}
}
if(cb && !cb->amount_complete(total_tiles,total_tiles))
}
}
if(cb && !cb->amount_complete(total_tiles,total_tiles))
#endif
#include "asyncrenderer.h"
#endif
#include "asyncrenderer.h"
#include <glibmm/thread.h>
#include <glibmm/dispatcher.h>
#include <glibmm/thread.h>
#include <glibmm/dispatcher.h>
}
};
std::list<tile_t> tile_queue;
}
};
std::list<tile_t> tile_queue;
+#endif // SINGLE_THREADED
#ifndef GLIB_DISPATCHER_BROKEN
Glib::Dispatcher tile_ready_signal;
#ifndef GLIB_DISPATCHER_BROKEN
Glib::Dispatcher tile_ready_signal;
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
assert(surface);
if(!alive_flag)
return false;
assert(surface);
if(!alive_flag)
return false;
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
tile_queue.push_back(tile_t(surface,gx,gy));
if(tile_queue.size()==1)
{
tile_queue.push_back(tile_t(surface,gx,gy));
if(tile_queue.size()==1)
{
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
if(!alive_flag)
{
tile_queue.clear();
if(!alive_flag)
{
tile_queue.clear();
virtual void end_frame()
{
virtual void end_frame()
{
while(alive_flag)
{
Glib::Mutex::Lock lock(mutex);
while(alive_flag)
{
Glib::Mutex::Lock lock(mutex);
break;
}
Glib::Mutex::Lock lock(mutex);
break;
}
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
if(!alive_flag)
return;
return warm_target->end_frame();
if(!alive_flag)
return;
return warm_target->end_frame();
int scanline_;
Surface surface;
int scanline_;
Surface surface;
+#endif // SINGLE_THREADED
#ifndef GLIB_DISPATCHER_BROKEN
Glib::Dispatcher frame_ready_signal;
#ifndef GLIB_DISPATCHER_BROKEN
Glib::Dispatcher frame_ready_signal;
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
virtual void end_frame()
{
{
virtual void end_frame()
{
{
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
while(alive_flag && !ready_next)
{
Glib::Mutex::Lock lock(mutex);
if(cond_frame_queue_empty.timed_wait(mutex,Glib::TimeVal(0,BOREDOM_TIMEOUT)))
break;
}
while(alive_flag && !ready_next)
{
Glib::Mutex::Lock lock(mutex);
if(cond_frame_queue_empty.timed_wait(mutex,Glib::TimeVal(0,BOREDOM_TIMEOUT)))
break;
}
+#endif // SINGLE_THREADED
}
virtual Color * start_scanline(int scanline)
{
}
virtual Color * start_scanline(int scanline)
{
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
return surface[scanline];
}
return surface[scanline];
}
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
if(alive_flag)
alive_flag=warm_target->add_frame(&surface);
cond_frame_queue_empty.signal();
if(alive_flag)
alive_flag=warm_target->add_frame(&surface);
cond_frame_queue_empty.signal();
error(false),
success(false),
cb(cb)
error(false),
success(false),
cb(cb)
+#ifdef SINGLE_THREADED
+ , updating(false)
+#endif // SINGLE_THREADED
{
render_thread=0;
if(etl::handle<synfig::Target_Tile>::cast_dynamic(target_))
{
render_thread=0;
if(etl::handle<synfig::Target_Tile>::cast_dynamic(target_))
Glib::Mutex::Lock lock(mutex);
Glib::Mutex::Lock lock(mutex);
+#endif // SINGLE_THREADED
done_connection.disconnect();
if(render_thread)
{
signal_stop_();
done_connection.disconnect();
if(render_thread)
{
signal_stop_();
#if REJOIN_ON_STOP
render_thread->join();
#endif
#if REJOIN_ON_STOP
render_thread->join();
#endif
// Make sure all the dispatch crap is cleared out
//Glib::MainContext::get_default()->iteration(false);
// Make sure all the dispatch crap is cleared out
//Glib::MainContext::get_default()->iteration(false);
+#ifdef SINGLE_THREADED
+void
+AsyncRenderer::rendering_progress()
+{
+ updating = true;
+ while(studio::App::events_pending()) studio::App::iteration(false);
+ updating = false;
+}
+#endif // SINGLE_THREADED
+
void
AsyncRenderer::start_()
{
void
AsyncRenderer::start_()
{
done_connection=signal_done_.connect(mem_fun(*this,&AsyncRenderer::stop));
#endif
done_connection=signal_done_.connect(mem_fun(*this,&AsyncRenderer::stop));
#endif
+#ifdef SINGLE_THREADED
+ target->signal_progress().connect(sigc::mem_fun(this,&AsyncRenderer::rendering_progress));
+ render_thread = (Glib::Thread*)1;
+ render_target();
+#else // SINGLE_THREADED
render_thread=Glib::Thread::create(
sigc::mem_fun(*this,&AsyncRenderer::render_target),
#if REJOIN_ON_STOP
render_thread=Glib::Thread::create(
sigc::mem_fun(*this,&AsyncRenderer::render_target),
#if REJOIN_ON_STOP
#endif
);
assert(render_thread);
#endif
);
assert(render_thread);
+#endif // SINGLE_THREADED
+#endif // SINGLE_THREADED
{
#ifdef GLIB_DISPATCHER_BROKEN
done_connection=Glib::signal_timeout().connect(
{
#ifdef GLIB_DISPATCHER_BROKEN
done_connection=Glib::signal_timeout().connect(
#else
signal_done_.emit();
#endif
#else
signal_done_.emit();
#endif
+#endif // SINGLE_THREADED
/* === M A C R O S ========================================================= */
/* === M A C R O S ========================================================= */
+#define SINGLE_THREADED
+
/* === T Y P E D E F S ===================================================== */
/* === C L A S S E S & S T R U C T S ======================================= */
/* === T Y P E D E F S ===================================================== */
/* === C L A S S E S & S T R U C T S ======================================= */
bool has_error()const { return error; }
bool has_success()const { return success; }
bool has_error()const { return error; }
bool has_success()const { return success; }
+#ifdef SINGLE_THREADED
+ bool updating;
+#endif // SINGLE_THREADED
sigc::signal<void>& signal_finished() { return signal_finished_; }
sigc::signal<void>& signal_success() { return signal_success_; }
sigc::signal<void>& signal_finished() { return signal_finished_; }
sigc::signal<void>& signal_success() { return signal_success_; }
void render_target();
void start_();
void render_target();
void start_();
+ void rendering_progress();
/*
-- ** -- C H I L D M E M B E R S -------------------------------------------
/*
-- ** -- C H I L D M E M B E R S -------------------------------------------
bool
studio::WorkArea::async_update_preview()
{
bool
studio::WorkArea::async_update_preview()
{
+ if (async_renderer && async_renderer->updating == true)
+ {
+ async_renderer->stop();
+ return false;
+ }
+
async_renderer=0;
queued=false;
async_renderer=0;
queued=false;