68 : QObject(parent), m_engine(scriptEngine), m_container(container)
72 zDebug() <<
"ZblApp::ZblApp";
78 connect( &
zApp.zStatus(), SIGNAL(dataReady(
const QString&)),
81 connect(
this, SIGNAL(destroyed(QObject*)),
84 connect(
this, SIGNAL(
exit(
int)),
85 this, SLOT(
exitApp(
int)), Qt::QueuedConnection);
91 zDebug() <<
"ZblApp::~ZblApp";
99 throw ZblException(
"ZblApp::zInstance - a ZblApp object hasn't been " 100 "constructed for the current thread.");
102 return *
m_zApp.localData()->m_app;
140 map.insert(
"SettingsUserScope", QSettings::UserScope);
141 map.insert(
"SettingsSystemScope", QSettings::SystemScope);
146 testMap.insert(
"VALUE_ONE", 1);
147 testMap.insert(
"VALUE_TWO", 2);
150 map.insert(
"Test", QVariant::fromValue(testMap));
153 m_tags = QVariant::fromValue(map);
162 QQmlEngine *
engine, QJSEngine *scriptEngine)
166 zDebug() <<
"ZblApp::getSingletonType";
178 zDebug() <<
"ZblApp::registerSingletonType";
186 return qmlRegisterSingletonType<ZblApp>(
232 zDebug() <<
"ZblException exception caught: " << zblEx.
what();
236 zDebug() <<
"unknown exception caught";
252 setError(QJSValue(
"returnExceptionError"));
254 return m_errorObject;
263 setError(QJSValue(
"returnExceptionError"));
265 return error().toVariant();
271 QWriteLocker lock(&
m_lock);
273 if(errValue.isError())
276 errValue.property(QStringLiteral(
"name")).toString(),
278 errValue.property(QStringLiteral(
"message")).toString());
283 QStringLiteral(
"Error"),
285 errValue.toString());
293 QReadLocker lock(&
m_lock);
300 QWriteLocker lock(&
m_lock);
308 QJSValue err(
m_engine->evaluate(
"new Error();"));
309 err.setProperty(QStringLiteral(
"facility"), QJSValue(
zThreadErr.error().facility()));
310 err.setProperty(QStringLiteral(
"code"), QJSValue(
zThreadErr.error().code()));
311 err.setProperty(QStringLiteral(
"message"), QJSValue(
zThreadErr.error().message()));
312 err.setProperty(QStringLiteral(
"description"), QJSValue(
zThreadErr.error().description()));
313 err.setProperty(QStringLiteral(
"isError"), QJSValue(
zThreadErr.error().isError()));
319 QString msg(evaluateError.toString());
320 QString desc(
"ZBL:0:%1");
322 QJSValue err(
m_engine->evaluate(
"new Error();"));
323 err.setProperty(QStringLiteral(
"facility"), QJSValue(
"ZBL"));
324 err.setProperty(QStringLiteral(
"code"), QJSValue(0));
325 err.setProperty(QStringLiteral(
"message"), QJSValue(msg));
326 err.setProperty(QStringLiteral(
"description"), QJSValue(desc.arg(msg)));
327 err.setProperty(QStringLiteral(
"isError"),
true);
338 QFile file(filePath);
340 status(QString(
"zInclude: %1").arg(filePath));
344 QString msg(
"zInclude -- Non-existent file: %1");
347 else if(!file.open(QIODevice::ReadOnly))
349 QString msg(
"zInclude -- Can't open file for reading: %1");
353 QTextStream stream(&file);
355 script = stream.readAll();
357 if(!script.isEmpty())
358 result =
m_engine->evaluate(script, fileUrl, 1);
380 return result.toVariant();
387 qDebug() <<
"z@ " << text;
407 return zApp.getAppData(dataKey);
417 QMetaObject::invokeMethod(&
zApp,
"getAppData",
418 Qt::BlockingQueuedConnection,
419 Q_RETURN_ARG( QVariant, retValue),
420 Q_ARG(
int, dataKey));
432 return zApp.getAppName();
442 QMetaObject::invokeMethod(&
zApp,
"getAppName",
443 Qt::BlockingQueuedConnection,
444 Q_RETURN_ARG(QVariant, retValue));
452 return QThread::currentThread() == qApp->thread();
488 QTextStream instream(stdin);
489 QString text = instream.readLine(0);
497 QTextStream outstream(stdout, QIODevice::WriteOnly | QIODevice::Text);
507 QTextStream errstream(stderr, QIODevice::WriteOnly | QIODevice::Text);
521 "Programming error - object passed is not a Zbl::ZByteArray");
599 const QString& application,
600 const QString& organization)
607 bool ok = settings->open(scope, application, organization);
611 throw ZblException(QString(
"ZblApp::newAppSettings - can't open app settings " 612 "for scope: %1, application: %2, organization: %3")
613 .arg(scope).arg(application, organization));
626 bool ok = settings->open(filePath);
630 throw ZblException(QString(
"ZblApp::newSettingsFile - can't open settings " 631 "file: %1").arg(filePath));
653 QObject* settings =
nullptr;
661 const QString& sprocketUri,
const QString& objectName)
663 QObject* ob =
nullptr;
671 "No Sprocket plugin has been imported for uri: %1").arg(sprocketUri));
675 ob = factory->createObject(
cStr(objectName));
689 "Sprocket already imported: %1").arg(sprocketUri));
691 ZblFactory* factory =
zCog.createFactory(
cStr(sprocketUri), versionMajor, versionMinor);
695 "Can't import Sprocket: %1").arg(sprocketUri));
697 factory->setParent(
this);
710 const QString& fileName)
714 zCog.mapResource(uri.toUtf8(),
733 zCog.mapPluginResources(fileName.toUtf8(), qmlregister),
749 QProcessEnvironment::systemEnvironment().toStringList(),
756 QThread* thread = QThread::currentThread();
758 if(thread == qApp->thread())
761 return thread->isInterruptionRequested();
769 QString(
"<Thread ID Error>"),
778 QString(
"<Thread ID Error>"),
789 QMetaObject::invokeMethod(&
zApp,
"addLibraryPath",
790 Qt::BlockingQueuedConnection,
791 Q_ARG(
const QString&, path));
794 zWarning() <<
"Zuble programming ERROR: addLibaryPath not supported for background threads.";
800 qApp->addLibraryPath(path);
813 QString homePath(QDir::homePath() +
"/");
815 homePath, path, includeUrlScheme);
837 if(scheme ==
"qrc:/" || scheme ==
":/")
861 QJSValue timerFunction,
862 QJSValue timerArgument,
869 timerID = startTimer(milliseconds);
875 zWarning() <<
"ZblApp::startTimerInterval - warning: script timer ID reused";
901 const int timerID =
event->timerId();
908 QJSValueList timerArgs;
909 timerArgs.append(call.timerArg);
925 timerKeys::iterator it(timers.begin());
927 while(it != timers.end())
942 QThread::msleep(milliseconds);
951 unsigned long waitTime = 25;
952 unsigned long count = milliseconds / waitTime;
953 QAbstractEventDispatcher* d = QThread::currentThread()->eventDispatcher();
959 zDebug() <<
"Waiting: " << count <<
" * " << waitTime <<
" milliseconds.";
961 for(
unsigned long i=0; i < count; i++)
963 QThread::msleep(waitTime);
965 d->processEvents(QEventLoop::AllEvents);
971 zDebug() <<
"Done Waiting: " << count <<
" * " << waitTime <<
" milliseconds.";
999 zWarning() <<
"ZblApp::alert - Programming error! Background ZblApp " 1000 "expects it's container to be a ZScriptThread object.";
1005 zDebug() <<
"SENDING ALERT id=" << signalID <<
", wait = " << wait <<
", payload=" << payload;
1013 int metatype = int(payload.type());
1015 zDebug() <<
"metatype = " << metatype;
1020 case QMetaType::Int:
1022 zDebug() <<
"QMetaType = Int";
1024 strPayload = payload.toString();
1029 case QMetaType::Double:
1031 zDebug() <<
"QMetaType = Double";
1033 strPayload = payload.toString();
1038 case QMetaType::QString:
1040 zDebug() <<
"QMetaType = QString";
1042 strPayload = payload.toString();
1047 case QMetaType::User:
1049 zDebug() <<
"QMetaType = User";
1051 static const int qjstype = QVariant::fromValue(QJSValue()).userType();
1053 if(payload.userType() == qjstype)
1055 zDebug() <<
"QMetaType = QJSValue";
1057 QVariant var = payload.value<QJSValue>().
toVariant();
1062 zDebug() <<
"Stringified payload=" << strPayload;
1066 QString msg(
"ZblApp::alert received unrecognized QVariant type: %1");
1073 QString msg(
"ZblApp::alert received unrecognized QVariant type: %1");
1074 msg = msg.arg(metatype);
1082 Qt::ConnectionType connection = wait ? Qt::BlockingQueuedConnection
1083 : Qt::QueuedConnection;
1085 QMetaObject::invokeMethod(
m_container,
"onThreadAlert",
1087 Q_ARG(QString, signalID),
1088 Q_ARG(QString, strPayload),
1089 Q_ARG(
int, static_cast<int>(conversion)));
1091 zDebug() <<
"SENT ALERT id=" << signalID <<
", payload=" << payload;
1102 zDebug() <<
"ZblApp calling QCoreApplication::quit()...";
1104 QMetaObject::invokeMethod(
m_engine,
"quit",
1105 Qt::QueuedConnection);
1114 zWarning() <<
"ZblApp::quit - Programming error! Background ZblApp " 1115 "expects it's container to be a ZScriptThread object.";
1123 Qt::QueuedConnection);
1135 zDebug() <<
"ZblApp calling QCoreApplication::exit()...";
1139 QCoreApplication::exit(returnCode);
1143 zWarning() <<
"ZblApp::exit - Programming ERROR: exit() method must be called from main thread.";
1152 zDebug() <<
"ZblApp::onDestroyed";
Q_INVOKABLE QObject * newTextStream(const QString &text)
Returns a new ZTextStream object for reading and writing text in strings.
void stopAllTimers()
Stops all existing timers that were started with ZblApp::startTimerInterval() and destroys them...
Q_INVOKABLE QObject * newMessageQueue()
Returns a new ZMessageQueue object for passing messages between components.
This class supports streaming of text and binary data.
Q_INVOKABLE QVariant getAppData(int dataKey)
Allows background threads to obtain application object data.
int startTimerInterval(QJSValue timerFunction, QJSValue timerArgument, int milliseconds)
Calls the specified javascript function periodically at the specified interval.
This class wraps QFileSystemWatcher and adds path reference counting.
Q_INVOKABLE void status(const QString &text)
Sends status information to Zuble's main status text feed.
QML/Javascript wrapper for the QProcess class, allows QML programs to spawn and communicate with a ba...
A Javascript dictionary object.
Q_INVOKABLE QObject * newSettingsFile(const QString &filePath)
Returns a new ZSettings object representing a JSON file in the specified file location.
Q_INVOKABLE QObject * newThread()
Returns a new ZScriptThread object.
static QObject * getSingletonType(QQmlEngine *engine, QJSEngine *scriptEngine)
Obtains an new instance of this class. This is called by the QML engine to create the ZblApp object f...
static QThreadStorage< AppPtr * > m_zApp
ZblApp is a thread singleton - ie one ZblApp object exists per Zuble thread. This variable holds a po...
Q_INVOKABLE QVariant getAppName()
Obtains Zuble application name.
Q_INVOKABLE QObject * newProcess()
Returns a new ZProcess object for creating an operating system process.
static QString getPathScheme(const QString &path)
Obtains the scheme part of a URL path.
Q_INVOKABLE QStringList getApplicationArguments()
obtain a string array containing arguments passed on the command line
static ZblApp & zInstance()
Obtains a reference to the ZblApp object for the current thread.
Q_INVOKABLE QObject * newSchemaValidator()
Returns a new ZSchemaValidator object for validating XML documents against XML schemas.
Access and manipulate file directories. This class is a Javascript wrapper for QDir objects...
Q_INVOKABLE QObject * getLogBuffer()
Obtain the log buffer data model.
Q_INVOKABLE QString resolveAppPath(const QString &path, bool includeUrlScheme=true)
Converts Zuble application paths into canonical file paths. Zuble applicaiton paths are prefixed with...
void setError(QJSValue theObject)
Sets the internal Javascript Error object.
QVariant returnAnException()
test method to return a javascript Error object
A mechanism for safely holding a ZblApp object pointer in thread local storage.
A QML type that manages reading JSON formatted Zuble log files. QML programs create using Zbl...
void printErr(const QString &text, bool newLine=true)
Writes text to stderr.
Q_INVOKABLE bool isResourcePath(const QString &path)
Determine if the specified path refers to a an object inside a Qt binary resource.
void throwAnException()
test method to throw a ZblException
void throwDeeperException()
test method to throw a ZblException
QJSEngine * m_engine
The QJSEngine that owns the javascript context for this ZblApp object.
void collectGarbage()
Instructs the javascript engine to garbage collect memory as soon as possible.
Q_INVOKABLE QObject * newMailslot()
Returns a new ZMailslot object for passing messages between components.
This class provides a means of directing a text stream to listeners.
enum Zbl::ZScriptThread::alertConversion AlertConversion
Q_INVOKABLE QString resolveHomePath(const QString &path, bool includeUrlScheme=true)
Converts Zuble home paths into canonical file paths. Zuble home paths are prefixed with "home://" and...
QString getRootPath()
Obtains the canonical path to the Zuble application's root directory.
Q_INVOKABLE void addLibraryPath(const QString &path)
Add the specified path to the beginning of the library search path.
Q_INVOKABLE bool isInterruptRequested()
Calls QThread::isInterruptRequested() on the current thread. Does nothing and returns false if curren...
Q_INVOKABLE QObject * getLogBuffer()
Obtain Zuble's log buffer data model.
Q_INVOKABLE QString bundleMetadata(const QString &bundleID)
Returns the Zuble settings metadata text for the specified settings bundle ID.
#define ZBL_REGISTER_LOGGED_OBJECT
Q_INVOKABLE QObject * newTableModel()
Returns a new ZTableModel object for passing variant data to QML views.
QJSEngine & engine()
Returns the QJSEngine object associated with this object.
Q_INVOKABLE bool isInMainThread()
Determine if the caller is currently executing in the Qt's main GUI thread.
Q_INVOKABLE bool mapPluginResources(const QString &fileName, bool qmlregister=false)
Make a plugin's binary resource files known to Zuble so they can be loaded into QML by calling Zbl...
Q_INVOKABLE bool mapResource(const QString &uri, int versionMajor, int versionMinor, const QString &fileName)
Called by Javascript programs to make binary resource files known to Zuble so they can be loaded into...
void send(const QString &text)
Q_INVOKABLE QObject * newScopedMap()
Returns a new ZScopedMap object for mapping arbitrary strings to javascript values.
Q_INVOKABLE bool registerResource(const QString &uri, int versionMajor, int versionMinor)
Makes a Zuble resource file known to QML and background javascript programs.
static const QString m_appPathPrefix
URL scheme used to specify Zuble app directory location: "zbl://".
Q_INVOKABLE QObject * newDir()
Returns a new ZDir object for reading and manipulating file directories.
QSharedPointer< QString > ZqStringPtr
A message queue that decouples sending and processing of messages.
A thread class to support Zuble's background Javascript processing.
bool isError()
Determines if an error state exists for this thread.
ZblApp(QJSEngine *scriptEngine, ZScriptThread *container=nullptr, QObject *parent=nullptr)
factoryMap m_factories
Maps sprocket plugin uri's to ZblFactory objects.
Q_INVOKABLE QObject * bundleSettings(const QString &bundleID)
Returns a new ZSettings object representing a JSON file in the location specified by the settings bun...
A two-way messaging communication channel that supports buffered message streams to multiple end poin...
A javascript wrapper for QFile.
static QString getMainQmlPath()
Obtains the canonical path to the Zuble application's main QML file.
QString errorMessage()
Returns a formatted error message from this thread's ZblThreadErr object.
static QVariant m_tags
A QVariantMap used to pass ZApplication enumeration values to Javascript programs.
static QString variantToJson(QVariant &var)
Converts QVariant to json string.
static const QString m_homePathPrefix
URL scheme used to specify user's home directory location: "home://".
static QReadWriteLock m_lock
A lock for multi-threaded data access.
Q_INVOKABLE QObject * newMap()
Returns a new ZMap object for mapping arbitrary strings to javascript values.
QString readLine()
Reads a line of text from stdin.
timerHash m_scriptTimers
A hash of javascript function/argument pairs keyed by timer ID.
Q_INVOKABLE QStringList getSystemEnvironment()
obtain a string array containing the process system environment
Q_INVOKABLE QObject * newMailbox()
Returns a new ZMailbox object for passing messages between components.
Q_INVOKABLE QObject * newObject(const QString &sprocketUri, const QString &objectName)
Returns a new Zuble sprocket object from the specified sprocket extension plugin. ...
static ZblLogManager & zInstance()
Obtain a reference to Zuble's log manager object.
Q_INVOKABLE QObject * newLogReader()
Returns a new ZLogReader object for reading Zuble log files.
QVariant getAppTags()
Obtains a javascript dictionary object that maps application data item names to integer values...
#define ZBL_SLOT_BEGIN_TRY
void clearError()
Clears an existing error condition for this thread.
Q_INVOKABLE void sleep(unsigned long milliseconds)
Blocks the current thread for the specified number of milliseconds.
#define ZBL_DEFINE_LOGGED_OBJECT(class_name)
void stopTimerInterval(int timerID)
Stops the specified timer.
Q_INVOKABLE QObject * newFile()
Returns a new ZFile object for reading, writing and manipulating files.
#define zThreadErr
where does this show up?
This two dimensional table model is used to store and manipulate data.
Q_INVOKABLE QObject * newXmlQuery()
Returns a new ZxQuery object.
Q_INVOKABLE QObject * newAppSettings(int scope, const QString &application, const QString &organization)
Returns a new ZSettings object representing a JSON file in the platform-specific configuration file l...
#define ZBL_SLOT_END_VOID(facility, code, error_message)
The primary QML API to the Zuble plugin library. Zuble applications access this object through the ja...
Q_INVOKABLE QObject * getLogRules()
Obtain Zuble's log category rules data model.
ZScriptThread * m_container
The ZScriptThread object that represents the thread in which ZblApp is running.
Q_INVOKABLE QString bundleMetapath(const QString &bundleID)
Returns the path to the Zuble settings metadata file for the specified settings bundle ID...
void statusAvailable(const QString &text)
Sent when text for the main applicaiton status is available. Connect to this signal to display status...
Q_INVOKABLE void sleepEvents(unsigned long milliseconds)
Blocks the current thread for the specified number of milliseconds while processing events...
Wraps the QSettings class and implements a JSON-based backend for storing the settings data...
A two-way buffered message stream with attached user-defined data cache.
QJSValue error()
returns the internal Error object for this thread saved in thread local storage.
static QString getObjectThreadAddress(QObject *object)
Returns the human-readable memory address of the specified object's thread.
const char * what() const
static int registerSingletonType()
Registers this object with QML as a singleton type.
QJSValue convertEvaluateError(const QJSValue &evaluateError)
Javascript syntax errors appear to be passing back a string object with the QJSValue error bit set...
void catchDeeperException()
test method to throw and then catch a ZblException
void createTags()
Create the m_tag object that presents a Javascript interface to ZApplication enumeration values...
static QString resolvePath(const QString &path, bool includeUrlScheme=true)
Converts relative file paths into canonical file paths. Paths prefixed with prefix are mapped relativ...
static QString getBundleMetadata(const QString &id)
void onDestroyed(QObject *obj)
Experimental, may be deprecated.
Q_INVOKABLE QObject * newByteArray()
Returns a new ZByteArray object for reading and writing byte arrays.
This inner class allows ZblApp to store javascript function pointers that are used to provide timer s...
Q_INVOKABLE QString getCurrentThreadAddress()
Returns the human-readable memory address of the current thread.
virtual ZBL_DECLARE_LOGGED_OBJECT void timerEvent(QTimerEvent *event)
Overloaded timer function to implement startTimerInterval. This method calls the specified timer's ja...
Q_INVOKABLE QObject * newFileSystemWatcher()
Returns a new ZFileSystemWatcher object for detecting changes in files and directories.
Zuble's Qt Exception Object.
static QString getCurrentThreadAddress()
Returns the human-readable memory address of the current thread.
A hierarchical map object for creating scopes.
An object factory that creates new instances of objects defined by a Zuble sprocket. Used primarily to construct sprocket objects in Zuble background threads.
QString getMainQmlPath()
Obtains the canonical path to the Zuble application's main QML file.
static QString getRootPath()
Obtains the canonical path to the Zuble application's root directory.
static ZSettings * getBundleSettings(const QString &id)
Returns the ZSettings object for the specified settings bundle ID. Caller takes ownership of the ZSet...
This class provides access to the QXMLQuery class from Javascript.
Q_INVOKABLE QString getObjectThreadAddress(QObject *object)
Returns the human-readable memory address of the specified object's thread.
static QString getBundleMetapath(const QString &id)
void throwException()
test method to throw an exception
Q_INVOKABLE QString resolvePath(const QString &path, bool includeUrlScheme=true)
Converts Zuble paths into canonical file paths. Zuble home paths are prefixed with "home://" and are ...
void quit()
Calls quit() on the owning ZScriptThread object.
This class wraps the QXmlSchemaValidator and QXmlSchema classes.
Q_INVOKABLE bool import(const QString &sprocketUri, int versionMajor, int versionMinor)
Makes a Zuble sprocket extension plugin available to background javascript threads.
Q_INVOKABLE QObject * newDataStream(QObject *byteArray)
Returns a new ZDataStream object for reading and writing data in byte arrays.
return result toVariant()
void print(const QString &text, bool newLine=true)
Writes text to stdout.
#define ZBL_SLOT_END_RETURN(return_success, return_failed, facility, code, error_message)
void alert(const QString signalID, QVariant payload, bool wait=false)
Call this method to send an alert signal to the owning ZScriptThread object.
void exit(int returnCode)
Exits the thread. When called by the main thread exits the application.
void exitApp(int returnCode=0)
Calls exit() on ??? the owning ZScriptThread object.
QVariant include(const QString &fileUrl)
Loads the specified javascript file and executes it in the current javascript context.
Q_INVOKABLE QObject * getLogRules()
Obtain the logging rules data model.