From c346375e36a2dc85c382a631900a0c1c67187339 Mon Sep 17 00:00:00 2001 From: Adam Sosnowski Date: Fri, 18 Oct 2013 16:04:51 -0400 Subject: [PATCH] headless apps update with cleanup,bug fixes, etc --- headlesservice/bar-descriptor.xml | 102 ++++++++++++ headlesservice/config.pri | 12 +- headlesservice/src/applicationheadless.cpp | 133 +++++++++------- headlesservice/src/applicationheadless.hpp | 125 ++++++++------- headlesservice/src/main.cpp | 1 - headlesserviceui/assets/.assets.index | 10 +- headlesserviceui/src/applicationui.cpp | 122 +++++++------- headlesserviceui/src/applicationui.hpp | 103 ++++++------ xandos/assets/.assets.index | 18 +-- xandos/assets/main.qml | 9 -- xandos/bar-descriptor.xml | 7 +- xandos/src/applicationui.cpp | 44 ++--- xandos/src/applicationui.hpp | 46 +++--- xandos/src/droidlistener.cpp | 70 +++++--- xandos/src/droidlistener.hpp | 39 +++-- xandos/src/main.cpp | 31 ++-- xandos/src/xandos.cpp | 90 +++++------ xandos/src/xandos.hpp | 55 ++++--- xandos/translations/xandos.ts | 20 +-- xandosdroid/src/applicationheadless.cpp | 28 ++-- xandosdroid/src/applicationheadless.hpp | 36 ++--- xandosdroid/src/main.cpp | 28 ++-- xandosdroid/src/xandosdroid.cpp | 177 +++++++++++---------- xandosdroid/src/xandosdroid.hpp | 64 ++++---- 24 files changed, 779 insertions(+), 591 deletions(-) create mode 100755 headlesservice/bar-descriptor.xml diff --git a/headlesservice/bar-descriptor.xml b/headlesservice/bar-descriptor.xml new file mode 100755 index 00000000..a15be8fc --- /dev/null +++ b/headlesservice/bar-descriptor.xml @@ -0,0 +1,102 @@ + + + + + + + + com.example.headlesservice + + + headlesservice + + + 1.0.0 + + + 1 + + + + + + The headlesservice application + + + + + + Example Inc. + + + + + + true + none + false + + + + + armle-v7 + headlesservice + + + Qnx/Cascades + armle-v7 + headlesservice.so + + + armle-v7 + headlesservice + + + x86 + headlesservice + + + + + icon.png + + + icon.png + assets + + + + + + + + run_native + + + diff --git a/headlesservice/config.pri b/headlesservice/config.pri index c4566a57..32687e93 100644 --- a/headlesservice/config.pri +++ b/headlesservice/config.pri @@ -16,9 +16,11 @@ device { -lbbsystem SOURCES += $$quote($$BASEDIR/src/applicationheadless.cpp) \ + $$quote($$BASEDIR/src/applicationui.cpp) \ $$quote($$BASEDIR/src/main.cpp) - HEADERS += $$quote($$BASEDIR/src/applicationheadless.hpp) + HEADERS += $$quote($$BASEDIR/src/applicationheadless.hpp) \ + $$quote($$BASEDIR/src/applicationui.hpp) } CONFIG(release, debug|release) { @@ -35,9 +37,11 @@ device { -lbbsystem SOURCES += $$quote($$BASEDIR/src/applicationheadless.cpp) \ + $$quote($$BASEDIR/src/applicationui.cpp) \ $$quote($$BASEDIR/src/main.cpp) - HEADERS += $$quote($$BASEDIR/src/applicationheadless.hpp) + HEADERS += $$quote($$BASEDIR/src/applicationheadless.hpp) \ + $$quote($$BASEDIR/src/applicationui.hpp) } } @@ -56,9 +60,11 @@ simulator { -lbbsystem SOURCES += $$quote($$BASEDIR/src/applicationheadless.cpp) \ + $$quote($$BASEDIR/src/applicationui.cpp) \ $$quote($$BASEDIR/src/main.cpp) - HEADERS += $$quote($$BASEDIR/src/applicationheadless.hpp) + HEADERS += $$quote($$BASEDIR/src/applicationheadless.hpp) \ + $$quote($$BASEDIR/src/applicationui.hpp) } } diff --git a/headlesservice/src/applicationheadless.cpp b/headlesservice/src/applicationheadless.cpp index 94c8ccd4..066b69b4 100644 --- a/headlesservice/src/applicationheadless.cpp +++ b/headlesservice/src/applicationheadless.cpp @@ -36,83 +36,104 @@ using namespace bb::device; using namespace bb::system; //! [1] -ApplicationHeadless::ApplicationHeadless(bb::Application *app) : - QObject(app), m_invokeManager(new InvokeManager(this)), m_led(0), m_flashCount(20) { - QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); - // log the service PID - qDebug() << "PID------------" << QString::number(QCoreApplication::applicationPid()); +ApplicationHeadless::ApplicationHeadless(bb::Application *app) + : QObject(app) + , m_invokeManager(new InvokeManager(this)) + , m_led(0) + , m_flashCount(20) + , m_settingsWatcher(new QFileSystemWatcher(this)) +{ + QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); + // log the service PID + qDebug() << "PID------------" << QString::number(QCoreApplication::applicationPid()); } //! [1] //! [3] -void ApplicationHeadless::onInvoked(const bb::system::InvokeRequest& request) { - qDebug() << "##service got invoked: " << request.action(); +void ApplicationHeadless::onInvoked(const bb::system::InvokeRequest& request) +{ + qDebug() << "##service got invoked: " << request.action(); - // start led flashing once the start request is received - if (request.action().compare("bb.action.system.STARTED") == 0) { - m_led->flash(m_flashCount); - } else { - // write service running status to qsettings - QSettings settings(m_author, m_appName); - settings.setValue(m_serviceStatus, request.action()); - } + // start led flashing once the start request is received + if (request.action().compare("bb.action.system.STARTED") == 0) { + m_led->flash(m_flashCount); + } else { + // write service running status to qsettings + QSettings settings(m_author, m_appName); + settings.setValue(m_serviceStatus, request.action()); + } } //! [3] //! [4] -void ApplicationHeadless::flashCountChanged(int x) { - qDebug() << "---------" + QString::number(x); - QSettings settings(m_author, m_appName); - settings.setValue(m_remainingCount, x); +void ApplicationHeadless::flashCountChanged(int x) +{ + qDebug() << "---------" + QString::number(x); + QSettings settings(m_author, m_appName); + settings.setValue(m_remainingCount, x); } -void ApplicationHeadless::activeUpdate(bool active) { - QSettings settings(m_author, m_appName); - settings.value(m_ledActive, active); +void ApplicationHeadless::activeUpdate(bool active) +{ + qDebug() << "---active: " << active; + QSettings settings(m_author, m_appName); + settings.value(m_ledActive, active); + if(!active) { + QSettings settings(m_author, m_appName); + settings.setValue(m_remainingCount, m_led->remainingFlashCount()); + } } //! [4] -void ApplicationHeadless::settingsChanged(const QString & path) { - QSettings settings(m_author, m_appName); - if (settings.value(m_reset).toBool()) { - settings.setValue(m_reset, false); - settings.setValue(m_flashNumber, m_flashCount); - settings.setValue(m_remainingCount, m_flashCount); - m_led->cancel(); - delete m_led; - m_led = new Led(LedColor::Blue); - connect(m_led, SIGNAL(remainingFlashCountChanged(int)), this, SLOT(flashCountChanged(int))); - m_led->flash(m_flashCount); - } +void ApplicationHeadless::settingsChanged(const QString & path) +{ + QSettings settings(m_author, m_appName); + if (settings.value(m_reset).toBool()) { + settings.setValue(m_reset, false); + settings.setValue(m_flashNumber, m_flashCount); + settings.setValue(m_remainingCount, m_flashCount); + settings.value(m_ledActive, false); + m_led->cancel(); + disconnect(m_led, SIGNAL(remainingFlashCountChanged(int)), this, SLOT(flashCountChanged(int))); + disconnect(m_led, SIGNAL(activeChanged(bool)), this, SLOT(activeUpdate(bool))); + delete m_led; + m_led = new Led(LedColor::Blue, this); + bool ok = connect(m_led, SIGNAL(remainingFlashCountChanged(int)), this, SLOT(flashCountChanged(int))); + Q_ASSERT(ok); + ok = connect(m_led, SIGNAL(activeChanged(bool)), this, SLOT(activeUpdate(bool))); + Q_ASSERT(ok); + Q_UNUSED(ok); + m_led->flash(m_flashCount); + } } //! [2] -void ApplicationHeadless::init() { - m_led = new Led(LedColor::Blue, this); +void ApplicationHeadless::init() +{ + m_led = new Led(LedColor::Blue, this); - // set the initial qsettings keys/values upon startup - QSettings settings(m_author, m_appName); + // set the initial qsettings keys/values upon startup + QSettings settings(m_author, m_appName); - settings.setValue(m_serviceStatus, "running"); - settings.setValue(m_flashNumber, m_flashCount); - settings.setValue(m_remainingCount, m_flashCount); - // Force the creation of the settings file so that we can watch it for changes. - settings.sync(); + settings.setValue(m_serviceStatus, "running"); + settings.setValue(m_flashNumber, m_flashCount); + settings.setValue(m_remainingCount, m_flashCount); + // Force the creation of the settings file so that we can watch it for changes. + settings.sync(); - // Watcher for changes in the settings file. - settingsWatcher = new QFileSystemWatcher(this); - settingsWatcher->addPath(settings.fileName()); + // Watcher for changes in the settings file. + m_settingsWatcher->addPath(settings.fileName()); - // Do all the necessary signal/slot connections to be invokable to receive led updates. - bool ok = connect(m_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)), this, SLOT(onInvoked(const bb::system::InvokeRequest&))); - Q_ASSERT(ok); + // Do all the necessary signal/slot connections to be invokable to receive led updates. + bool ok = connect(m_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)), this, SLOT(onInvoked(const bb::system::InvokeRequest&))); + Q_ASSERT (ok); - ok = connect(m_led, SIGNAL(remainingFlashCountChanged(int)), this, SLOT(flashCountChanged(int))); - Q_ASSERT(ok); + ok = connect(m_led, SIGNAL(remainingFlashCountChanged(int)), this, SLOT(flashCountChanged(int))); + Q_ASSERT(ok); - ok = connect(m_led, SIGNAL(activeChanged(bool)), this, SLOT(activeUpdate(bool))); - Q_ASSERT(ok); + ok = connect(m_led, SIGNAL(activeChanged(bool)), this, SLOT(activeUpdate(bool))); + Q_ASSERT(ok); - ok = connect(settingsWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(settingsChanged(const QString&))); - Q_ASSERT(ok); - Q_UNUSED(ok); + ok = connect(m_settingsWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(settingsChanged(const QString&))); + Q_ASSERT(ok); + Q_UNUSED(ok); } //! [2] diff --git a/headlesservice/src/applicationheadless.hpp b/headlesservice/src/applicationheadless.hpp index 1a589e20..fddbebc6 100644 --- a/headlesservice/src/applicationheadless.hpp +++ b/headlesservice/src/applicationheadless.hpp @@ -19,15 +19,18 @@ #include #include -namespace bb { -class Application; -namespace system { -class InvokeManager; -class InvokeRequest; -} -namespace device { -class Led; -} +namespace bb +{ + class Application; + namespace system + { + class InvokeManager; + class InvokeRequest; + } + namespace device + { + class Led; + } } /*! @@ -37,68 +40,70 @@ class Led; * */ //! [0] -class ApplicationHeadless: public QObject { - Q_OBJECT +class ApplicationHeadless: public QObject +{ + Q_OBJECT public: - ApplicationHeadless(bb::Application *app); - virtual ~ApplicationHeadless() { - } + ApplicationHeadless(bb::Application *app); + virtual ~ApplicationHeadless() + { + } public Q_SLOTS: - /** - * Method invoked by the invocation framework - * upon bb.action.system.STARTED. Meaning when this - * service is install for the first time and upon startup - * of the system. - */ - void onInvoked(const bb::system::InvokeRequest& request); + /** + * Method invoked by the invocation framework + * upon bb.action.system.STARTED. Meaning when this + * service is install for the first time and upon startup + * of the system. + */ + void onInvoked(const bb::system::InvokeRequest& request); - /** - * Method hooked into the signal/slots mechanism, which - * gets invoked upon receiving remainingFlashCountChanged() signal - * from the Led instance. - */ - void flashCountChanged(int x); + /** + * Method hooked into the signal/slots mechanism, which + * gets invoked upon receiving remainingFlashCountChanged() signal + * from the Led instance. + */ + void flashCountChanged(int x); - /** - * Method hooked into the signal/slots mechanism, which - * gets invoked upon receiving fileChanged() signal - * from the settingsWatcher instance. - */ - void settingsChanged(const QString & path); + /** + * Method hooked into the signal/slots mechanism, which + * gets invoked upon receiving fileChanged() signal + * from the settingsWatcher instance. + */ + void settingsChanged(const QString & path); - /** - * Method invoked when a activeChanged() signal is - * received from the Led instance, indicating - * a led state change. - */ - void activeUpdate(bool active); + /** + * Method invoked when a activeChanged() signal is + * received from the Led instance, indicating + * a led state change. + */ + void activeUpdate(bool active); - /** - * Initialization method to create QSettings entries - * and prepare Led instance. - */ - void init(); + /** + * Initialization method to create QSettings entries + * and prepare Led instance. + */ + void init(); private: - // Invocation Manager instance for receiving system events - bb::system::InvokeManager *m_invokeManager; + // Invocation Manager instance for receiving system events + bb::system::InvokeManager *m_invokeManager; - static const QString m_author; // for creating settings - static const QString m_appName; // for creating settings + static const QString m_author; // for creating settings + static const QString m_appName; // for creating settings - // keys used in setting - static const QString m_flashNumber; - static const QString m_remainingCount; - static const QString m_serviceStatus; - static const QString m_ledActive; - static const QString m_reset; - // The Led instance - bb::device::Led *m_led; - // flash count holder - int m_flashCount; - // Watcher for qsettigns file changes - QFileSystemWatcher* settingsWatcher; + // keys used in setting + static const QString m_flashNumber; + static const QString m_remainingCount; + static const QString m_serviceStatus; + static const QString m_ledActive; + static const QString m_reset; + // The Led instance + bb::device::Led *m_led; + // flash count holder + int m_flashCount; + // Watcher for qsettigns file changes + QFileSystemWatcher* m_settingsWatcher; }; //! [0] #endif /* ApplicationHeadless_HPP_ */ diff --git a/headlesservice/src/main.cpp b/headlesservice/src/main.cpp index 99db9525..2845ba76 100644 --- a/headlesservice/src/main.cpp +++ b/headlesservice/src/main.cpp @@ -16,7 +16,6 @@ #include "applicationheadless.hpp" - using namespace bb; int main(int argc, char **argv) diff --git a/headlesserviceui/assets/.assets.index b/headlesserviceui/assets/.assets.index index 6cf9fec1..b4a8c5e6 100644 --- a/headlesserviceui/assets/.assets.index +++ b/headlesserviceui/assets/.assets.index @@ -1,5 +1,5 @@ -1 -3 -ColoredRectangle.qml -images/rect_overlay.png -main.qml +1 +3 +ColoredRectangle.qml +images/rect_overlay.png +main.qml diff --git a/headlesserviceui/src/applicationui.cpp b/headlesserviceui/src/applicationui.cpp index 396ad428..7c92828a 100644 --- a/headlesserviceui/src/applicationui.cpp +++ b/headlesserviceui/src/applicationui.cpp @@ -33,78 +33,86 @@ const QString ApplicationHeadless::m_reset = "Reset"; //! [0] using namespace bb::cascades; -ApplicationHeadless::ApplicationHeadless(bb::cascades::Application *app) : - QObject(app), m_remainingFlashCount(-1) { - // prepare the localization - m_pTranslator = new QTranslator(this); - m_pLocaleHandler = new LocaleHandler(this); +ApplicationHeadless::ApplicationHeadless(bb::cascades::Application *app) + : QObject(app) + , m_remainingFlashCount(-1) +{ + // prepare the localization + m_pTranslator = new QTranslator(this); + m_pLocaleHandler = new LocaleHandler(this); - QSettings settings(m_author, m_appName); - // Force the creation of the settings file so that we can watch it for changes. - settings.sync(); - // Watcher for changes in the settings file. - settingsWatcher = new QFileSystemWatcher(this); - settingsWatcher->addPath(settings.fileName()); - connect(settingsWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(settingsChanged(const QString&))); + QSettings settings(m_author, m_appName); + // Force the creation of the settings file so that we can watch it for changes. + settings.sync(); + // Watcher for changes in the settings file. + settingsWatcher = new QFileSystemWatcher(this); + settingsWatcher->addPath(settings.fileName()); + connect(settingsWatcher, SIGNAL(fileChanged(const QString&)), this, SLOT(settingsChanged(const QString&))); - // initial load - // Create scene document from main.qml asset, the parent is set - // to ensure the document gets destroyed properly at shut down. - QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this); - // expose this class to the qml context so that we can query it for the necessary values - // via properties, slots or invokable methods - qml->setContextProperty("_app", this); - // Create root object for the UI - AbstractPane *root = qml->createRootObject(); + // initial load + // Create scene document from main.qml asset, the parent is set + // to ensure the document gets destroyed properly at shut down. + QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this); + // expose this class to the qml context so that we can query it for the necessary values + // via properties, slots or invokable methods + qml->setContextProperty("_app", this); + // Create root object for the UI + AbstractPane *root = qml->createRootObject(); - // Set created root object as the application scene - app->setScene(root); + // Set created root object as the application scene + app->setScene(root); } //! [1] -bool ApplicationHeadless::isServiceRunning() { - qDebug() << "check for service running via qsettings..."; - QSettings settings(m_author, m_appName); - if (settings.value("ServiceStatus").isNull()) { - qDebug() << "found null value for ServiceStatus key..."; - } else { - QString status = settings.value("ServiceStatus").toString(); - if (status == "running") { - // update remaining flash count since service is already running - settingsChanged(""); - return true; - } - } - return false; +bool ApplicationHeadless::isServiceRunning() +{ + qDebug() << "check for service running via qsettings..."; + QSettings settings(m_author, m_appName); + if (settings.value("ServiceStatus").isNull()) { + qDebug() << "found null value for ServiceStatus key..."; + } else { + QString status = settings.value("ServiceStatus").toString(); + if (status == "running") { + // update remaining flash count since service is already running + settingsChanged(""); + return true; + } + } + return false; } -int ApplicationHeadless::flashCount() { - QSettings settings(m_author, m_appName); - if (settings.contains(m_flashNumber)) { - return settings.value(m_flashNumber).toInt(); - } - return 0; +int ApplicationHeadless::flashCount() +{ + QSettings settings(m_author, m_appName); + if (settings.contains(m_flashNumber)) { + return settings.value(m_flashNumber).toInt(); + } + return 0; } //! [1] //! [2] -void ApplicationHeadless::resetLED() { - QSettings settings(m_author, m_appName); - settings.setValue(m_reset, true); +void ApplicationHeadless::resetLED() +{ + QSettings settings(m_author, m_appName); + settings.setValue(m_reset, true); } -void ApplicationHeadless::setRemainingFlashCount(int x) { - m_remainingFlashCount = x; - qDebug() << "emitting update signal flc"; - Q_EMIT rFlashCountChanged(); +void ApplicationHeadless::setRemainingFlashCount(int x) +{ + m_remainingFlashCount = x; + qDebug() << "emitting update signal flc"; + Q_EMIT remainingFlashCountChanged(); } //! [2] -int ApplicationHeadless::remainingFlashCount() { - return m_remainingFlashCount; +int ApplicationHeadless::remainingFlashCount() +{ + return m_remainingFlashCount; } -void ApplicationHeadless::settingsChanged(const QString & path) { - qDebug() << "updating flash remaining counter"; - QSettings settings(m_author, m_appName); - setRemainingFlashCount(settings.value(m_remainingCount).toInt()); - qDebug() << "remaining count: " << settings.value(m_remainingCount).toString(); +void ApplicationHeadless::settingsChanged(const QString & path) +{ + qDebug() << "updating flash remaining counter"; + QSettings settings(m_author, m_appName); + setRemainingFlashCount(settings.value(m_remainingCount).toInt()); + qDebug() << "remaining count: " << settings.value(m_remainingCount).toString(); } diff --git a/headlesserviceui/src/applicationui.hpp b/headlesserviceui/src/applicationui.hpp index 8f3ee314..9b695246 100644 --- a/headlesserviceui/src/applicationui.hpp +++ b/headlesserviceui/src/applicationui.hpp @@ -18,11 +18,13 @@ #include #include -namespace bb { -namespace cascades { -class Application; -class LocaleHandler; -} +namespace bb +{ + namespace cascades + { + class Application; + class LocaleHandler; + } } class QTranslator; @@ -35,62 +37,61 @@ class QTranslator; * */ //! [0] -class ApplicationHeadless: public QObject { - Q_OBJECT - // property holding value for remaining flash count - Q_PROPERTY(int remainingFlashCount READ remainingFlashCount WRITE setRemainingFlashCount NOTIFY rFlashCountChanged) +class ApplicationHeadless: public QObject +{ + Q_OBJECT + // property holding value for remaining flash count + Q_PROPERTY(int remainingFlashCount READ remainingFlashCount WRITE setRemainingFlashCount NOTIFY remainingFlashCountChanged) public: - ApplicationHeadless(bb::cascades::Application *app); - virtual ~ApplicationHeadless() { - } - Q_INVOKABLE - void resetLED(); + ApplicationHeadless(bb::cascades::Application *app); + virtual ~ApplicationHeadless() {} + Q_INVOKABLE void resetLED(); - Q_SIGNALS: - // Emitted when the remaining flash count value has changed - void rFlashCountChanged(); +Q_SIGNALS: + // Emitted when the remaining flash count value has changed + void remainingFlashCountChanged(); public Q_SLOTS: - /** - * Method that can be invoked from within qml - * to read QSettings key/value for ServiceStatus, - * in order to decipher if service is running (active). - */ - bool isServiceRunning(); + /** + * Method that can be invoked from within qml + * to read QSettings key/value for ServiceStatus, + * in order to decipher if service is running (active). + */ + bool isServiceRunning(); - /** - * Method hooked into the signal/slots mechanism, which - * gets invoked upon receiving fileChanged() signal - * from the settingsWatcher instance. - */ - void settingsChanged(const QString & path); + /** + * Method hooked into the signal/slots mechanism, which + * gets invoked upon receiving fileChanged() signal + * from the settingsWatcher instance. + */ + void settingsChanged(const QString & path); - /** - * Method to retrieve the number of times the Led - * was set to flash by reading this from the QSettings. - */ - int flashCount(); + /** + * Method to retrieve the number of times the Led + * was set to flash by reading this from the QSettings. + */ + int flashCount(); private: - static const QString m_author; // for creating settings - static const QString m_appName; // for creating settings - static const QString m_flashNumber; - static const QString m_remainingCount; - static const QString m_reset; - static const QString m_serviceStatus; + static const QString m_author; // for creating settings + static const QString m_appName; // for creating settings + static const QString m_flashNumber; + static const QString m_remainingCount; + static const QString m_reset; + static const QString m_serviceStatus; - QTranslator* m_pTranslator; - bb::cascades::LocaleHandler* m_pLocaleHandler; - // QTimer used to periodically read QSettings to retrieve - // new remaining flash count value - int m_remainingFlashCount; - // setter to store the new remaining flash count value - void setRemainingFlashCount(int x); - // Convenience method to retrieve remaining flash count. - int remainingFlashCount(); - // Watcher for qsettigns file changes - QFileSystemWatcher* settingsWatcher; + QTranslator* m_pTranslator; + bb::cascades::LocaleHandler* m_pLocaleHandler; + // QTimer used to periodically read QSettings to retrieve + // new remaining flash count value + int m_remainingFlashCount; + // setter to store the new remaining flash count value + void setRemainingFlashCount(int x); + // Convenience method to retrieve remaining flash count. + int remainingFlashCount(); + // Watcher for qsettigns file changes + QFileSystemWatcher* settingsWatcher; }; //! [0] #endif /* ApplicationUI_HPP_ */ diff --git a/xandos/assets/.assets.index b/xandos/assets/.assets.index index 69c8fbd4..c922819e 100644 --- a/xandos/assets/.assets.index +++ b/xandos/assets/.assets.index @@ -1,9 +1,9 @@ -1 -7 -images/background.png -images/blank.png -images/grid.png -images/grid_start.png -images/o.png -images/x.png -main.qml +1 +7 +images/grid.png +images/grid_start.png +images/blank.png +images/o.png +images/x.png +images/background.png +main.qml diff --git a/xandos/assets/main.qml b/xandos/assets/main.qml index 1f76f3ff..ac60f019 100644 --- a/xandos/assets/main.qml +++ b/xandos/assets/main.qml @@ -109,7 +109,6 @@ Page { maxHeight: 140 visible: gameEnabled imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { // conditions to make sure that a selection can only be made // by the user in grid cells that have not already been selected @@ -127,7 +126,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" @@ -143,7 +141,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" @@ -165,7 +162,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" @@ -181,7 +177,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" @@ -197,7 +192,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" @@ -219,7 +213,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" @@ -235,7 +228,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" @@ -251,7 +243,6 @@ Page { maxWidth: 140 maxHeight: 140 imageSource: "asset:///images/blank.png" - scalingMethod: ScalingMethod.None onTouch: { if (event.isDown() && imageSource.toString().search("blank") != -1) { imageSource = "asset:///images/x.png" diff --git a/xandos/bar-descriptor.xml b/xandos/bar-descriptor.xml index 56f74fb6..d8c61e58 100644 --- a/xandos/bar-descriptor.xml +++ b/xandos/bar-descriptor.xml @@ -123,8 +123,9 @@ - bb.action.CHOICE - text/plain - + bb.action.STOP + * + + diff --git a/xandos/src/applicationui.cpp b/xandos/src/applicationui.cpp index a81c9477..36ef7484 100644 --- a/xandos/src/applicationui.cpp +++ b/xandos/src/applicationui.cpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "applicationui.hpp" #include "xandos.hpp" #include "droidlistener.hpp" @@ -30,20 +30,25 @@ ApplicationUI::ApplicationUI(bb::cascades::Application *app) // prepare the localization m_pTranslator = new QTranslator(this); m_pLocaleHandler = new LocaleHandler(this); - bool ok = QObject::connect(m_pLocaleHandler, SIGNAL(systemLanguageChanged()), this, SLOT(onSystemLanguageChanged())); + bool ok = connect(m_pLocaleHandler, SIGNAL(systemLanguageChanged()), this, + SLOT(onSystemLanguageChanged())); Q_ASSERT(ok); // initial load onSystemLanguageChanged(); - // Create the game ackend mechanism + // Create the game mechanism xandos *tac = new xandos(app, this); // created the server socket listener droidlistener *listener = new droidlistener(this); - // Start listening for connections on the server socket - listener->listen(); + ok = connect(listener, SIGNAL(droidSelection(const QString)), tac, SLOT(droidSelection(const QString))); Q_ASSERT(ok); + ok = connect(tac, SIGNAL(sendSelection(const int)), listener, SLOT(readyWrite(const int))); + Q_ASSERT(ok); Q_UNUSED(ok); + // Start listening for connections on the server socket + listener->listen(); + // Create scene document from main.qml asset, the parent is set // to ensure the document gets destroyed properly at shut down. QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this); @@ -55,7 +60,8 @@ ApplicationUI::ApplicationUI(bb::cascades::Application *app) app->setScene(root); } -void ApplicationUI::onSystemLanguageChanged() { +void ApplicationUI::onSystemLanguageChanged() +{ QCoreApplication::instance()->removeTranslator(m_pTranslator); // Initiate, load and install the application translation files. QString locale_string = QLocale().name(); diff --git a/xandos/src/applicationui.hpp b/xandos/src/applicationui.hpp index 701755e3..f8eb3d8f 100644 --- a/xandos/src/applicationui.hpp +++ b/xandos/src/applicationui.hpp @@ -1,28 +1,30 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef ApplicationUI_HPP_ #define ApplicationUI_HPP_ #include -namespace bb { -namespace cascades { -class Application; -class LocaleHandler; -} +namespace bb +{ + namespace cascades + { + class Application; + class LocaleHandler; + } } class QTranslator; @@ -33,11 +35,13 @@ class QTranslator; * */ -class ApplicationUI: public QObject { +class ApplicationUI: public QObject +{ Q_OBJECT public: ApplicationUI(bb::cascades::Application *app); - virtual ~ApplicationUI() { + virtual ~ApplicationUI() + { } private slots: void onSystemLanguageChanged(); diff --git a/xandos/src/droidlistener.cpp b/xandos/src/droidlistener.cpp index 6c10656a..bcf12838 100644 --- a/xandos/src/droidlistener.cpp +++ b/xandos/src/droidlistener.cpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "droidlistener.hpp" #include @@ -21,7 +21,8 @@ //! [0] droidlistener::droidlistener(QObject *parent) - : QObject(parent), m_port(9876) { + : QObject(parent), m_port(9876) +{ m_server = new QTcpServer(this); // Connect into the signal/slot mechanism to invoke this class method when a new connection // is available @@ -30,22 +31,29 @@ droidlistener::droidlistener(QObject *parent) Q_UNUSED(ok); } //! [0] -droidlistener::~droidlistener() { +droidlistener::~droidlistener() +{ + if (m_socket) { + disconnected(); + m_socket->deleteLater(); + } m_server->close(); m_server->deleteLater(); } //! [1] -void droidlistener::listen() { - qDebug() << "start listening for connections"; +void droidlistener::listen() +{ + qDebug() << "xandos: start listening for connections"; m_server->listen(QHostAddress::LocalHost, m_port); } //! [1] //! [2] -void droidlistener::newConnection() { +void droidlistener::newConnection() +{ m_socket = m_server->nextPendingConnection(); if (m_socket->state() == QTcpSocket::ConnectedState) { - qDebug() << "New connection established."; + qDebug() << "xandos: New connection established."; } // Make connections for reveiving disconnect and read ready signals for the // new connection socket @@ -57,18 +65,28 @@ void droidlistener::newConnection() { } //! [2] //! [3] -void droidlistener::readyRead() { +void droidlistener::readyRead() +{ QByteArray ba = m_socket->read(20); // Emit the droid selection when finished reading in the // data from the droid client socket Q_EMIT droidSelection(QString(ba)); } + +void droidlistener::readyWrite(const int code) +{ + if (m_socket && m_socket->state() == QTcpSocket::ConnectedState) { + m_socket->write(QByteArray::number(code)); + m_socket->flush(); + } +} //! [3] //! [4] -void droidlistener::disconnected() { - qDebug() << "Connection disconnected."; - disconnect(m_socket, SIGNAL(disconnected())); - disconnect(m_socket, SIGNAL(readyRead())); - m_socket->deleteLater(); +void droidlistener::disconnected() +{ + qDebug() << "xandOs: disconnecting..."; + disconnect(m_socket, SIGNAL(disconnected()), this, SLOT(disconnected())); + disconnect(m_socket, SIGNAL(readyRead()), this, SLOT(readyRead())); + m_socket->close(); } //! [4] diff --git a/xandos/src/droidlistener.hpp b/xandos/src/droidlistener.hpp index af6dc034..6f67a917 100644 --- a/xandos/src/droidlistener.hpp +++ b/xandos/src/droidlistener.hpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef DROIDLISTENER_HPP_ #define DROIDLISTENER_HPP_ @@ -22,7 +22,6 @@ class QTcpServer; class QTcpSocket; - /** * This class serves mainly as a server socket listening * for client connection(s). The client being a the droid @@ -30,7 +29,8 @@ class QTcpSocket; * to exchange grid selections between the user and the droid. */ //! [0] -class droidlistener: public QObject { +class droidlistener: public QObject +{ Q_OBJECT public: droidlistener(QObject *parent = 0); @@ -53,6 +53,13 @@ public Q_SLOTS: * as well, when the socket is ready to read data. */ void readyRead(); + + /** + * This method is used in order to write data out + * to the socket. + */ + void readyWrite(const int code); + /** * This method is invoked when the socket connection disconnects. */ diff --git a/xandos/src/main.cpp b/xandos/src/main.cpp index 99cdbc7b..958a8937 100644 --- a/xandos/src/main.cpp +++ b/xandos/src/main.cpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include @@ -23,7 +23,8 @@ using namespace bb::cascades; -Q_DECL_EXPORT int main(int argc, char **argv) { +Q_DECL_EXPORT int main(int argc, char **argv) +{ Application app(argc, argv); // Create the Application UI object, this is where the main.qml file diff --git a/xandos/src/xandos.cpp b/xandos/src/xandos.cpp index 6e05cd62..39dbb814 100644 --- a/xandos/src/xandos.cpp +++ b/xandos/src/xandos.cpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "xandos.hpp" @@ -28,24 +28,31 @@ //! [0] // The grid matrix with all the winning possibilities // representing the wins from left to right {D1,H1,H2,H3,V1,V2,V3,D2} -int xandos::m_possibilities[9][9] = { { 1, 1, 0, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 0, 0, 1, 1, 0 } - , { 0, 0, 1, 0, 1, 0, 0, 0, 0 }, { 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 0, 0, 0, 1, 0, 0 } - , { 0, 0, 0, 1, 1, 0, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1, 0, 0, 0 }, { 1, 0, 0, 1, 0, 0, 1, 0, 0 } }; +int xandos::m_possibilities[9][9] = { { 1, 1, 0, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 0, 0, 1, 1, 0 }, + { 0, 0, 1, 0, 1, 0, 0, 0, 0 }, { 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 0, 0, 0, 1, 0, 0 }, + { 0, 0, 0, 1, 1, 0, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1, 0, 0, 0 }, { 1, 0, 0, 1, 0, 0, 1, 0, 0 } }; //! [0] //! [1] xandos::xandos(bb::cascades::Application* app, QObject *parent) : QObject(parent) , m_size(sizeof(m_possibilities) / sizeof(m_possibilities[0])) - , m_gameMatrix( { 0, 0, 0, 0, 0, 0, 0, 0 }) + , m_gameMatrix({ 0, 0, 0, 0, 0, 0, 0, 0 }) , m_invokeManager(new bb::system::InvokeManager(this)) , m_app(app) { } //! [1] -xandos::~xandos() { +xandos::~xandos() +{ } //! [2] -void xandos::select(int index, int player, bool send) { +void xandos::select(int index, int player, bool send) +{ + if (0 > index || 8 < index) { + qDebug() << "XandOs: invalid index ->" << index; + return; + } + m_possibilities[index][8] = 1; for (int i = 0; i < 8; i++) { // Add the matrix at the selected index to the game matrix @@ -68,11 +75,12 @@ void xandos::select(int index, int player, bool send) { return; } if (send) { - sendSelection(index); + Q_EMIT sendSelection(index); } } //! [2] -void xandos::resetGame() { +void xandos::resetGame() +{ for (int i = 0; i < m_size; i++) { // reset all grid selections to 0's m_possibilities[i][8] = 0; @@ -83,21 +91,23 @@ void xandos::resetGame() { } } //! [3] -void xandos::startDroid() { +void xandos::startDroid() +{ qDebug() << "requesting to start droid"; bb::system::InvokeRequest request; request.setTarget("com.example.xandos.droid"); request.setAction("bb.action.START"); request.setMimeType("text/plain"); bb::system::InvokeTargetReply *reply = m_invokeManager->invoke(request); - if(!reply) { + if (!reply) { qDebug() << "failed to start droid: " << reply->errorCode(); reply->deleteLater(); } } -void xandos::stopDroid() { - qDebug() << "requesting to terminate droid"; +void xandos::stopDroid() +{ + qDebug() << "XandOs: requesting to terminate droid"; bb::system::InvokeRequest request; request.setTarget("com.example.xandos.droid"); request.setAction("bb.action.STOP"); @@ -109,11 +119,12 @@ void xandos::stopDroid() { } //! [3] //! [4] -void xandos::droidSelection(const QString choice) { +void xandos::droidSelection(const QString choice) +{ // the first droid choice being a -1 that represents // the droid establishing communication and is in ready state to play - if(-1 == choice.toInt()) { - qDebug() << "emit droid ready"; + if (-1 == choice.toInt()) { + qDebug() << "XandOs: emit droid ready"; Q_EMIT droidReady(); return; } @@ -123,27 +134,14 @@ void xandos::droidSelection(const QString choice) { image->setImageSource(QUrl("asset:///images/o.png")); select(choice.toInt(), -1, false); } else { - qDebug() << "failed to find ImageView: " << choice; + qDebug() << "XandOs: failed to find ImageView: " << choice; } } //! [4] -//! [5] -void xandos::sendSelection(int index) { - qDebug() << "sending user selection to droid"; - bb::system::InvokeRequest request; - request.setTarget("com.example.xandos.droid"); - request.setAction("bb.action.CHOICE"); - request.setMimeType("text/plain"); - request.setData(QString::number(index).toUtf8()); - bb::system::InvokeTargetReply *reply = m_invokeManager->invoke(request); - if (!reply) { - qDebug() << "failed xandos.droid invocation: " << reply->errorCode(); - reply->deleteLater(); - } -} -//! [5] + //! [6] -bool xandos::noMoreSelections() { +bool xandos::noMoreSelections() +{ for (int i = 0; i < m_size; i++) { if (0 == m_possibilities[i][8]) { return false; diff --git a/xandos/src/xandos.hpp b/xandos/src/xandos.hpp index 1a7021ab..e3680092 100644 --- a/xandos/src/xandos.hpp +++ b/xandos/src/xandos.hpp @@ -1,31 +1,34 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef XANDOS_HPP_ #define XANDOS_HPP_ #include -namespace bb { -namespace cascades { -class Application; -} -namespace system { -class InvokeManager; -class InvokeRequest; -} +namespace bb +{ + namespace cascades + { + class Application; + } + namespace system + { + class InvokeManager; + class InvokeRequest; + } } /** @@ -34,7 +37,8 @@ class InvokeRequest; * represents O sprite. */ //! [0] -class xandos: public QObject { +class xandos: public QObject +{ Q_OBJECT public: xandos(bb::cascades::Application* app, QObject *parent = 0); @@ -86,14 +90,15 @@ public Q_SLOTS: // the droid is ready to play void droidReady(); -private: /** - * Method invoked to send the user selection + * Sginal emitting the user selection * to the droid, in order to keep in synce both * game matrices. */ void sendSelection(int index); +private: + /** * Convenience method to check the grid * matrix that there are no more selections available diff --git a/xandos/translations/xandos.ts b/xandos/translations/xandos.ts index cceb1033..4a20953f 100644 --- a/xandos/translations/xandos.ts +++ b/xandos/translations/xandos.ts @@ -4,22 +4,22 @@ main - + Start Game of XandOs? - + The droid is ready when the grid turns green - + Start - + Cancel @@ -29,32 +29,32 @@ - + Would you like to play again? - + Yes - + No - + Droid has WON! - + You have WON! - + It's a TIE! diff --git a/xandosdroid/src/applicationheadless.cpp b/xandosdroid/src/applicationheadless.cpp index 254c8e45..76eaa0b5 100644 --- a/xandosdroid/src/applicationheadless.cpp +++ b/xandosdroid/src/applicationheadless.cpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "applicationheadless.hpp" #include "xandosdroid.hpp" diff --git a/xandosdroid/src/applicationheadless.hpp b/xandosdroid/src/applicationheadless.hpp index ca7be4a6..fb2f45a4 100644 --- a/xandosdroid/src/applicationheadless.hpp +++ b/xandosdroid/src/applicationheadless.hpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef ApplicationHeadless_HPP_ #define ApplicationHeadless_HPP_ @@ -23,20 +23,20 @@ namespace bb class Application; } -class QTranslator; - /*! * @brief Application object * * */ -class ApplicationHeadless : public QObject +class ApplicationHeadless: public QObject { Q_OBJECT public: ApplicationHeadless(bb::Application *app); - virtual ~ApplicationHeadless() { } + virtual ~ApplicationHeadless() + { + } }; #endif /* ApplicationHeadless_HPP_ */ diff --git a/xandosdroid/src/main.cpp b/xandosdroid/src/main.cpp index c07e13f0..681feff5 100644 --- a/xandosdroid/src/main.cpp +++ b/xandosdroid/src/main.cpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include #include "applicationheadless.hpp" diff --git a/xandosdroid/src/xandosdroid.cpp b/xandosdroid/src/xandosdroid.cpp index e06c3aa7..e58741a1 100644 --- a/xandosdroid/src/xandosdroid.cpp +++ b/xandosdroid/src/xandosdroid.cpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "xandosdroid.hpp" #include #include @@ -20,79 +20,65 @@ #include #include +#include //! [0] // Grid selections with possible winning scenarios -int xandosdroid::m_possibilities[9][9] = { { 1, 1, 0, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 0, 0, 1, 1, 0 } - , { 0, 0, 1, 0, 1, 0, 0, 0, 0 }, { 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 0, 0, 0, 1, 0, 0 } - , { 0, 0, 0, 1, 1, 0, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1, 0, 0, 0 }, { 1, 0, 0, 1, 0, 0, 1, 0, 0 } }; +int xandosdroid::m_possibilities[9][9] = { { 1, 1, 0, 0, 1, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 1, 0, 0, 0, 0, 1, 1, 0 }, + { 0, 0, 1, 0, 1, 0, 0, 0, 0 }, { 1, 0, 1, 0, 0, 1, 0, 1, 0 }, { 0, 0, 1, 0, 0, 0, 1, 0, 0 }, + { 0, 0, 0, 1, 1, 0, 0, 1, 0 }, { 0, 0, 0, 1, 0, 1, 0, 0, 0 }, { 1, 0, 0, 1, 0, 0, 1, 0, 0 } }; //! [0] //! [1] xandosdroid::xandosdroid(bb::Application *parent) : QObject(parent) , m_size(sizeof(m_possibilities) / sizeof(m_possibilities[0])) - , m_gameMatrix({ 0, 0, 0, 0, 0, 0, 0, 0 }) - , m_nextMove(-1) + , m_gameMatrix({ 0, 0, 0, 0, 0, 0, 0, 0 }), m_nextMove(-1) , m_port(9876) , m_invokeManager(new bb::system::InvokeManager(this)) , m_app(parent) - , m_clientSocket(new QTcpSocket(this)) { + , m_clientSocket(new QTcpSocket(this)) +{ + srand (time(NULL)); // establish signal/slot connection with invocation manager bool ok = connect(m_invokeManager, SIGNAL(invoked(const bb::system::InvokeRequest&)), this, SLOT(onInvoked(const bb::system::InvokeRequest&))); - Q_ASSERT(ok); + Q_ASSERT (ok); // establish signal/slot connection with socket for being informed of new established connection ok = connect(m_clientSocket, SIGNAL(connected()), this, SLOT(connected())); Q_ASSERT(ok); Q_UNUSED(ok); } //! [1] -xandosdroid::~xandosdroid() { - m_clientSocket->close(); - m_clientSocket->deleteLater(); +xandosdroid::~xandosdroid() +{ + if (m_clientSocket) { + qDebug() << "XandOsDroid: closing socket"; + disconnect(m_clientSocket, SIGNAL(disconnected()), this, SLOT(disconnected())); + m_clientSocket->close(); + m_clientSocket->deleteLater(); + } } //! [2] -void xandosdroid::onInvoked(const bb::system::InvokeRequest& request) { +void xandosdroid::onInvoked(const bb::system::InvokeRequest& request) +{ if (request.action().compare("bb.action.START") == 0) { qDebug() << "XandOsDroid : start requested"; // once the headless is started, communicate back to ui that its ready to play connectToServer(); } else if (request.action().compare("bb.action.STOP") == 0) { - qDebug() << "XandOsDroid: stop request"; + qDebug() << "XandOsDroid: stop requested"; // terminate headless droid - terminateDroid(); - } else if (request.action().compare("bb.action.CHOICE") == 0) { - int choice = QString(request.data()).toInt(); - qDebug() << "XandOsDroid: received user choice: " << choice; - // mark the user selection in the grid matrix and update the - // game matrix state - select(choice, 1); - // verify there are still moves available - if (availableChoices().isEmpty()) { - qDebug() << "XandOsDroid: game over!"; - terminateDroid(); - } - // Check whether you have any two in a row sequences - int nextM = nextMove(-2); - // If no, than block the user based on his possible selections for - // a consecutive sequence - if (-1 == nextM) { - nextM = nextMove(1); - } - qDebug() << "XandOsDroid: droid selection: " << nextM; - // send your next selection to the UI. - sendSelection(nextM); - + disconnected(); } else { - qDebug() << "XandOsDroid : unknown service request " - << request.action(); + qDebug() << "XandOsDroid : unknown service request " << request.action(); } } //! [2] //! [3] -void xandosdroid::select(int index, int player) { - if(0 > index || 8 < index) { - qDebug() << "XandOsDroid: invalid index -> index"; +void xandosdroid::select(int index, int player) +{ + if (0 > index || 8 < index) { + qDebug() << "XandOsDroid: invalid index -> " << index; return; } // update the grid matrix with the selection @@ -103,18 +89,18 @@ void xandosdroid::select(int index, int player) { // verify if droid has 3 in a row sequences and terminate if so. if (0 != m_gameMatrix[i] && m_gameMatrix[i] % 3 == 0) { qDebug() << "XandOsDroid: droid has won"; - terminateDroid(); + disconnected(); } } } //! [3] //! [4] -QList xandosdroid::availableChoices(int index) { +QList xandosdroid::availableChoices(int index) +{ QList choices; for (int i = 0; i < m_size; i++) { // Check the selections, and base the result on the cell index if index is set. - if (0 == m_possibilities[i][8] - && (index == -1 || 1 == m_possibilities[i][index])) { + if (0 == m_possibilities[i][8] && (index == -1 || 1 == m_possibilities[i][index])) { choices << i; } } @@ -122,54 +108,84 @@ QList xandosdroid::availableChoices(int index) { } //! [4] //! [5] -void xandosdroid::sendSelection(int index) { - if (-1 != m_nextMove) { - qDebug() << "XandOsDroid: failed to send last move, check code"; - return; - } +void xandosdroid::sendSelection(const int index) +{ m_nextMove = index; connectToServer(); } -void xandosdroid::connectToServer() { - qWarning() << "XandOsDroid: connecting to server socket"; +void xandosdroid::connectToServer() +{ if (!m_clientSocket->isOpen()) { + qDebug() << "XandOsDroid: connecting to server socket"; m_clientSocket->connectToHost(QHostAddress::LocalHost, m_port); bool ok = connect(m_clientSocket, SIGNAL(disconnected()), this, SLOT(disconnected())); Q_ASSERT(ok); + ok = connect(m_clientSocket, SIGNAL(readyRead()), this, SLOT(readyRead())); + Q_ASSERT(ok); Q_UNUSED(ok); } else { connected(); } } -void xandosdroid::connected() { - qWarning() << "XandOsDroid: Connection established."; +void xandosdroid::connected() +{ + qWarning() << "XandOsDroid: writing to socket."; m_clientSocket->write(QByteArray::number(m_nextMove)); m_clientSocket->flush(); select(m_nextMove, -1); - m_nextMove = -1; } //! [5] -void xandosdroid::disconnected() { - m_clientSocket->close(); - resetGame(); +void xandosdroid::readyRead() +{ + QByteArray ba = m_clientSocket->read(20); + qDebug() << "XandOsDroid: received move from user: " << ba; + const int choice = ba.toInt(); + // mark the user selection in the grid matrix and update the + // game matrix state + select(choice, 1); + // verify there are still moves available + if (availableChoices().isEmpty()) { + qDebug() << "XandOsDroid: game over!"; + disconnected(); + return; + } + // Check whether you have any two in a row sequences + int nextM = nextMove(-2); + // If no, than block the user based on his possible selections for + // a consecutive sequence + if (-1 == nextM) { + nextM = nextMove(1); + } + qDebug() << "XandOsDroid: droid selection: " << nextM; + // send your next selection to the UI. + sendSelection(nextM); +} + +void xandosdroid::disconnected() +{ + qDebug() << "XandOsDroid: disconnected..."; bb::Application::instance()->quit(); } //! [6] -int xandosdroid::nextMove(int player) { +int xandosdroid::nextMove(int player) +{ QList moves; + bool blockUserWin = false; for (int i = 0; i < 8; i++) { // check for next move based on players // current existing 2 sequences, otherwise // block player's 1 sequence selections. - if ((1 * player) == m_gameMatrix[i]) { + if ((1 * player) == m_gameMatrix[i] && !blockUserWin) { moves << availableChoices(i); } else if ((2 * player) == m_gameMatrix[i]) { - moves.clear(); + if (!blockUserWin) { + moves.clear(); + blockUserWin = true; + } moves << availableChoices(i); - break; } } if (moves.isEmpty()) { @@ -179,17 +195,14 @@ int xandosdroid::nextMove(int player) { return moves.at(rand() % moves.size()); } //! [6] -//! [7] -inline void xandosdroid::terminateDroid() { - qDebug() << "XandOsDroid: terminating droid"; - resetGame(); -} -//! [7] -void xandosdroid::resetGame() { + +void xandosdroid::resetGame() +{ for (int i = 0; i < 9; i++) { m_possibilities[i][8] = 0; if (i < 8) { m_gameMatrix[i] = 0; } } + m_nextMove = -1; } diff --git a/xandosdroid/src/xandosdroid.hpp b/xandosdroid/src/xandosdroid.hpp index 5a9a28cd..08fa4345 100644 --- a/xandosdroid/src/xandosdroid.hpp +++ b/xandosdroid/src/xandosdroid.hpp @@ -1,18 +1,18 @@ /* -* Copyright (c) 2013 BlackBerry Limited. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright (c) 2013 BlackBerry Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #ifndef XANDOSDROID_HPP_ #define XANDOSDROID_HPP_ @@ -20,16 +20,16 @@ #include #include -namespace bb { -class Application; -namespace system { -class InvokeManager; -class InvokeRequest; -} +namespace bb +{ + class Application; + namespace system + { + class InvokeManager; + class InvokeRequest; + } } - - /** * This class represents the game droid player. Basically * containing the same matrices as it's UI counterpart in order @@ -37,8 +37,9 @@ class InvokeRequest; * has logic to choose the next move based on the user selections. */ //! [0] -class xandosdroid: public QObject { -Q_OBJECT +class xandosdroid: public QObject +{ + Q_OBJECT public: xandosdroid(bb::Application *parent = 0); virtual ~xandosdroid(); @@ -66,6 +67,12 @@ public Q_SLOTS: */ void onInvoked(const bb::system::InvokeRequest& request); + /** + * This method is invoked through the signal/slot mechanism + * as well, when the socket is ready to read data. + */ + void readyRead(); + /** * This method is invoked when the socket connects * to it's UI server socket for grid selection communication. @@ -87,18 +94,13 @@ public Q_SLOTS: /** * Method to transmit the droid selection back to the UI. */ - void sendSelection(int index); + void sendSelection(const int index = -1); /** * Method to establish the socket connection with * the UI server socket. */ - void connectToServer() - - /** - * Method invoked when the droid termination is requested. - */; - inline void terminateDroid(); + void connectToServer(); void resetGame();