1/***************************************************************************
2 * Copyright (C) 2005-2014 by the Quassel Project *
3 * devel@quassel-irc.org *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) version 3. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
20
21#include "core.h"
22#include "coresession.h"
23#include "internalpeer.h"
24#include "remotepeer.h"
25#include "sessionthread.h"
26#include "signalproxy.h"
27
28SessionThread::SessionThread(UserId uid, bool restoreState, QObject *parent)
29 : QThread(parent),
30 _session(0),
31 _user(uid),
32 _sessionInitialized(false),
33 _restoreState(restoreState)
34{
35 connect(this, SIGNAL(initialized()), this, SLOT(setSessionInitialized()));
36}
37
38
39SessionThread::~SessionThread()
40{
41 // shut down thread gracefully
42 quit();
43 wait();
44}
45
46
47CoreSession *SessionThread::session()
48{
49 return _session;
50}
51
52
53UserId SessionThread::user()
54{
55 return _user;
56}
57
58
59bool SessionThread::isSessionInitialized()
60{
61 return _sessionInitialized;
62}
63
64
65void SessionThread::setSessionInitialized()
66{
67 _sessionInitialized = true;
68 foreach(QObject *peer, clientQueue) {
69 addClientToSession(peer);
70 }
71 clientQueue.clear();
72}
73
74
75// this and the following related methods are executed in the Core thread!
76void SessionThread::addClient(QObject *peer)
77{
78 if (isSessionInitialized()) {
79 addClientToSession(peer);
80 }
81 else {
82 clientQueue.append(peer);
83 }
84}
85
86
87void SessionThread::addClientToSession(QObject *peer)
88{
89 RemotePeer *remote = qobject_cast<RemotePeer *>(peer);
90 if (remote) {
91 addRemoteClientToSession(remote);
92 return;
93 }
94
95 InternalPeer *internal = qobject_cast<InternalPeer *>(peer);
96 if (internal) {
97 addInternalClientToSession(internal);
98 return;
99 }
100
101 qWarning() << "SessionThread::addClient() received invalid peer!" << peer;
102}
103
104
105void SessionThread::addRemoteClientToSession(RemotePeer *remotePeer)
106{
107 remotePeer->setParent(0);
108 remotePeer->moveToThread(session()->thread());
109 emit addRemoteClient(remotePeer);
110}
111
112
113void SessionThread::addInternalClientToSession(InternalPeer *internalPeer)
114{
115 internalPeer->setParent(0);
116 internalPeer->moveToThread(session()->thread());
117 emit addInternalClient(internalPeer);
118}
119
120
121void SessionThread::run()
122{
123 _session = new CoreSession(user(), _restoreState);
124 connect(this, SIGNAL(addRemoteClient(RemotePeer*)), _session, SLOT(addClient(RemotePeer*)));
125 connect(this, SIGNAL(addInternalClient(InternalPeer*)), _session, SLOT(addClient(InternalPeer*)));
126 connect(_session, SIGNAL(sessionState(Protocol::SessionState)), Core::instance(), SIGNAL(sessionState(Protocol::SessionState)));
127 emit initialized();
128 exec();
129 delete _session;
130}
131