Skip to content
This repository has been archived by the owner on Sep 4, 2021. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
AnyActor is renamed to Actor and it uses PImpl
Signed-off-by: Denis Zalevskiy <denis.zalevskiy@jolla.com>
  • Loading branch information
Denis Zalevskiy committed Jan 12, 2015
1 parent 28e8e37 commit 187e04f
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 51 deletions.
64 changes: 29 additions & 35 deletions include/qtaround/mt.hpp
Expand Up @@ -13,71 +13,65 @@

namespace qtaround { namespace mt {

class AnyActor;
typedef std::shared_ptr<AnyActor> AnyActorHandle;
class Actor;

class ActorContext : public QObject
{
Q_OBJECT
public:
typedef std::function<UNIQUE_PTR(QObject) ()> ctor_type;
typedef std::function<void (AnyActorHandle)>callback_type;
ActorContext(AnyActorHandle actor, ctor_type ctor, callback_type cb)
: actor_(actor), ctor_(ctor), notify_(cb)
{}

AnyActorHandle actor_;
ctor_type ctor_;
callback_type notify_;
};
typedef std::shared_ptr<Actor> ActorHandle;
typedef std::function<UNIQUE_PTR(QObject) ()> qobj_ctor_type;
typedef std::function<void (ActorHandle)> actor_callback_type;

class AnyActor : public QThread
class ActorImpl;

class Actor : public QObject
{
Q_OBJECT
protected:
virtual ~AnyActor();

void run() Q_DECL_OVERRIDE;

public:
AnyActor(QObject *parent) : QThread(parent) {}
Actor(QObject *parent);
virtual ~Actor();

AnyActor(AnyActor const&) = delete;
AnyActor& operator = (AnyActor const&) = delete;
Actor(Actor const&) = delete;
Actor& operator = (Actor const&) = delete;

static void create(ActorContext::ctor_type
, ActorContext::callback_type
static void create(qobj_ctor_type
, actor_callback_type
, QObject *parent = nullptr);

static AnyActorHandle createSync
(ActorContext::ctor_type, QObject *parent = nullptr);
static ActorHandle createSync
(qobj_ctor_type, QObject *parent = nullptr);

bool postEvent(QEvent *);
bool sendEvent(QEvent *);
void quit();

signals:
void finished();

private:
std::shared_ptr<QObject> obj_;
friend class ActorImpl;
ActorImpl *impl_;
};

template <typename T> void startActor
template <typename T>
void startActor
(std::function<UNIQUE_PTR(T) ()> ctor
, ActorContext::callback_type cb, QObject *parent = nullptr
, actor_callback_type cb
, QObject *parent = nullptr
, typename std::enable_if<std::is_convertible<T*, QObject*>::value>::type* = 0)
{
auto qobj_ctor = [ctor]() {
return static_cast_qobject_unique<QObject>(ctor());
};
AnyActor::create(qobj_ctor, cb, parent);
Actor::create(qobj_ctor, cb, parent);
}

template <typename T> AnyActorHandle startActorSync
template <typename T>
ActorHandle startActorSync
(std::function<UNIQUE_PTR(T) ()> ctor, QObject *parent = nullptr
, typename std::enable_if<std::is_convertible<T*, QObject*>::value>::type* = 0)
{
auto qobj_ctor = [ctor]() {
return static_cast_qobject_unique<QObject>(ctor());
};
return AnyActor::createSync(qobj_ctor, parent);
return Actor::createSync(qobj_ctor, parent);
}

}}
Expand Down
102 changes: 89 additions & 13 deletions src/mt.cpp
Expand Up @@ -12,7 +12,84 @@

namespace qtaround { namespace mt {

AnyActor::~AnyActor()
class Actor;

class ActorContext : public QObject
{
Q_OBJECT
public:
ActorContext(ActorHandle actor
, qobj_ctor_type ctor
, actor_callback_type cb)
: actor_(actor), ctor_(ctor), notify_(cb)
{}

ActorHandle actor_;
qobj_ctor_type ctor_;
actor_callback_type notify_;
};

class ActorImpl : public QThread
{
Q_OBJECT
protected:
virtual ~ActorImpl();

void run() Q_DECL_OVERRIDE;

public:
ActorImpl(QObject *parent) : QThread(parent) {}

ActorImpl(ActorImpl const&) = delete;
ActorImpl& operator = (ActorImpl const&) = delete;

static void create(qobj_ctor_type, actor_callback_type, QObject *);
static ActorHandle createSync(qobj_ctor_type, QObject *parent);

bool postEvent(QEvent *);
bool sendEvent(QEvent *);

private:
std::shared_ptr<QObject> obj_;
};

Actor::Actor(QObject *parent)
: QObject(parent), impl_(new ActorImpl(this))
{
connect(impl_, &QThread::finished
, this, &Actor::finished
, Qt::DirectConnection);
}

Actor::~Actor()
{}

void Actor::quit()
{
impl_->quit();
}

void Actor::create(qobj_ctor_type ctor, actor_callback_type cb, QObject *parent)
{
ActorImpl::create(ctor, cb, parent);
}

ActorHandle Actor::createSync(qobj_ctor_type ctor, QObject *parent)
{
return ActorImpl::createSync(ctor, parent);
}

bool Actor::postEvent(QEvent *e)
{
return impl_->postEvent(e);
}

bool Actor::sendEvent(QEvent *e)
{
return impl_->sendEvent(e);
}

ActorImpl::~ActorImpl()
{
auto app = QCoreApplication::instance();
if (app) {
Expand All @@ -27,7 +104,7 @@ AnyActor::~AnyActor()
, QThread::currentThread(), ", Need:", this);
}

void AnyActor::run()
void ActorImpl::run()
{
auto ctx = std::static_pointer_cast<ActorContext>(std::move(obj_));
obj_ = ctx->ctor_();
Expand All @@ -36,7 +113,7 @@ void AnyActor::run()
obj_.reset();
}

bool AnyActor::postEvent(QEvent *e)
bool ActorImpl::postEvent(QEvent *e)
{
auto obj = obj_;

Expand All @@ -49,7 +126,7 @@ bool AnyActor::postEvent(QEvent *e)
}
}

bool AnyActor::sendEvent(QEvent *e)
bool ActorImpl::sendEvent(QEvent *e)
{
auto obj = obj_;
if (obj) {
Expand All @@ -60,25 +137,24 @@ bool AnyActor::sendEvent(QEvent *e)
}
}

void AnyActor::create
(ActorContext::ctor_type ctor, ActorContext::callback_type cb
, QObject *parent)
void ActorImpl::create(qobj_ctor_type ctor, actor_callback_type cb
, QObject *parent)
{
auto self = make_qobject_shared<AnyActor>(parent);
auto wrapper = make_qobject_shared<Actor>(parent);
auto self = wrapper->impl_;
auto ctx = make_qobject_unique<ActorContext>
(self, std::move(ctor), std::move(cb));
(wrapper, std::move(ctor), std::move(cb));
self->obj_ = qobject_shared_cast(std::move(ctx));
self->start();
}

AnyActorHandle AnyActor::createSync
(ActorContext::ctor_type ctor, QObject *parent)
ActorHandle ActorImpl::createSync(qobj_ctor_type ctor, QObject *parent)
{
std::mutex mutex;
std::condition_variable cond;
AnyActorHandle result;
ActorHandle result;
std::unique_lock<std::mutex> l(mutex);
create(ctor, [&](mt::AnyActorHandle p) {
create(ctor, [&](mt::ActorHandle p) {
std::unique_lock<std::mutex> l(mutex);
result = p;
cond.notify_all();
Expand Down
6 changes: 3 additions & 3 deletions tests/mt.cpp
Expand Up @@ -73,13 +73,13 @@ void object::test<tid_actor>()
auto main_thread = QThread::currentThread();
decltype(main_thread) actor_thread = nullptr;

mt::AnyActorHandle actor;
mt::ActorHandle actor;
std::mutex mutex;
std::condition_variable cond;
auto make_test = []() { return make_qobject_unique<Test>(); };
do {
std::unique_lock<std::mutex> l(mutex);
mt::startActor<Test>(make_test, [&](mt::AnyActorHandle a) {
mt::startActor<Test>(make_test, [&](mt::ActorHandle a) {
actor_thread = QThread::currentThread();
std::unique_lock<std::mutex> l(mutex);
actor = a;
Expand All @@ -94,7 +94,7 @@ void object::test<tid_actor>()

std::condition_variable exit_cond;
auto isExited = false;
QObject::connect(actor.get(), &QThread::finished, [&]() {
QObject::connect(actor.get(), &mt::Actor::finished, [&]() {
std::unique_lock<std::mutex> l(mutex);
isExited = true;
exit_cond.notify_all();
Expand Down

0 comments on commit 187e04f

Please sign in to comment.