Commits

Wei Cheng Pan  committed 89f610d

Add disconnect handler.

  • Participants
  • Parent commits 961adf8
  • Branches develop

Comments (0)

Files changed (5)

File Krapture/server/src/TestUnit/TestUnit.cpp

 	server->connect( this, SIGNAL( inputReceived( int, int, const QString &, const QString &, const QStringList & ) ), SIGNAL( inputReceived( int, int, const QString &, const QString &, const QStringList & ) ) );
 }
 
+TestUnit::Private::~Private() {
+	if( this->socket ) {
+		if( this->socket->isValid() ) {
+			this->socket->disconnectFromServer();
+		}
+		this->socket->deleteLater();
+	}
+}
+
 void TestUnit::Private::onReadyRead() {
 	while( !this->socket->atEnd() ) {
 		auto packet = this->socket->read();
 	}
 }
 
-TestUnit::TestUnit( int id, SimpleSocket * socket, TestUnitServer * server, QObject * parent ): QObject( parent ), p_( new Private( id, socket, server ) ) {
+TestUnit::TestUnit( int id, SimpleSocket * socket, TestUnitServer * server, QObject * parent ):
+QObject( parent ),
+p_( new Private( id, socket, server ) ) {
+	this->connect( socket, SIGNAL( disconnected() ), SIGNAL( disconnected() ) );
 }
 
 bool TestUnit::check() const {

File Krapture/server/src/TestUnit/TestUnit.hpp

 class TestUnitServer;
 
 class TestUnit: public QObject {
+	Q_OBJECT
 public:
 	TestUnit( int id, SimpleSocket * socket, TestUnitServer * server, QObject * parent );
 
 	void recordOracle( const QString & label, const QString & value );
 	void sendInput( const QString & object, const QString & method, const QVariantList & args );
 
+signals:
+	void disconnected();
+
 private:
 	class Private;
 	std::shared_ptr< Private > p_;

File Krapture/server/src/TestUnit/TestUnitServer.cpp

 	while( this->server->hasPendingConnections() ) {
 		auto socket = this->server->nextPendingConntion();
 		auto testUnit = new TestUnit( this->clients.size(), socket, this->owner, this );
+		this->connect( testUnit, SIGNAL( disconnected() ), SLOT( onClientDisconnected() ) );
 		this->clients.push_back( testUnit );
 	}
 }
 
+void TestUnitServer::Private::onClientDisconnected() {
+	auto testUnit = qobject_cast< TestUnit * >( this->sender() );
+	auto it = std::remove( this->clients.begin(), this->clients.end(), testUnit );
+	if( it == this->clients.end() ) {
+		// why not found?
+		return;
+	}
+	std::for_each( it, this->clients.end(), []( TestUnit * tu )->void {
+		tu->deleteLater();
+	} );
+	this->clients.erase( it, this->clients.end() );
+}
+
 TestUnitServer::TestUnitServer( QObject * parent ): QObject( parent ), p_( new Private( this ) ) {
 }
 

File Krapture/server/src/TestUnit/TestUnitServer_p.hpp

 
 public slots:
 	void onNewConnection();
+	void onClientDisconnected();
 
 public:
 	TestUnitServer * owner;

File Krapture/server/src/TestUnit/TestUnit_p.hpp

 public:
 	typedef std::function< void ( const QVariant & ) > Command;
 
-	explicit Private( int id, SimpleSocket * socket, TestUnitServer * server );
+	Private( int id, SimpleSocket * socket, TestUnitServer * server );
+	virtual ~Private();
 
 public slots:
 	void onReadyRead();