Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add key 'w' to show winner(s) from voting #2

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
27 changes: 16 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM ubuntu:16.04

ENV TERM=xterm-256color
ENV OF_VERSION "0.9.8"
ENV OF_VERSION "0.10.1-patched"
ENV OF_ROOT "/opt/openFrameworks"

ARG DEBIAN_FRONTEND=noninteractive
Expand All @@ -14,15 +14,22 @@ RUN apt-get update; \
lsb-release \
libmpg123-dev \
gstreamer1.0 \
gstreamer1.0-plugins-ugly
gstreamer1.0-plugins-ugly \
ccache \
vim \
unzip \
rsync \
git \
ca-certificates

# Install OpenFrameworks
# based off https://openframeworks.cc/setup/raspberrypi/raspberry-pi-getting-started/
RUN wget --no-check-certificate http://openframeworks.cc/versions/v${OF_VERSION}/of_v${OF_VERSION}_linux64_release.tar.gz && \
mkdir -p /opt/openFrameworks && \
tar -xzvf of_v${OF_VERSION}_linux64_release.tar.gz -C /opt/openFrameworks --strip-components 1 && \
# Install openFrameworks for linux64 and linuxarmv6l
RUN git clone https://github.com/lucasrangit/openFrameworks.git --branch ${OF_VERSION} --single-branch /opt/openFrameworks && \
/opt/openFrameworks/scripts/linux/download_libs.sh && \
/opt/openFrameworks/scripts/linux/ubuntu/install_dependencies.sh -y && \
/opt/openFrameworks/scripts/linux/compileOF.sh -j3
/opt/openFrameworks/scripts/linux/compileOF.sh -j`nproc` && \
/opt/openFrameworks/scripts/linux/download_libs.sh --platform linuxarmv6l && \
/opt/openFrameworks/scripts/ci/linuxarmv6l/install.sh && \
TARGET=linuxarmv6l /opt/openFrameworks/scripts/ci/linuxarmv6l/build.sh

# Add user that matches host user
ARG BUILD_UID=1000
Expand All @@ -33,9 +40,7 @@ RUN (test $(getent group $BUILD_GID) || addgroup -gid $BUILD_GID docker) && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/docker

# Build needs write access to /opt/openFrameworks/addons/obj for some reason
RUN mkdir /opt/openFrameworks/addons/obj && \
chown docker. /opt/openFrameworks/addons/obj
RUN chown docker. /opt/openFrameworks/addons/obj

USER $BUILD_UID
WORKDIR /home/docker/hackandtell-raspberry

8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ Needs http://openframeworks.cc/ to compile.
make && make run
# or use XCode or other IDE to compile

## Host Build with Docker
## Build

* Pass the `--shell` argument to get an interactive shell inside the build container.
* Pass the `armv6` argument to build for the armv6 (e.g. Raspberry Pi).

* `./build.sh`

### Runtime Dependencies

* Ubuntu: `sudo apt install libfreeimage3`
* Ubuntu 16.04: `sudo apt install libfreeimage3 libglfw3 liburiparser1`

### Run

* `bin/hackandtell-raspberry`

13 changes: 9 additions & 4 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ set -o xtrace
if ! grep -c docker /proc/1/cgroup > /dev/null; then
image_tag="$(basename $PWD | sed 's/_/-/g' | cut -c 1-40 | tr '[:upper:]' '[:lower:]'):$(git rev-parse --short HEAD)"
docker build --build-arg BUILD_UID=$(id -u) --build-arg BUILD_GID=$(id -g) --tag local/$image_tag .
if [[ $1 == "--shell" ]]; then
docker run --name $(basename $PWD) -it -v $PWD:/home/docker/$(basename $PWD) local/$image_tag bash
if [[ ${1} == "--shell" ]]; then
docker run --name $(basename $PWD) -it --rm -v $PWD:/home/docker/$(basename $PWD) local/$image_tag bash
else
docker run --name $(basename $PWD) --rm -v $PWD:/home/docker/$(basename $PWD) local/$image_tag $0 $*
docker run --name $(basename $PWD) --rm -v $PWD:/home/docker/$(basename $PWD) local/$image_tag "$0" "$*"
fi
exit $?
fi

make
rm -f bin/hackandtell-raspberry

if [[ ${1} == "armv6" ]]; then
source cross.env
fi

make -j`nproc`
15 changes: 15 additions & 0 deletions cross.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export TARGET=linuxarmv6l
export GCC_PREFIX=arm-linux-gnueabihf
export GST_VERSION=1.0
export RPI_ROOT=${OF_ROOT}/scripts/ci/$TARGET/raspbian
export TOOLCHAIN_ROOT=${OF_ROOT}/scripts/ci/$TARGET/rpi_toolchain
export PLATFORM_OS=Linux
export PLATFORM_ARCH=armv6l
export PKG_CONFIG_LIBDIR=${RPI_ROOT}/usr/lib/pkgconfig:${RPI_ROOT}/usr/lib/${GCC_PREFIX}/pkgconfig:${RPI_ROOT}/usr/share/pkgconfig
export CXX="ccache ${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-g++"
export CC="ccache ${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-gcc"
export AR=${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-ar
export LD=${TOOLCHAIN_ROOT}/bin/${GCC_PREFIX}-ld

# match the flags used the build OF or it will require a recompile
export CXXFLAGS="${CXXFLAGS} -ftrack-macro-expansion=0"
151 changes: 112 additions & 39 deletions src/ofApp.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#include <ctime>
#include <iostream>
#include <iterator>
#include <locale>
#include <regex>
#include <sstream>
#include "ofApp.h"

//--------------------------------------------------------------
Expand All @@ -13,6 +16,8 @@ void ofApp::setup(){
#endif
ofSetVerticalSync(true);
resetButton.addListener(this,&ofApp::resetButtonPressed);

ofSetEscapeQuitsApp(false);

matelightFont.loadFont("OSP-DIN.ttf", 68, true, true, true);
signsFont.loadFont("OSP-DIN.ttf", 100, true, true, true );
Expand All @@ -30,9 +35,11 @@ void ofApp::setup(){
gui.add(paused.setup("Pause (p/space)", true));
gui.add(minutes.setup("Minutes", 5, 1, 120));
gui.add(showApplause.setup("Show applause (a)", false));
gui.add(showWinners.setup("Show winners (w)", false));
gui.add(showCount.setup("Show vote count (v)", false));
gui.add(showMatelightPreview.setup("Show ML preview", false));


millisecondsTotal = minutes;
millisecondsLeft = minutes * 60 * 1000;

Expand All @@ -44,49 +51,63 @@ void ofApp::setup(){
udpConnection.Connect("10.0.1.39", 1337);
udpConnection.SetNonBlocking(true);

ofRegisterURLNotification(this);
}

void ofApp::resetButtonPressed() {
paused = true;
showApplause = false;
millisecondsLeft = minutes * 60 * 1000;
ofRemoveAllURLRequests();
ofStopURLLoader();
showWinners = false;
showCount = false;
queueGetCount = false;
}


//--------------------------------------------------------------
void ofApp::update(){
if (!showApplause) {
updateTimeLeft();
}
else {
paused = true;
std::string s1;

updateTimeLeft();

if (showWinners) {
s1 = winners;
showCount = false;
} else if (showCount) {
s1 = count;
// queue another if the last update was successful
if (queueGetCount) {
queueGetCount = false;
ofLoadURLAsync("http://localhost:80/count", "async_req");
}
} else {
// update time left display
int minutes = millisecondsLeft / 1000 / 60;
int seconds = (millisecondsLeft - (minutes * 60 * 1000)) / 1000;
int millis = millisecondsLeft - (minutes * 1000 * 60) - (seconds * 1000);

std::stringstream ss;
ss << setfill('0') << setw(2) << seconds;
std::stringstream ms;
ms << setfill('0') << setw(3) << millis;

s1 = ofToString(minutes) + ":" + ofToString(ss.str());
std::string s2 = s1 + "." + ofToString(ms.str());

strncpy(timeLeftStr, s2.c_str(), sizeof(timeLeftStr));
// update the local time
std::time_t t = std::time(NULL);
std::strftime(localTimeStr, sizeof(localTimeStr), "%H:%M:%S", std::localtime(&t));
}

// update time left display
int minutes = millisecondsLeft / 1000 / 60;
int seconds = (millisecondsLeft - (minutes * 60 * 1000)) / 1000;
int millis = millisecondsLeft - (minutes * 1000 * 60) - (seconds * 1000);

std::stringstream ss;
ss << setfill('0') << setw(2) << seconds;
std::stringstream ms;
ms << setfill('0') << setw(3) << millis;

std::string s1 = ofToString(minutes) + ":" + ofToString(ss.str());
std::string s2 = s1 + "." + ofToString(ms.str());


strncpy(timeLeftStr, s2.c_str(), sizeof(timeLeftStr));
// update the local time
std::time_t t = std::time(NULL);
std::strftime(localTimeStr, sizeof(localTimeStr), "%H:%M:%S", std::localtime(&t));

updateMatelight(s1);
}

//--------------------------------------------------------------
void ofApp::updateTimeLeft(){
if (showApplause) {
if (showApplause || showWinners) {
return;
}
if (paused) {
Expand Down Expand Up @@ -145,6 +166,35 @@ void ofApp::updateMatelight(std::string text) {
udpConnection.Send(message, 1924);
}

void ofApp::urlResponse(ofHttpResponse & response) {
if (response.status == 200 && response.request.name == "async_req") {
std::string s = response.data.getText();
if (response.request.url.find("winners") != std::string::npos) {
std::regex regex("[0-9]+");
winners.clear();
for (std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), regex); i != std::sregex_iterator(); ++i) {
std::smatch match = *i;
winners += match.str() + " ";
}
// if there are no winners this will show a blank screen
// allowing the game master to retry getting the winners
showWinners = true;
} else if (response.request.url.find("count") != std::string::npos) {
cerr << "Count: " << s << endl;
std::stringstream stream;
stream << "0x" << setfill('0') << setw(2) << std::hex << std::stoi(s);
count = stream.str();
// queue an update on success
queueGetCount = true;
}
} else {
// cerr << response.status << " " << response.error << endl;
// if an error occurs, clear the results in case they are no longer valid
count.clear();
winners.clear();
}
}

//--------------------------------------------------------------
void ofApp::drawStringMono(ofTrueTypeFont* font, std::string text, float x, float y, float w) {
for (int i = 0 ; i < text.length(); i++) {
Expand Down Expand Up @@ -215,28 +265,51 @@ void ofApp::draw(){
void ofApp::exit()
{
resetButton.removeListener(this,&ofApp::resetButtonPressed);
ofUnregisterURLNotification(this);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
if (key == 'h') {
switch (key) {
case 'h':
case 'H':
isMenuHidden = !isMenuHidden;
return;
}
if (key == 'a') {
break;
case 'a':
case 'A':
showApplause = !showApplause;
}
if (key == 'r') {
paused = true;
break;
case 'r':
case 'R':
resetButtonPressed();
return;
}

if (key == 'p' || key == ' ') {
break;
case 'v':
case 'V':
showCount = !showCount;
if (!showCount)
ofLoadURLAsync("http://localhost:80/count", "async_req");
break;
case 'w':
case 'W':
// if not shown, async HTTP GET winners
if (!showWinners)
ofLoadURLAsync("http://localhost:80/winners", "async_req");
// if shown, hide
showWinners = false;
break;
case 'p':
case 'P':
case ' ':
paused = !paused;
}

if (key == 'q') {
break;
case 'q':
case 'Q':
ofExit();
break;
default:
/* do nothing with unknown keys */
break;
}
}

Expand Down
9 changes: 6 additions & 3 deletions src/ofApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ofApp : public ofBaseApp{

void updateTimeLeft();
void updateMatelight(std::string minutes);
void urlResponse(ofHttpResponse & response);
void drawStringMono(ofTrueTypeFont* font, std::string text, float x, float y, float w);
void drawApplause();
void drawCountDown();
Expand All @@ -50,21 +51,23 @@ class ofApp : public ofBaseApp{
ofPixels matelightPixels;
ofPixels matelightSmall;
ofImage matelightPreview;

ofxUDPManager udpConnection;

bool isMenuHidden;
bool isTimerRunning;
ofxToggle showApplause;
ofxToggle showCount;
ofxToggle showWinners;
int applauseTextColor;
int applauseBackgroundColor;
// buffers for variable strings on the display
char localTimeStr[100];
char timeLeftStr[100];
// application state

int millisecondsTotal;
int millisecondsLeft;
int lastTime;

std::string winners;
std::string count;
ofxToggle queueGetCount;
};