Skip to content

Instantly share code, notes, and snippets.

@fpruitt
Created August 4, 2013 02:41
Show Gist options
  • Save fpruitt/6148869 to your computer and use it in GitHub Desktop.
Save fpruitt/6148869 to your computer and use it in GitHub Desktop.
var WebSocketServer = require('websocket').server;
var http = require('http');
var http2 = require('http');
var setter_server = http.createServer(function(request,response) {
});
var getter_server = http2.createServer(function(request,response) {
});
setter_server.listen(5250,function(){});
getter_server.listen(5251,function(){});
wsSetServer = new WebSocketServer({
httpServer: setter_server,
//protocol: 'of-protocol'
});
wsGetServer = new WebSocketServer({
httpServer: getter_server,
//protocol: 'of-protocol'
});
var libraryJson={};
var tcJson={};
var libraryTiles=-1;
var tcTiles=-1;
var setterConnection;
var getterConnection;
console.log('Listening on port 5250 for all SET commands');
console.log('Listening on port 5251 for all GET commands');
wsSetServer.on('request', function(request)
{
console.log('Got connection request from '+request);
setterConnection = request.accept('of-protocol', request.origin);
console.log('Accepted connection.');
setterConnection.on('message', function(message)
{
if(message.type === 'utf8')
{
try
{
var command = JSON.parse(message.utf8Data);
if(command.ORIGIN=="LIB")
{
if(command.TYPE=="STREAM")
{
libraryJson = message.utf8Data;
//console.log("Received Stream Data from Library: "+libraryJson);
}
else if(command.TYPE=="TILES")
{
libraryTiles = message.utf8Data;
console.log("Received Tile info from Library!"+libraryTiles);
}
}
else if(command.ORIGIN=='TC')
{
if(command.TYPE=="STREAM")
{
tcJson = JSON.parse(message.utf8Data);
console.log("Received JSON Data from Theatre Centre: "+tcJson);
}
else if(command.TYPE=="TILES")
{
tcTiles = message.utf8Data;
console.log("Received Tile info from Theatre Centre!");
console.log(message.utf8Data);
}
else
{
console.log("Nontyped message: "+message.utf8Data);
}
}
else
{
console.log("Received unknown message: "+message.utf8Data);
}
}
catch(e)
{
console.log("Error: "+e);
}
}}
)});
wsGetServer.on('request',function(request)
{
getterConnection = request.accept('of-protocol', request.origin);
console.log("Saw connection on GET server");
getterConnection.on('message', function(message)
{
//console.log("Saw message: "+message.utf8Data);
if(message.type === 'utf8')
{
try
{
var command = JSON.parse(message.utf8Data);
//console.log(command.ORIGIN);
if(command.ORIGIN == "LIB")
{
if(command.TYPE == "STREAM")
{
console.log("Saw request from Library.");
getterConnection.sendUTF(JSON.stringify(tcJson.utf8Data));
}
else if(command.TYPE == "TILES")
{
console.log("Saw Tile request from library.");
if(tcTiles != -1 )
{
console.log("Sending tile info to Library..."+ tcTiles.utf8Data);
getterConnection.sendUTF(tcTiles);
}
else
{
console.log("No tile info yet!");
}
}
}
else if(command.ORIGIN=='TC')
{
if(command.TYPE=="TILES")
{
if(libraryTiles != -1)
{
console.log("Sending Tile Info to Theatre Centre!");
getterConnection.sendUTF(libraryTiles);
}
}
if(command.TYPE=="STREAM")
{
getterConnection.sendUTF(libraryJson);
}
}
else
{
console.log("Received packet I don't understand from "+getterConnection.origin+"Containing "+message);
}
}
catch(e)
{
console.log("An error occured: "+e);
}
}
}
)});
#include "testApp.h"
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <json/json.h>
#define THEATRE_CENTRE 1
#define GET 10
#define MANUAL_FRAMERATE 1
//--------------------------------------------------------------
void testApp::setup(){
//ofSetLogLevel(OF_LOG_VERBOSE);
ofSetFrameRate(MANUAL_FRAMERATE);
windowWidth = ofGetWidth();
windowHeight = ofGetHeight();
movie[0].name = "movies/01.mov";
movie[1].name = "movies/02.mov";
movie[2].name = "movies/03.mov";
movie[3].name = "movies/04.mov";
movie[4].name = "movies/05.mov";
movie[5].name = "movies/06.mov";
movie[6].name = "movies/07.mov";
movie[7].name = "movies/08.mov";
movie[8].name = "movies/09.mov";
movie[9].name = "movies/10.mov";
movie[10].name = "movies/11.mov";
movie[11].name = "movies/12.mov";
movie[12].name = "movies/13.mov";
movie[13].name = "movies/14.mov";
movie[14].name = "movies/15.mov";
movie[15].name = "movies/16.mov";
movie[16].name = "movies/17.mov";
movie[17].name = "movies/18.mov";
movie[18].name = "movies/19.mov";
movie[19].name = "movies/20.mov";
for(int i = 0; i<20;i++)
{
movie[i].load();
}
vidTiles.push_back(-1);
for(int i = 0; i<9; i++)
{
tilesPlaying.push_back(-1);
}
ws_options = ofxLibwebsockets::defaultClientOptions();
/*
ws_options.host = "localhost";
ws_options.port = 5251;
ws_options.protocol = "of-protocol";
ws_options.bUseSSL = false;
*/
//LOCALHOST
ws_options.host = "66.18.35.210";
ws_options.port = 5251;
ws_options.protocol = "of-protocol";
ws_options.bUseSSL = false;
ws_connected = ws_client.connect( ws_options );
while (!ws_connected)
{
cout << "Failed to connect to " << ws_options.host << " on port " << ws_options.port << "." << endl;
cout << "Trying again in 0.25 seconds." << endl;
sleep(0.25);
ws_connected = ws_client.connect( ws_options );
}
cout << "Connected to EPB SERVER " << ws_options.host << " on port " << ws_options.port << "." << endl;
ws_client.addListener(this);
localGrid.setCorners(0,windowWidth,0,windowHeight);
}
//--------------------------------------------------------------
void testApp::update(){
// while (!ws_connected)
// {
// cout << "Failed to connect to " << ws_options.host << " on port " << ws_options.port << "." << endl;
// cout << "Trying again in 0.25 seconds." << endl;
// sleep(0.25);
// ws_connected = ws_client.connect( ws_options );
// }
Json::Value root;
//Json::Value value1( "x");
//Json::Value value2( 2 );
//Json::Value value3( true );
//Json::Value value4( 3.141562f );
//Json::Value value5( std::string("My STL string") );
/*
JSON Packet:
ORIGIN: [LIB/TC]
LOCX: [xxx.xxx]
LOCY: [xxx.xxx]
LOCW: [xxx.xxx]
ID: [xx]
*/
root["ORIGIN"] = "TC";
root["TYPE"] = "TILES";
Json::StyledWriter writer;
std::string outputConfig = writer.write( root );
ws_client.send(outputConfig);
root["ORIGIN"] = "TC";
root["TYPE"] = "STREAM";
Json::StyledWriter writer2;
std::string outputConfig2 = writer2.write( root );
ws_client.send(outputConfig2);
if(currentFrame != NULL)
{
Json::Value args = currentFrame;
string id_str = args["ID"].toStyledString();
int id = StringToNumber<int>(id_str);
if(id > 0)
{
string origin_str = args["ORIGIN"].toStyledString();
string locx_str = args["LOCX"].toStyledString();
string locy_str = args["LOCY"].toStyledString();
string locw_str = args["LOCW"].toStyledString();
//std::cout<<"New Message from "<<origin_str<<": Video with ID "<<id_str<<"Should play at x="<<locx_str<<",y="<<locy_str<<",w="<<locw_str<<"\n";
if(id<0 || id > 20)
{
//Stop playing any video here.
//Stop currently playing video, if it is playing.
for(int j=0;j<20;j++)
{
if(movie[j].playing)
{
movie[j].stop();
currentPlaying = -10;
}
}
}
else
{
double x = StringToNumber<double>(locx_str);
double y = StringToNumber<double>(locy_str);
double w = StringToNumber<double>(locw_str);
//std::cout<<"New Message: "<<": Video with ID "<<id<<" Should play at x="<<x<<",y="<<y<<",w="<<w<<"\n";
if(id==currentPlaying)
{
//cout<<"Updating currently playing movie.";
movie[id].Loc.set(x,y);
cout<<movie[id].Loc.x<<"\n";
movie[id].width=w;
movie[id].height=w;
movie[id].update();
}
else
{
//Stop currently playing video.
for(int j=0;j<20;j++)
{
if(movie[j].playing)
{
movie[j].stop();
currentPlaying = -10;
}
}
//Start the video
//cout<<"Starting Video with ID "<<id<<"\n";
if(!movie[id].playing)
{
movie[id].play();
currentPlaying = id;
}
}
}
//else
// std::cout<<"Received -10, No video should play.\n";
//testApp::draw();
}
}
}
//--------------------------------------------------------------
void testApp::draw()
{
localGrid.drawGrid();
//==============================================
/*
SOME SAMPLE SHIT
if(!movie[3].playing)
{
movie[3].play();
}
else
{
ofSetColor(ofColor::white);
movie[3].width=localGrid.Xstride;
movie[3].height=localGrid.Ystride;
movie[3].update();
movie[3].Image.draw(localGrid.regionCorner[]);
}
*/
//==================================================
if(currentPlaying >=0)
{
//iterate = (iterate > 500)? 0: iterate +1;
movie[currentPlaying].Image.resize(movie[currentPlaying].width,movie[currentPlaying].width);
//movie[currentPlaying].Image.draw(movie[currentPlaying].Loc.x+iterate,movie[currentPlaying].Loc.y+iterate);
//cout<<"\nX="<<movie[currentPlaying].Loc.x<<",Y="<<movie[currentPlaying].Loc.y<<"\n";
movie[currentPlaying].Image.draw(movie[currentPlaying].Loc);
}
int tileToStart;
int vidTileBack = vidTiles.back();
while(vidTileBack != -1)
{
//Draw some tiles, update tilesPlaying
if(tileIndex >=0 && tileIndex <9)
{
bool found = false;
tileToStart = lookupTable[tileIndex];
for(int i =0; i<9;i++)
{
//cout<<tileToStart<<tilesPlaying[i]<<"\n";
if(vidTileBack == tilesPlaying[i])
{
cout<<"Already playing this video. Not starting.\n";
found = true;
vidTiles.pop_back();
}
}
if(!found)
{
cout<<"Not playing this video yet. Starting...\n";
tileIndex++;
tilesPlaying[tileToStart] = vidTileBack;
vidTiles.pop_back();
for(int i =0; i< 9; i++)
{
int j = tilesPlaying[i];
//cout<<"Should be -1 if not active, Tile Number "<<i<<" Value "<<j<<"\n";
if(j >= 0 && j <20)
{
cout<<"J: "<<j<<"\n";
//Play in specific space.
cout<<movie[j].playing<<"\n";
if(!movie[j].playing)
{
movie[j].play();
}
ofSetColor(ofColor::white);
movie[j].width=localGrid.Xstride;
movie[j].height=localGrid.Ystride;
movie[j].width=50;
movie[j].height=50;
movie[j].Loc.set(100,100);
movie[j].update();
movie[j].Image.draw(localGrid.regionCorner[tileToStart]);
}
}
}
}
}
}
void testApp::onConnect( ofxLibwebsockets::Event& args )
{
ofLog(OF_LOG_NOTICE, " ### on connected");
//frame_rate = 10;
}
void testApp::onOpen( ofxLibwebsockets::Event& args )
{
ofLog(OF_LOG_NOTICE, " ### on open /new connection open from "
+ args.conn.getClientIP() );
}
void testApp::onClose( ofxLibwebsockets::Event& args )
{
ofLog(OF_LOG_NOTICE, " ### on close");
ws_connected = false;
}
void testApp::onIdle( ofxLibwebsockets::Event& args )
{
ofLog(OF_LOG_NOTICE, " ### on idle");
}
void testApp::onMessage( ofxLibwebsockets::Event& args )
{
//ofLog(OF_LOG_NOTICE, " ### got message!");
//ofLog(OF_LOG_NOTICE, args.message);
//cout<<args.message<<"\n";
// trace out string messages or JSON messages!
if ( args.json != NULL )
{
string msg_type = args.json["TYPE"].toStyledString();
msg_type.erase(std::remove(msg_type.begin(), msg_type.end(), '\n'), msg_type.end());
if(msg_type.compare("\"STREAM\"") == 0)
{
//cout<<args.json<<"\n";
currentFrame=args.json;
}
else if(msg_type == "\"TILES\"")
{
cout<<"Received Tile Message!\n";
cout<<args.json<<"\n";
string tile_str = args.json["TILES"].toStyledString();
int tileNum = StringToNumber<int>(tile_str);
if(tileNum >0 && tileNum <20)
{
vidTiles.push_back(tileNum);
}
}
else
{
cout<<args.json<<"\n";
}
}
}
void testApp::onBroadcast( ofxLibwebsockets::Event& args )
{
ofLog(OF_LOG_NOTICE, " ### got broadcast " + args.message);
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
}
//--------------------------------------------------------------
void testApp::keyReleased(int key){
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){
}
//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){
}
#pragma once
#include "ofMain.h"
#include "ofxLibwebsockets.h"
class MOVIE {
public:
string name;
ofVideoPlayer Player;
ofImage Image;
ofPoint Loc;
int width;
int height;
bool loaded = false;
bool playing = false;
void load(){
if ( !loaded ) {
Player.loadMovie(name);
Player.setLoopState(OF_LOOP_NONE);
Image.allocate(Player.getWidth(), Player.getHeight(), OF_IMAGE_COLOR);
loaded = true;
}
}
void play(){
if ( loaded ) {
Player.play();
playing = true;
}
}
void stop() {
Player.stop();
Player.close();
Image.clear();
loaded = false;
playing = false;
}
void update() {
if ( loaded ) {
Player.update();
Image.setFromPixels(Player.getPixels(), Player.getWidth(), Player.getHeight(), OF_IMAGE_COLOR);
Image.resize(width,height);
}
}
};
class GRID{
public:
static const int Xdim = 3;
static const int Ydim = 3;
int NumRgns = Xdim*Ydim;
double Width,Height;
double Xstride;
double Ystride;
double left,right,top,bottom;
ofPoint regionCorner[Xdim*Ydim];
ofPoint corner[4];
ofColor color = ofColor::black;
int i, j, k;
double ii, jj, kk;
void setColor(ofColor collar){
color = collar;
}
void setCorners(double l, double r, double t, double b){
left = l;
right = r;
top = t;
bottom = b;
Width = abs(right-left);
Height = abs(bottom-top);
corner[0].set(left, top);
corner[1].set(left, bottom);
corner[2].set(right, bottom);
corner[3].set(right, top);
Xstride = Width/(double)Xdim;
Ystride = Height/(double)Ydim;
for ( i=0; i<Ydim; i++ ) {
for ( j=0; j<Xdim; j++ ) {
k = i*Xdim + j;
ii = (double)i;
jj = (double)j;
regionCorner[k].set(jj*Xstride+left, ii*Ystride+top);
}
}
}
void drawGrid(){
ofSetColor(color);
ofLine(corner[0], corner[1]);
ofLine(corner[1], corner[2]);
ofLine(corner[2], corner[3]);
ofLine(corner[3], corner[0]);
Xstride = Width/(double)Xdim;
Ystride = Height/(double)Ydim;
for ( i=0; i<Xdim; i++ ) {
jj = (double)i +1;
ofLine(Xstride*jj+left, top, Xstride*jj+left, bottom);
}
for ( i=0; i<Ydim; i++ ) {
jj = (double)i +1;
ofLine(left, Ystride*jj, right, Ystride*jj);
}
}
};
class testApp : public ofBaseApp{
public:
//CUSTOM
ofxLibwebsockets::Client ws_client;
ofxLibwebsockets::ClientOptions ws_options;
int windowWidth, windowHeight;
bool connected;
bool ws_connected;
int connectedTime;
int deltaTime;
int updateNumber = 0;
MOVIE movie[20];
string epbServerIP = "66.18.35.210";
//string epbServerIP = "169.254.177.61";
string receivedString;
ofVideoPlayer localPlayer;
bool garbageData;
bool isFilled = false;
int id = -10;
int currentX = -10;
int currentY = -10;
int currentW = -10;
int currentPlaying = -10;
int tiles[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
int lookupTable[10] ={3,2,7,4,8,5,1,6,0,-1};
int tileIndex=0;
vector<int> vidTiles;
vector<int> tilesPlaying;
int iterate = 0;
Json::Value currentFrame = NULL;
GRID localGrid;
//END CUSTOM
void setup();
void update();
void draw();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
// websocket methods
void onConnect( ofxLibwebsockets::Event& args );
void onOpen( ofxLibwebsockets::Event& args );
void onClose( ofxLibwebsockets::Event& args );
void onIdle( ofxLibwebsockets::Event& args );
void onMessage( ofxLibwebsockets::Event& args );
void onBroadcast( ofxLibwebsockets::Event& args );
};
template <typename T>
T StringToNumber ( const string &Text )//Text not by const reference so that the function can be used with a
{ //character array as argument
stringstream ss(Text);
T result;
return ss >> result ? result : 0;
}
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup() {
ofSetFrameRate(30);
windowWidth = ofGetWidth();
windowHeight = ofGetHeight();
//Networking Magic
//Cloud Passthrough Server at EPB:
// 66.18.35.210
isLibrary=true;
Json::Value ORIGIN;
Json::Value LOCX;
Json::Value LOCY;
Json::Value LOCW;
Json::Value ID;
ofSetLogLevel(OF_LOG_VERBOSE);
openNIDevice.setup();
openNIDevice.addImageGenerator();
openNIDevice.addDepthGenerator();
openNIDevice.setRegister(true);
openNIDevice.setMirror(true);
openNIDevice.addUserGenerator();
openNIDevice.setMaxNumUsers(2);
openNIDevice.start();
// set properties for all user masks and point clouds
//openNIDevice.setUseMaskPixelsAllUsers(true); // if you just want pixels, use this set to true
openNIDevice.setUseMaskTextureAllUsers(false); // this turns on mask pixels internally AND creates mask textures efficiently
openNIDevice.setUsePointCloudsAllUsers(false);
openNIDevice.setPointCloudDrawSizeAllUsers(1); // size of each 'point' in the point cloud
openNIDevice.setPointCloudResolutionAllUsers(1); // resolution of the mesh created for the point cloud eg., this will use every second depth pixel
kinectTiltAngle = 10;
kinectHardwareDriver.setup();
kinectHardwareDriver.setTiltAngle(kinectTiltAngle);
kinWidth = openNIDevice.getWidth();
kinHeight = openNIDevice.getHeight();
///////////////////////////////////
// ESTABLISH LOCAL & REMOTE GRID //
///////////////////////////////////
LocalGrid.setColor(ofColor::blueViolet);
LocalGrid.setCorners(kinWidth, kinHeight);
RemoteGrid.setColor(ofColor::black);
RemoteGrid.setCorners(kinWidth, kinHeight);
////////////////////////////
// set button coordinates //
////////////////////////////
buttWidth = kinWidth/LocalGrid.Xdim;
buttHeight = kinHeight/LocalGrid.Ydim;
for ( i=0; i<LocalGrid.Ydim; i++ ) { // height
for ( j=0; j<LocalGrid.Xdim; j++ ) { // width
k = i*LocalGrid.Xdim + j;
butt[k].setButtDimension(buttWidth, buttHeight);
butt[k].setButtCorner(j*buttWidth, i*buttHeight);
butt[k].label = k;
}
}
// you can alternatively create a 'base' user class
// ofxOpenNIUser user;
// user.setUseMaskTexture(true);
// user.setUsePointCloud(true);
// user.setPointCloudDrawSize(2);
// user.setPointCloudResolution(2);
// openNIDevice.setBaseUserClass(user);
verdana.loadFont(ofToDataPath("verdana.ttf"), 18);
Tri[0].set(0.0, 20.0);
Tri[1].set(20.0, 0.0);
Tri[2].set(0.0, 0.0);
origin.set(0.0,0.0);
leftHand.handColor = ofColor::blue;
rightHand.handColor = ofColor::yellow;
//ball.b_Toss = true;
//ball.screen_height = windowHeight;
//ball.screen_width = windowWidth;
//ball.Position.set(origin);
/*
movie[0].name = "movies/1.mov";
movie[1].name = "movies/2.mov";
movie[2].name = "movies/3.mov";
movie[3].name = "movies/4.mov";
movie[4].name = "movies/5.mov";
movie[5].name = "movies/6.mov";
movie[6].name = "movies/7.mov";
movie[7].name = "movies/8.mov";
movie[8].name = "movies/9.mov";
movie[9].name = "movies/10.mov";
movie[10].name = "movies/11.mov";
movie[11].name = "movies/12.mov";
movie[12].name = "movies/13.mov";
movie[13].name = "movies/14.mov";
movie[14].name = "movies/15.mov";
movie[15].name = "movies/16.mov";
movie[16].name = "movies/17.mov";
movie[17].name = "movies/18.mov";
movie[18].name = "movies/19.mov";
movie[19].name = "movies/20.mov";
*/
ofSetColor(ofColor::white);
for ( i=0; i<numMovies; i++ ) {
videoPlayer[i].loadMovie(butt[i].videoName);
videoImage[i].allocate(videoPlayer[i].getWidth(), videoPlayer[i].getHeight(), OF_IMAGE_COLOR);
}
PhaseDuration[0] = 0.40*60.0; // boot time for the program nothing can be selected
PhaseDuration[1] = 0.01*60.0; // first phase of performance; nothing can be selected
PhaseDuration[2] = 0.01*60.0; // second phase of performance; videos can be played but not sent
PhaseDuration[3] = 3.00*60.0*20; // third phase of performance; videos that are stopped will be sent
PhaseDuration[4] = 60.0*60.0; // fourth phase of performance; videos will be arriving and playing
PhaseTime[0] = PhaseDuration[0];
for ( i=1; i<5; i++ ) PhaseTime[i] = PhaseTime[i-1] + PhaseDuration[i];
b_Phase[0] = true;
b_Phase[1] = false;
b_Phase[2] = false;
b_Phase[3] = false;
b_Phase[4] = false;
movsToSend.push_back(-1);
for ( i=0; i<numMovies; i++ ) videoLoaded[i] = false;
ws_options = ofxLibwebsockets::defaultClientOptions();
/*
ws_options.host = "localhost";
ws_options.port = 5250;
ws_options.protocol = "of-protocol";
ws_options.bUseSSL = false;
*/
//EPB
ws_options.host = "66.18.35.210";
ws_options.port = 5250;
ws_options.protocol = "of-protocol";
ws_options.bUseSSL = false;
ws_connected = ws_client.connect( ws_options );
while (!ws_connected)
{
cout << "Failed to connect to " << ws_options.host << " on port " << ws_options.port << "." << endl;
cout << "Trying again in 0.25 seconds." << endl;
sleep(0.25);
ws_connected = ws_client.connect( ws_options );
}
cout << "Connected to EPB SERVER " << ws_options.host << " on port " << ws_options.port << "." << endl;
}
//--------------------------------------------------------------
void testApp::update(){
currentTime = ofGetElapsedTimeMillis()*0.001;
for ( i=0; i<4; i++ ) {
b_Phase[i+1] = false;
if ( currentTime > PhaseTime[i] && currentTime < PhaseTime[i+1]) {
b_Phase[i+1] = true;
b_Phase[i] = false;
Phase = i+1;
}
}
if ( !b_Phase[4] ) {
openNIDevice.update();
numUsers = openNIDevice.getNumTrackedUsers();
if ( numUsers > 0 ) {
ofxOpenNIUser & user = openNIDevice.getTrackedUser(0);
// pull head joint coordinates
headJnt = user.getJoint(JOINT_HEAD);
headPnt = headJnt.getProjectivePosition();
// pull neck joint coordinates
neckJnt = user.getJoint(JOINT_NECK);
neckPnt = neckJnt.getProjectivePosition();
// pull torso joint coordinates
torsoJnt = user.getJoint(JOINT_TORSO);
torsoPnt = torsoJnt.getProjectivePosition();
// pull left Knee joint coordinates
leftKneeJnt = user.getJoint(JOINT_LEFT_KNEE);
leftKneePnt = leftKneeJnt.getProjectivePosition();
//pull right knee joint coordinates
rightKneeJnt = user.getJoint(JOINT_RIGHT_KNEE);
rightKneePnt = rightKneeJnt.getProjectivePosition();
// pull left hip joint coordinates
leftHipJnt = user.getJoint(JOINT_LEFT_HIP);
leftHipPnt = leftHipJnt.getProjectivePosition();
// pull right hip coordinates
rightHipJnt = user.getJoint(JOINT_RIGHT_HIP);
rightHipPnt = rightHipJnt.getProjectivePosition();
// pull right hand joint coordinates
rightHandJnt = user.getJoint(JOINT_RIGHT_HAND);
rightHandPnt = rightHandJnt.getProjectivePosition();
rhWrldPos = rightHandJnt.getWorldPosition();
rightHand.Jnt = rightHandJnt;
rightHand.referencePnt = origin;
rightHand.update();
// pull left hand joint coordinates
leftHandJnt = user.getJoint(JOINT_LEFT_HAND);
leftHandPnt = leftHandJnt.getProjectivePosition();
lhWrldPos = leftHandJnt.getWorldPosition();
leftHand.Jnt = leftHandJnt;
leftHand.referencePnt = origin;
leftHand.update();
videoTriggerPnt = 0.25*(leftKneePnt + rightKneePnt + leftHipPnt + rightHipPnt);
}
////////////////////////////////
// CHECK BUTTONS FOR ACTIVITY //
////////////////////////////////
// HAND CHECK ( is hand in butt )
for( i=0; i<LocalGrid.Xdim*LocalGrid.Ydim; i++){
#if HANDCHECK
// check left hand
butt[i].setHandCheck(leftHand.clkPos);
if(butt[i].handCheck)
butt[i].pushButton(leftHand.clkCounter);
// check right hand
butt[i].setHandCheck(rightHand.clkPos);
if(butt[i].handCheck)
butt[i].pushButton(rightHand.clkCounter);
#endif
// check for overhead
butt[i].setHandCheck(videoTriggerPnt);
overheadChk = overheadCheck(leftHandPnt, rightHandPnt, headPnt, neckPnt);
if ( butt[i].handCheck && curr_video == -1 ) {
// turn button on
if ( overheadChk && !butt[i].isOn ) {
butt[i].pushButton(overheadClickCounter);
overheadClickCounter++;
}
// turn button off
if ( !overheadChk && butt[i].isOn ) {
butt[i].pushButton(overheadClickCounter);
overheadClickCounter++;
}
}
// check for overhead stop
handDistance = sqrt((leftHandPnt.x - rightHandPnt.x)*(leftHandPnt.x - rightHandPnt.x) + (leftHandPnt.y - rightHandPnt.y)*(leftHandPnt.y - rightHandPnt.y));
if ( handDistance < handDistanceStopTolerance){
StopCheck = true;
stopTime = ofGetElapsedTimeMillis()*0.001;
}
if ( b_Phase[3] && movsToSend.back() != curr_video && curr_video != -1 ) {
movsToSend.push_back(curr_video);
}
for ( j=0; j<numButts; j++ )
if (StopCheck)
butt[i].isOn = false;
if ( currentTime - stopTime > playTimeOffset )
StopCheck = false;
// stop everything
if ( overheadChk && StopCheck ) {
//videoPlayer[i].stop();
//videoPlayer[i].close();
//videoImage[i].clear();
localPlayer.stop();
localPlayer.close();
localImage.clear();
isVideoPlaying = false;
curr_video = -1;
//ball.Position.set(rightHandPnt);
//ball.released = false;
}
}
///////////////////////////
// HANDLE VIDEO PLAYBACK //
///////////////////////////
imageWidth = rightHandPnt.x - leftHandPnt.x;
imageHeight = rightHandPnt.x - leftHandPnt.x;
if ( b_Phase[2] || b_Phase[3] ) {
for ( i=0; i<numMovies; i++ ) {
if ( butt[i].isOn && !isVideoPlaying ) {
curr_video = i;
currVideoName = butt[i].videoName;
localPlayer.loadMovie(currVideoName);
localPlayer.setLoopState(OF_LOOP_NONE);
localImage.allocate(localPlayer.getWidth(), localPlayer.getHeight(), OF_IMAGE_COLOR);
localPlayer.play();
isVideoPlaying = true;
// videoPlayer[i].loadMovie(butt[i].videoName);
// videoPlayer[i].setLoopState(OF_LOOP_NONE);
// videoImage[i].allocate(videoPlayer[i].getWidth(), videoPlayer[i].getHeight(), OF_IMAGE_COLOR);
// videoPlayer[i].play();
//ball.playTime = ofGetElapsedTimeMillis()*0.001;
}
}
}
if ( curr_video != -1){
localPlayer.update();
localImage.setFromPixels(localPlayer.getPixels(), localPlayer.getWidth(), localPlayer.getHeight(), OF_IMAGE_COLOR);
//videoPlayer[curr_video].update();
//videoImage[curr_video].setFromPixels(videoPlayer[curr_video].getPixels(),
//videoPlayer[curr_video].getWidth(),
//videoPlayer[curr_video].getHeight(),
//OF_IMAGE_COLOR);
//videoLoc[curr_video].set(leftHandPnt.x, 0.5*(rightHandPnt.y + leftHandPnt.y) - imageHeight);
localLoc.set(leftHandPnt.x, 0.5*(rightHandPnt.y + leftHandPnt.y) - imageHeight);
//if ( videoPlayer[curr_video].getIsMovieDone() ) {
if ( localPlayer.getIsMovieDone() ) {
localPlayer.close();
localImage.clear();
//videoPlayer [curr_video].close();
//videoImage [curr_video].clear();
curr_video = -1;
isVideoPlaying = false;
isVideoLoaded = false;
}
}
}
// videoPlayer[i].update();
// if ( curr_video > -1 ) {
// videoImage[i].setFromPixels(videoPlayer[i].getPixels(), videoPlayer[i].getWidth(), videoPlayer[i].getHeight(), OF_IMAGE_COLOR);
// }
// if ( videoPlayer[i].getIsMovieDone() ) {
// videoPlayer[i].close();
// videoImage[i].clear();
// curr_video = -1;
// isVideoPlaying = false;
// isVideoLoaded = false;
// }
// old ball gesture
// ball.Hand = rightHandPnt;
// ball.update();
if(isVideoPlaying)
{
/*
OLD NETWORKING CODE
connected = tcpClient.setup(epbServerIP, 5250);
connectedTime = 0;
deltaTime = 0;
tcpClient.setVerbose(true);
xString = static_cast<ostringstream*>( &(ostringstream() << localLoc.x) )->str();
yString = static_cast<ostringstream*>( &(ostringstream() << localLoc.y) )->str();
wString = static_cast<ostringstream*>( &(ostringstream() << imageHeight) )->str();
videoIDString = static_cast<ostringstream*>( &(ostringstream() << curr_video) )->str();
finalString="x=" + xString + ",y=" + yString + ",w=" + wString + ",id=" + videoIDString;
tcpClient.send(finalString);
tcpClient.close();
*/
root["TYPE"] = "STREAM";
root["ORIGIN"] = "LIB";
root["LOCX"] = localLoc.x;
root["LOCY"] = localLoc.y;
root["LOCW"] = imageHeight;
root["ID"] = curr_video;
Json::StyledWriter writer;
std::string outputConfig = writer.write( root );
std::cout << outputConfig << std::endl;
ws_client.send(outputConfig);
while(movsToSend.back() != -1)
{
tiles["ORIGIN"] = "LIB";
tiles["TYPE"] = "TILES";
tiles["TILES"] = movsToSend.back();
cout<<"Set TILE message to "<<movsToSend.back()<<".\n";
Json::StyledWriter writer;
std::string outputConfig = writer.write( tiles );
std::cout << outputConfig << std::endl;
ws_client.send(outputConfig);
movsToSend.pop_back();
}
}
else //Send a notification to let remote players you are not playing video anymore.
{
root["TYPE"] ="STREAM";
root["ORIGIN"] = "LIB";
root["LOCX"] = -10;
root["LOCY"] = -10;
root["LOCW"] = -10;
root["ID"] = -10;
Json::StyledWriter writer;
std::string outputConfig = writer.write( root );
std::cout << outputConfig << std::endl;
ws_client.send(outputConfig);
}
}
//--------------------------------------------------------------
void testApp::draw(){
ofSetColor(ofColor::gray);
//ofPushMatrix();
////draw debug (ie., image, depth, skeleton)
//openNIDevice.drawDebug();
//ofPopMatrix();
/////////////////////
// DRAW EVERYTHING //
/////////////////////
ofPushMatrix();
ofTranslate(0.0, windowHeight - kinHeight);
ofEnableBlendMode(OF_BLENDMODE_ALPHA); // see through the grid and buttons
LocalGrid.drawGrid();
for ( i=0; i<LocalGrid.Ydim; i++ ) {
for ( j=0; j<LocalGrid.Xdim; j++ ) {
k = i*LocalGrid.Xdim + j;
butt[k].drawButton();
}
}
//ofDisableBlendMode();
// CHECK FOR USERS
if ( numUsers > 0 && !b_Phase[4] ) {
ofxOpenNIUser & user = openNIDevice.getTrackedUser(0); // get a reference to this user
// draw the mask texture for this user
//user.drawMask();
user.drawSkeleton();
// red for torso
ofSetColor(ofColor::red);
ofCircle(torsoPnt.x, torsoPnt.y, 10);
//rightHand.drawHand();
leftHand.drawHand();
rightHand.drawClk();
leftHand.drawClk();
ofSetColor(ofColor::green);
ofCircle(videoTriggerPnt.x, videoTriggerPnt.y, 10);
}
// if ( ball.released && isVideoPlaying ) {
// imageLocation.set(ball.Position.x, ball.Position.y);
// if ( ball.stop ) {
// videoPlayer.stop();
// videoPlayer.close();
// videoImage.clear();
// }
// }
// ofSetColor(ofColor::yellow);
// ofCircle(ball.Position.x, ball.Position.y, 20);
ofSetColor(ofColor::white);
if ( curr_video != -1 && !b_Phase[4]) {
localImage.resize(imageWidth, imageHeight);
localImage.draw(localLoc);
}
ofSetColor(phaseColors[Phase]);
ofTriangle(Tri[0], Tri[1], Tri[2]);
ofPopMatrix();
// draw remote grid
RemoteGrid.drawGrid();
if ( b_Phase[3] || b_Phase[4] ) {
for ( i=1; i<movsToSend.size(); i++ ) {
j = movsToSend.at(i);
if ( !videoLoaded[j] ) {
videoPlayer[j].loadMovie(butt[j].videoName);
videoPlayer[j].setLoopState(OF_LOOP_NONE);
videoImage[j].allocate(videoPlayer[j].getWidth(),
videoPlayer[j].getHeight(),
OF_IMAGE_COLOR);
videoPlayer[j].play();
videoLoaded[j] = true;
}
videoPlayer[j].update();
videoImage[j].setFromPixels(videoPlayer[j].getPixels(),
videoPlayer[j].getWidth(),
videoPlayer[j].getHeight(),
OF_IMAGE_COLOR);
videoLoc[j] = RemoteGrid.regionCorner[LocToRemMap[j]];
ofSetColor(ofColor::white);
videoImage[j].resize(RemoteGrid.Xstride, RemoteGrid.Ystride);
videoImage[j].draw(videoLoc[j]);
}
}
/////////////////////////
// FEEDBACK STATEMENTS //
/////////////////////////
ofSetColor(ofColor::red);
statementCounter = 0;
msg[0] = ofToString(ofGetElapsedTimeMillis());
msg[1] = ofToString(ofGetFrameRate());
msg[2] = ofToString(openNIDevice.getFrameRate());
dbplx = windowWidth - 500 ;
MSG = "MILLIS: " + msg[0];
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "FPS: " + msg[1];
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "Device FPS: " + msg[2];
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "Number of Users = " + ofToString(numUsers);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "RH z position = " + ofToString(rightHand.PosAvg);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "RH velocity = " + ofToString(rightHand.Vel[0].x);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "RH clkChk = " + ofToString(rightHand.clkChk);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "FrwdChk = " + ofToString(rightHand.frwdChk);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "BackChk = " + ofToString(rightHand.bckChk);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "XYVel = " + ofToString(rightHand.VelAvg);
verdana.drawString(MSG,dbplx,dbply + dbpo*statementCounter);
statementCounter++;
MSG = "overheadClickCounter = " + ofToString(overheadClickCounter);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "window width & height: " + ofToString(windowWidth) + " " + ofToString(windowHeight);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "kinect width & height: " + ofToString(kinWidth) + " " + ofToString(kinHeight);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "kinect tilt angle: " + ofToString(kinectTiltAngle);
verdana.drawString(MSG, dbplx, dbply + dbpo*statementCounter);
statementCounter++;
MSG = "handDistance: " + ofToString(handDistance);
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
MSG = "stopTimeoffset: " + ofToString(ofGetSystemTimeMicros() - stopTime);
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
MSG = "stopCheck " + ofToString(StopCheck);
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
MSG = "isVideoPlaying: " + ofToString(isVideoPlaying);
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
MSG = "currentVideoPlaying: " + ofToString(curr_video);
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
for ( i=0; i<5; i++ ) {
MSG = "b_Phase["+ofToString(i)+"]: " + ofToString(b_Phase[i]);
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
}
MSG = "Phase: " + ofToString(Phase);
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
for ( i=0; i<movsToSend.size(); i++ ) {
MSG = "movsToSend: " + ofToString(movsToSend.at(i));
verdana.drawString(MSG, dbplx, dbply+dbpo*statementCounter);
statementCounter++;
}
}
//--------------------------------------------------------------
bool testApp::overheadCheck(ofPoint leftHand, ofPoint rightHand, ofPoint head, ofPoint neck){
//int height = head.y - (neck.y - head.y);
int height = head.y - 10;
if ( leftHand.y < height && rightHand.y < height ) {
return true;
}
else {
return false;
}
}
//--------------------------------------------------------------
void testApp::userEvent(ofxOpenNIUserEvent & event){
// show user event messages in the console
ofLogNotice() << getUserStatusAsString(event.userStatus) << "for user" << event.id << "from device" << event.deviceID;
}
//--------------------------------------------------------------
void testApp::exit(){
openNIDevice.stop();
}
//--------------------------------------------------------------
void testApp::keyPressed(int key){
switch (key) {
case OF_KEY_UP:
kinectTiltAngle = ofClamp(kinectTiltAngle + 1, -30,30);
kinectHardwareDriver.setTiltAngle(kinectTiltAngle);
break;
case OF_KEY_DOWN:
kinectTiltAngle = ofClamp(kinectTiltAngle - 1, -30, 30);
kinectHardwareDriver.setTiltAngle(kinectTiltAngle);
break;
case '0':
PhaseTime[0] = currentTime + PhaseDuration[0];
for ( i=1; i<5; i++ ) PhaseTime[i] = PhaseTime[i-1] + PhaseDuration[i];
b_Phase[0] = true;
for ( i=1; i<5; i++ ) b_Phase[i] = false;
break;
case '1':
PhaseTime[0] = 0.0;
PhaseTime[1] = currentTime + PhaseDuration[1];
for ( i=2; i<5; i++ ) PhaseTime[i] = PhaseTime[i-1] + PhaseDuration[i];
for ( i=0; i<5; i++ ) b_Phase[i] = false;
b_Phase[1] = true;
break;
case '2':
PhaseTime[0] = 0.0;
PhaseTime[1] = 0.01;
PhaseTime[2] = currentTime + PhaseDuration[1];
for ( i=3; i<5; i++ ) PhaseTime[i] = PhaseTime[i-1] + PhaseDuration[i];
for ( i=0; i<5; i++ ) b_Phase[i] = false;
b_Phase[2] = true;
break;
case '3':
PhaseTime[0] = 0.0;
PhaseTime[1] = 0.01;
PhaseTime[2] = 0.02;
PhaseTime[3] = currentTime + PhaseDuration[3];
PhaseTime[4] = currentTime + PhaseDuration[4] + PhaseTime[3];
for ( i=0; i<5; i++ ) b_Phase[i] = false;
b_Phase[3] = true;
break;
case '4':
PhaseTime[0] = 0.0;
PhaseTime[1] = 0.01;
PhaseTime[2] = 0.02;
PhaseTime[3] = 0.03;
PhaseTime[4] = currentTime + PhaseDuration[4];
for ( i=0; i<5; i++ ) b_Phase[i] = false;
b_Phase[1] = true;
break;
default:
break;
}
}
//--------------------------------------------------------------
void testApp::keyReleased(int key){
}
//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){
}
//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
}
//--------------------------------------------------------------
void testApp::windowResized(int w, int h){
}
//--------------------------------------------------------------
////////////////
// EXTRA CODE //
////////////////
#if 0
/*
// pull shoulder coordinates
// left
ofxOpenNIJoint leftShldrJnt = user.getJoint(JOINT_LEFT_SHOULDER);
ofPoint leftShldrPos = leftShldrJnt.getProjectivePosition();
ofPoint leftShldrWrld = leftShldrJnt.getWorldPosition();
// right
ofxOpenNIJoint rightShldrJnt = user.getJoint(JOINT_RIGHT_SHOULDER);
ofPoint rightShldrPos = rightShldrJnt.getProjectivePosition();
ofPoint rightShldrWrld = rightShldrJnt.getWorldPosition();
*/ // pull shoulder info
/*
// you can also access the pixel and texture references individually:
// TEXTURE REFERENCE
//ofTexture & tex = user.getMaskTextureReference();
// do something with texture...
// PIXEL REFERENCE
//ofPixels & pix = user.getMaskPixels();
// do something with the pixels...
// and point clouds:
*/ // extra stuff from the original example
/*
ofPushMatrix();
// move it a bit more central
ofTranslate(320, 240, 10);
user.drawPointCloud();
// you can also access the mesh:
// MESH REFERENCE
//ofMesh & mesh = user.getPointCloud();
// do something with the point cloud mesh
ofPopMatrix();
*/ // extra stuff from the original example
#endif
#pragma once
#include "ofMain.h"
#include "ofxLibwebsockets.h"
class MOVIE {
public:
string name;
ofVideoPlayer Player;
ofImage Image;
ofPoint Loc;
int width;
int height;
bool loaded = false;
bool playing = false;
void load(){
if ( !loaded ) {
Player.loadMovie(name);
Player.setLoopState(OF_LOOP_NONE);
Image.allocate(Player.getWidth(), Player.getHeight(), OF_IMAGE_COLOR);
loaded = true;
}
}
void play(){
if ( loaded ) {
Player.play();
playing = true;
}
}
void stop() {
Player.stop();
Player.close();
Image.clear();
loaded = false;
playing = false;
}
void update() {
if ( loaded ) {
Player.update();
Image.setFromPixels(Player.getPixels(), Player.getWidth(), Player.getHeight(), OF_IMAGE_COLOR);
Image.resize(width,height);
}
}
};
class GRID{
public:
static const int Xdim = 3;
static const int Ydim = 3;
int NumRgns = Xdim*Ydim;
double Width,Height;
double Xstride;
double Ystride;
double left,right,top,bottom;
ofPoint regionCorner[Xdim*Ydim];
ofPoint corner[4];
ofColor color = ofColor::black;
int i, j, k;
double ii, jj, kk;
void setColor(ofColor collar){
color = collar;
}
void setCorners(double l, double r, double t, double b){
left = l;
right = r;
top = t;
bottom = b;
Width = abs(right-left);
Height = abs(bottom-top);
corner[0].set(left, top);
corner[1].set(left, bottom);
corner[2].set(right, bottom);
corner[3].set(right, top);
Xstride = Width/(double)Xdim;
Ystride = Height/(double)Ydim;
for ( i=0; i<Ydim; i++ ) {
for ( j=0; j<Xdim; j++ ) {
k = i*Xdim + j;
ii = (double)i;
jj = (double)j;
regionCorner[k].set(jj*Xstride+left, ii*Ystride+top);
}
}
}
void drawGrid(){
ofSetColor(color);
ofLine(corner[0], corner[1]);
ofLine(corner[1], corner[2]);
ofLine(corner[2], corner[3]);
ofLine(corner[3], corner[0]);
Xstride = Width/(double)Xdim;
Ystride = Height/(double)Ydim;
for ( i=0; i<Xdim; i++ ) {
jj = (double)i +1;
ofLine(Xstride*jj+left, top, Xstride*jj+left, bottom);
}
for ( i=0; i<Ydim; i++ ) {
jj = (double)i +1;
ofLine(left, Ystride*jj, right, Ystride*jj);
}
}
};
class testApp : public ofBaseApp{
public:
//CUSTOM
ofxLibwebsockets::Client ws_client;
ofxLibwebsockets::ClientOptions ws_options;
int windowWidth, windowHeight;
bool connected;
bool ws_connected;
int connectedTime;
int deltaTime;
int updateNumber = 0;
MOVIE movie[20];
string epbServerIP = "66.18.35.210";
//string epbServerIP = "169.254.177.61";
string receivedString;
ofVideoPlayer localPlayer;
bool garbageData;
bool isFilled = false;
int id = -10;
int currentX = -10;
int currentY = -10;
int currentW = -10;
int currentPlaying = -10;
int tiles[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
int lookupTable[10] ={3,2,7,4,8,5,1,6,0,-1};
int tileIndex=0;
vector<int> vidTiles;
vector<int> tilesPlaying;
int iterate = 0;
Json::Value currentFrame = NULL;
GRID localGrid;
//END CUSTOM
void setup();
void update();
void draw();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
// websocket methods
void onConnect( ofxLibwebsockets::Event& args );
void onOpen( ofxLibwebsockets::Event& args );
void onClose( ofxLibwebsockets::Event& args );
void onIdle( ofxLibwebsockets::Event& args );
void onMessage( ofxLibwebsockets::Event& args );
void onBroadcast( ofxLibwebsockets::Event& args );
};
template <typename T>
T StringToNumber ( const string &Text )//Text not by const reference so that the function can be used with a
{ //character array as argument
stringstream ss(Text);
T result;
return ss >> result ? result : 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment