mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-14 10:36:34 +01:00
More missing stuff...
git-svn-id: svn://localhost/ardour2/trunk@2645 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
a313924b77
commit
aa6faa86b5
32 changed files with 5856 additions and 0 deletions
197
libs/glibmm2/examples/thread/dispatcher.cc
Normal file
197
libs/glibmm2/examples/thread/dispatcher.cc
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Glib::Dispatcher example -- cross thread signalling
|
||||
* by Daniel Elstner <daniel.elstner@gmx.net>
|
||||
*
|
||||
* modified to only use glibmm
|
||||
* by J. Abelardo Gutierrez <jabelardo@cantv.net>
|
||||
*
|
||||
* Copyright (c) 2002-2003 Free Software Foundation
|
||||
*/
|
||||
|
||||
#include <glibmm.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class ThreadProgress : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
explicit ThreadProgress(int id);
|
||||
virtual ~ThreadProgress();
|
||||
|
||||
void launch();
|
||||
void join();
|
||||
|
||||
sigc::signal<void>& signal_finished();
|
||||
int id() const;
|
||||
|
||||
virtual void reference() const { ++ref_count_; }
|
||||
virtual void unreference() const { if (!(--ref_count_)) delete this; }
|
||||
|
||||
private:
|
||||
Glib::Thread* thread_;
|
||||
int id_;
|
||||
unsigned int progress_;
|
||||
Glib::Dispatcher signal_increment_;
|
||||
sigc::signal<void> signal_finished_;
|
||||
|
||||
void progress_increment();
|
||||
void thread_function();
|
||||
|
||||
mutable int ref_count_;
|
||||
|
||||
};
|
||||
|
||||
class Application : public sigc::trackable
|
||||
{
|
||||
public:
|
||||
Application();
|
||||
virtual ~Application();
|
||||
|
||||
void launch_threads();
|
||||
void run();
|
||||
|
||||
private:
|
||||
Glib::RefPtr<Glib::MainLoop> main_loop_;
|
||||
std::list<ThreadProgress*> progress_list_;
|
||||
std::list<Glib::RefPtr<ThreadProgress> > progress_ref_list_;
|
||||
|
||||
void on_progress_finished(ThreadProgress* thread_progress);
|
||||
};
|
||||
|
||||
|
||||
ThreadProgress::ThreadProgress(int id)
|
||||
:
|
||||
thread_ (0),
|
||||
id_ (id),
|
||||
progress_ (0),
|
||||
ref_count_(0)
|
||||
{
|
||||
// Increment the reference count
|
||||
reference();
|
||||
// Connect to the cross-thread signal.
|
||||
signal_increment_.connect(sigc::mem_fun(*this, &ThreadProgress::progress_increment));
|
||||
}
|
||||
|
||||
ThreadProgress::~ThreadProgress()
|
||||
{}
|
||||
|
||||
void ThreadProgress::launch()
|
||||
{
|
||||
// Create a joinable thread.
|
||||
thread_ = Glib::Thread::create(sigc::mem_fun(*this, &ThreadProgress::thread_function), true);
|
||||
}
|
||||
|
||||
void ThreadProgress::join()
|
||||
{
|
||||
thread_->join();
|
||||
}
|
||||
|
||||
sigc::signal<void>& ThreadProgress::signal_finished()
|
||||
{
|
||||
return signal_finished_;
|
||||
}
|
||||
|
||||
int ThreadProgress::id() const
|
||||
{
|
||||
return id_;
|
||||
}
|
||||
|
||||
void ThreadProgress::progress_increment()
|
||||
{
|
||||
// Use an integer because floating point arithmetic is inaccurate --
|
||||
// we want to finish *exactly* after the 100th increment.
|
||||
++progress_;
|
||||
|
||||
std::cout << "Thread " << id_ << ": " << progress_ << '%' << std::endl;
|
||||
|
||||
if(progress_ >= 100)
|
||||
signal_finished_();
|
||||
}
|
||||
|
||||
void ThreadProgress::thread_function()
|
||||
{
|
||||
Glib::Rand rand;
|
||||
int usecs = 5000;
|
||||
|
||||
for(int i = 0; i < 100; ++i)
|
||||
{
|
||||
usecs = rand.get_int_range(std::max(0, usecs - 1000 - i), std::min(20000, usecs + 1000 + i));
|
||||
Glib::usleep(usecs);
|
||||
|
||||
// Tell the main thread to increment the progress value.
|
||||
signal_increment_();
|
||||
}
|
||||
}
|
||||
|
||||
Application::Application()
|
||||
:
|
||||
main_loop_ (Glib::MainLoop::create())
|
||||
{
|
||||
std::cout << "Thread Dispatcher Example." << std::endl;
|
||||
|
||||
for(int i = 1; i <= 5; ++i)
|
||||
{
|
||||
ThreadProgress* progress=new ThreadProgress(i);
|
||||
progress_list_.push_back(progress);
|
||||
progress_ref_list_.push_back(Glib::RefPtr<ThreadProgress>(progress));
|
||||
|
||||
progress->signal_finished().connect(
|
||||
sigc::bind<1>(sigc::mem_fun(*this, &Application::on_progress_finished), progress));
|
||||
}
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
}
|
||||
|
||||
void Application::launch_threads()
|
||||
{
|
||||
std::for_each(progress_list_.begin(), progress_list_.end(),
|
||||
std::mem_fun(&ThreadProgress::launch));
|
||||
}
|
||||
|
||||
void Application::run()
|
||||
{
|
||||
main_loop_->run();
|
||||
}
|
||||
|
||||
void Application::on_progress_finished(ThreadProgress* thread_progress)
|
||||
{
|
||||
{
|
||||
progress_list_.remove(thread_progress);
|
||||
thread_progress->join();
|
||||
|
||||
std::cout << "Thread " << thread_progress->id()
|
||||
<< ": finished." << std::endl;
|
||||
}
|
||||
|
||||
if(progress_list_.empty())
|
||||
main_loop_->quit();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
Glib::thread_init();
|
||||
|
||||
Application application;
|
||||
|
||||
// Install a one-shot idle handler to launch the threads
|
||||
Glib::signal_idle().connect(
|
||||
sigc::bind_return(sigc::mem_fun(application, &Application::launch_threads), false));
|
||||
|
||||
application.run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue