Skip to content

Commit

Permalink
Merge pull request #18 from rdumusc/master
Browse files Browse the repository at this point in the history
Allow Streams to register for events without waiting for window creat…
  • Loading branch information
Raphael Dumusc committed May 12, 2015
2 parents fc6bfa0 + ebf125f commit eb08399
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 87 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ include(GitExternal)

set(VERSION_MAJOR "0")
set(VERSION_MINOR "5")
set(VERSION_PATCH "0")
set(VERSION_PATCH "1")
set(VERSION_ABI 1)

set(DEFLECT_DESCRIPTION
Expand Down
3 changes: 2 additions & 1 deletion apps/DesktopStreamer/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ void MainWindow::startStreaming()
handleStreamingError("Could not connect to host!");
return;
}
stream_->registerForEvents();

#ifdef __APPLE__
napSuspender_.suspend();
Expand Down Expand Up @@ -268,7 +269,7 @@ void MainWindow::processStreamEvents()
{
if( !eventsBox_.checkState( ))
return;
if( !stream_->isRegisteredForEvents() && !stream_->registerForEvents( ))
if( !stream_->isRegisteredForEvents( ))
return;

while( stream_->hasEvent( ))
Expand Down
75 changes: 40 additions & 35 deletions apps/SimpleStreamer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,20 @@ void initGLWindow(int argc, char **argv)
void initDeflectStream()
{
// connect to DisplayCluster
deflectStream = new deflect::Stream(deflectStreamName, deflectHostname);
if (!deflectStream->isConnected())
deflectStream = new deflect::Stream( deflectStreamName, deflectHostname );
if( !deflectStream->isConnected( ))
{
std::cerr << "Could not connect to host!" << std::endl;
delete deflectStream;
exit(1);
}

if( deflectInteraction && !deflectStream->registerForEvents( ))
{
std::cerr << "Could not register for events!" << std::endl;
delete deflectStream;
exit(1);
}
}


Expand Down Expand Up @@ -183,58 +190,56 @@ void display()
deflectImage.compressionPolicy = deflectCompressImage ? deflect::COMPRESSION_ON : deflect::COMPRESSION_OFF;
deflectImage.compressionQuality = deflectCompressionQuality;
deflect::ImageWrapper::swapYAxis((void*)imageData, windowWidth, windowHeight, 4);
bool success = deflectStream->send(deflectImage);
const bool success = deflectStream->send(deflectImage);
deflectStream->finishFrame();

// and free the allocated image data
delete [] imageData;

glutSwapBuffers();

// increment rotation angle according to interaction, or by a constant rate if interaction is not enabled
// note that mouse position is in normalized window coordinates: (0,0) to (1,1)
if(deflectInteraction)
// increment rotation angle according to interaction, or by a constant rate
// if interaction is not enabled. Note that mouse position is in normalized
// window coordinates: (0,0) to (1,1).
if( deflectStream->isRegisteredForEvents( ))
{
if (deflectStream->isRegisteredForEvents() || deflectStream->registerForEvents())
static float mouseX = 0.;
static float mouseY = 0.;

// Note: there is a risk of missing events since we only process the
// latest state available. For more advanced applications, event
// processing should be done in a separate thread.
while( deflectStream->hasEvent( ))
{
static float mouseX = 0.;
static float mouseY = 0.;
const deflect::Event& event = deflectStream->getEvent();

// Note: there is a risk of missing events since we only process the latest state available.
// For more advanced applications, event processing should be done in a separate thread.
while (deflectStream->hasEvent())
if( event.type == deflect::Event::EVT_CLOSE )
{
const deflect::Event& event = deflectStream->getEvent();

if (event.type == deflect::Event::EVT_CLOSE)
{
std::cout << "Received close..." << std::endl;
exit(0);
}

const float newMouseX = event.mouseX;
const float newMouseY = event.mouseY;

if(event.mouseLeft)
{
angleX += (newMouseX - mouseX) * 360.;
angleY += (newMouseY - mouseY) * 360.;
}
else if(event.mouseRight)
{
zoom += (newMouseY - mouseY);
}

mouseX = newMouseX;
mouseY = newMouseY;
std::cout << "Received close..." << std::endl;
exit(0);
}

const float newMouseX = event.mouseX;
const float newMouseY = event.mouseY;

if( event.mouseLeft )
{
angleX += (newMouseX - mouseX) * 360.;
angleY += (newMouseY - mouseY) * 360.;
}
else if( event.mouseRight )
zoom += (newMouseY - mouseY);

mouseX = newMouseX;
mouseY = newMouseY;
}
}
else
{
angleX += 1.;
angleY += 1.;
}

if(!success)
{
if (!deflectStream->isConnected())
Expand Down
2 changes: 1 addition & 1 deletion deflect/PixelStreamBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace deflect

PixelStreamBuffer::PixelStreamBuffer()
: lastFrameComplete_(0)
, allowedToSend_(false)
, allowedToSend_(true)
{
}

Expand Down
80 changes: 38 additions & 42 deletions deflect/PixelStreamDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,96 +40,92 @@
#include "PixelStreamDispatcher.h"
#include "PixelStreamFrame.h"

#define STREAM_WINDOW_DEFAULT_SIZE 100

namespace deflect
{

PixelStreamDispatcher::PixelStreamDispatcher()
{
}

void PixelStreamDispatcher::addSource(const QString uri, const size_t sourceIndex)
void PixelStreamDispatcher::addSource( const QString uri,
const size_t sourceIndex )
{
streamBuffers_[uri].addSource(sourceIndex);
streamBuffers_[uri].addSource( sourceIndex );

if( streamBuffers_[uri].getSourceCount() == 1 )
emit openPixelStream( uri );
}

void PixelStreamDispatcher::removeSource(const QString uri, const size_t sourceIndex)
void PixelStreamDispatcher::removeSource( const QString uri,
const size_t sourceIndex )
{
if(!streamBuffers_.count(uri))
if( !streamBuffers_.count( uri ))
return;

streamBuffers_[uri].removeSource(sourceIndex);
streamBuffers_[uri].removeSource( sourceIndex );

if (streamBuffers_[uri].getSourceCount() == 0)
{
deleteStream(uri);
}
if( streamBuffers_[uri].getSourceCount() == 0 )
deleteStream( uri );
}

void PixelStreamDispatcher::processSegment(const QString uri, const size_t sourceIndex, PixelStreamSegment segment)
void PixelStreamDispatcher::processSegment( const QString uri,
const size_t sourceIndex,
PixelStreamSegment segment )
{
if (streamBuffers_.count(uri))
streamBuffers_[uri].insertSegment(segment, sourceIndex);
if( streamBuffers_.count( uri ))
streamBuffers_[uri].insertSegment( segment, sourceIndex );
}

void PixelStreamDispatcher::processFrameFinished(const QString uri, const size_t sourceIndex)
void PixelStreamDispatcher::processFrameFinished( const QString uri,
const size_t sourceIndex )
{
if (!streamBuffers_.count(uri))
if( !streamBuffers_.count( uri ))
return;

PixelStreamBuffer& buffer = streamBuffers_[uri];
buffer.finishFrameForSource(sourceIndex);

// When the first frame is complete, notify that the stream is now open
if (buffer.isFirstCompleteFrame())
{
QSize size = buffer.getFrameSize();
emit openPixelStream(uri, size);
buffer.setAllowedToSend(true);
}
buffer.finishFrameForSource( sourceIndex );

if (buffer.isAllowedToSend())
sendLatestFrame(uri);
if( buffer.isAllowedToSend( ))
sendLatestFrame( uri );
}

void PixelStreamDispatcher::deleteStream(const QString uri)
void PixelStreamDispatcher::deleteStream( const QString uri )
{
if (streamBuffers_.count(uri))
if( streamBuffers_.count( uri ))
{
streamBuffers_.erase(uri);
emit deletePixelStream(uri);
streamBuffers_.erase( uri );
emit deletePixelStream( uri );
}
}

void PixelStreamDispatcher::requestFrame(const QString uri)
void PixelStreamDispatcher::requestFrame( const QString uri )
{
if (!streamBuffers_.count(uri))
if( !streamBuffers_.count( uri ))
return;

PixelStreamBuffer& buffer = streamBuffers_[uri];
buffer.setAllowedToSend(true);
sendLatestFrame(uri);
buffer.setAllowedToSend( true );
sendLatestFrame( uri );
}

void PixelStreamDispatcher::sendLatestFrame(const QString uri)
void PixelStreamDispatcher::sendLatestFrame( const QString uri )
{
PixelStreamFramePtr frame(new PixelStreamFrame);
PixelStreamFramePtr frame( new PixelStreamFrame );
frame->uri = uri;

PixelStreamBuffer& buffer = streamBuffers_[uri];

// Only send the lastest frame
while (buffer.hasCompleteFrame())
// Only send the latest frame
while( buffer.hasCompleteFrame( ))
frame->segments = buffer.popFrame();

if (frame->segments.empty())
if( frame->segments.empty( ))
return;

// receiver will request a new frame once this frame was consumed
buffer.setAllowedToSend(false);
buffer.setAllowedToSend( false );

emit sendFrame(frame);
emit sendFrame( frame );
}

}
3 changes: 1 addition & 2 deletions deflect/PixelStreamDispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ public slots:
* Notify that a PixelStream has been opened
*
* @param uri Identifier for the Stream
* @param size Size in pixels of the stream
*/
void openPixelStream(QString uri, QSize size);
void openPixelStream(QString uri);

/**
* Notify that a pixel stream has been deleted
Expand Down
5 changes: 0 additions & 5 deletions deflect/Stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,6 @@ class Stream
* After registering, the DisplayCluster master application will send Events
* whenever a user is interacting with this Stream's window.
*
* Registation is only possible after a window for the stream has been
* created on the DisplayWall. A window is first created when all Streams
* that use the same identifier have sent the first frame and called
* finishFrame().
*
* Events can be retrieved using hasEvent() and getEvent().
*
* The current registration status can be checked with
Expand Down
3 changes: 3 additions & 0 deletions doc/RelNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ if you find any other issue with this release.

## git master

* Streamers can register for events immediately, without waiting for the
DisplayCluster host to have opened a window
* Desktopstreamer supports autodiscovery of DisplayCluster hosts using Zeroconf
* Add interaction from the Wall with the DesktopStreamer host (Mac OS X
only)

Expand Down

0 comments on commit eb08399

Please sign in to comment.