Read text multiple times with Elementary access on native Tizen TV - c++

Hello fellow programmers,
I am trying to use the Text To Speech functionality provided by the Elementary access library (from Enlightenment) in a native app for tizen TV.
So far I have been able to read text, but only once: when I call the API multiple times, only the first call is rendered to audio.
I have investigated the sources of elementary access, but can't really spot the problem.
Here is a sample of my app:
#include <app.h>
#include <Elementary.h>
#include <unistd.h>
#include <string>
using namespace std;
const char APP_PKG[] = "org.tizen.tts";
/// Struct to store application information and passed at start time to the efl framework
struct _appdata
{
const char *name;
Evas_Object *win;
};
static bool
_create(void *data)
{
elm_config_access_set(EINA_TRUE);
return true;
}
static bool
_control(app_control_h app_control, void *data)
{
for (int i = 1; i <= 2; i++) {
string text = to_string(i) + ". Read me please.";
elm_access_say(text.c_str());
// sleep(10);
}
return true;
}
int
main(int argc, char *argv[])
{
_appdata ad = {0,};
ad.name = APP_PKG;
ui_app_lifecycle_callback_s lifecycle_callback = {0,};
lifecycle_callback.create = _create;
lifecycle_callback.app_control = _control;
return ui_app_main(argc, argv, &lifecycle_callback, &ad);
}
I have tried using elm_access_force_say, also moving elm_config_access_set(EINA_TRUE) inside the loop, but everytime the sentence is only said once.
Here in the source is some code called by elm_access_say. It seems that the api makes a call to espeak executable, strangely I can't find any espeak executable on the device.
Tizen provides an API for using the TTS engine in native apps, but only for mobile and watches (at least in the documentation).
If someone ever tried to use the TTS engine on native TV, or have more experience with the Elementary access library, and would like to share some knowledge, I would be really thankful.

If you are using Tizen 4.0 or above and you want to read text multiple times using accessibility framework, please use the elm_atspi_bridge_utils_say. Below code snippet demonstrates how to read consecutive numbers.
statc void reade_n_times(int n) {
char buf[32];
for (int i=1;i<=n;++i){
snprintf(bug,sizesizeof(buf), "%d", i);
elm_atspi_bridge_utils_say(buf, EINA_FALSE, say_cb, NULL);
}
}
Full specification of elm_atspi_bridge_utils_say can be found here:
https://developer.tizen.org/dev-guide/tizen-iot-headed/4.0/group__Elm__Atspi__Bridge.html#gafde6945c1451cb8752c67f2aa871d12d "

Use this page for 4.0 Wearable API Reference. API Reference of tizen-iot-headed is not up-to-date.
https://docs.tizen.org/application/native/api/mobile/4.0/group__Elm__Atspi__Bridge.html

Related

Running an external text editor in a console app - C++

I'm building a console app in C++, and need a way to call a terminal text editor for the user's editing pleasure, and knowing when they are done.
For example, in git when you run git rebase --interactive, it launches a text editor right there in the terminal (Nano by default) wherein which you can easily edit commits. When you close the editor, git resumes its operations in the console.
I believe what I need to do is launch an editor as a child process, continuously pass through cin and cout to it, and finally resume the program when the editor exits.
I've looked into popen, but that only sends one stream (stdout). I even read through git's rebase implementation, but couldn't figure out how they did it.
Any suggestions?
How you invoke the editor depends on the system. On a Unix system, you would spawn a process with standard input, standard output, and standard error passed through to the child process, since presumably all three of those are connected to the terminal. This is usually the default behavior if you don't redirect these streams.
Usually this is done by using fork and one of the exec* family of functions on Unix, but you could also use the posix_spawn family of functions. There are different ways to do it on Windows.
You should use the VISUAL environment variable if it is set and TERM is set to something other than dumb, and EDITOR otherwise, falling back to a system default (usually vi) if neither is set. The value of these environment variables must always be passed to /bin/sh (or a POSIX sh if that is not one) for evaluation; for example, it is always acceptable to set VISUAL or EDITOR to f() { vim "$0" "$#"; };f and all programs using those variables must support that. Git does the same thing, plus searching for an editor in some additional locations.
Below is a rough C (and valid C++) program that does nothing but spawn an editor with the arguments on the command line. It should demonstrate approximately how to spawn an editor correctly:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
bool is_dumb(void)
{
const char *term = getenv("TERM");
return !term || !strcmp(term, "dumb");
}
const char *editor(void)
{
const char *ed = NULL;
if (!is_dumb())
ed = getenv("VISUAL");
if (!ed)
ed = getenv("EDITOR");
if (!ed)
ed = "vi";
return ed;
}
int main(int argc, char **argv)
{
const char *ed = editor();
pid_t pid = fork();
if (pid < 0) {
perror("Failed to spawn editor");
exit(127);
}
if (!pid) {
const char *append = " \"$#\"";
size_t len = strlen(ed) + strlen(append) + 1;
char *final_editor = (char *)malloc(len);
snprintf(final_editor, len, "%s%s", ed, append);
const char **args = (const char **)malloc(sizeof(const char *) * (argc + 3));
if (!args)
exit(255);
args[0] = "sh";
args[1] = "-c";
args[2] = final_editor;
for (int i = 1; i < argc; i++)
args[i + 2] = argv[i];
args[argc + 2] = NULL;
execvp("sh", (char *const *)args);
exit(127);
} else {
int wstatus;
waitpid(pid, &wstatus, 0);
if (WIFEXITED(wstatus)) {
exit(wstatus);
} else {
exit(255);
}
}
}
It seems there is an extremely easy and convenient way to do just this:
system("vim file.txt");
The statement runs the command and takes over terminal input and output until the user exits the editor, at which point it unblocks and execution continues in the console.
Thanks to the commenters for inspiration.
If you don't want blocking behaviour, see bk2204's answer.

Nodejs: How to start a node application from a c++ program [duplicate]

I want to use Node.js scripts in my C/C++ applications. Some people suggested me to start with v8, libev and libeio; but it means rewriting Node.js from scratch.
So, is it possible to embed Node.js into C or C++?
You should first consider whether it would be sufficient to implement your application as a C++ module for Node and then glue the main part as a Node script.
Otherwise you may wish to "re-implement Node", by taking the core code as the example and
removing the parts which you don't need (e.g. HTTP module) and then putting your components
into it. The least painful way would be to do a sub-tree merge and ripping-out the build system, then adding prefixes in the build scripts to point to the directory where it lives.
Then you can stop certain parts from being built. However Node's build system contains several parts and it may be quite a difficult job to do.
You can also try re-packaging Node with your stuff loaded by default and changing the name of the executable. However, that is just a more complex way of taking the first approach I have described, you can just install a script in /usr/bin/ which will go as:
#!/usr/bin/node
var myAppMain = require('libmyApp');
myAppMain.withConfig(filename,
function(err, cnf) {
if (err) throw err; // parser or file access error
cnf.evalMe();
});
You can use a JSlint as your parser, then grep for dangerous calls and then eval(conf_script) or just use require(config.js), though you will need to add exports.someMethod = function (...) {...}. But require() is much safer in general, however you may wish to implement a pre-processor for your config which will substitute exports.someMethod = function (...) {...} instead of your functions and will append require('OnlyCallMySafeMethods') and reject any
attempts to require('fs') or other lib which you may be afraid of letting the someone to use.
This sort of safety is just an optional thing you may wish to have, it's all up to you really.
Though I suppose you might want to do the bit with exports.someMethod = .... substitution and have one require('myAppConfigLib) added on the top so the user will just use you API plus anything they may wish to put into their script/config!
UPDATE: There is a quite useful comment on line 66 of src/node.js:
// To allow people to extend Node in different ways, this hook allows
// one to drop a file lib/_third_party_main.js into the build
// directory which will be executed instead of Node's normal loading.
Please also note that the contents of src/ are being compiled to bytecode at build time.
Embedding Node.JS is now officially supported by a Node.JS fork JXcore. Embedding docs are available from this link.
I've build something close to what I think you're looking for:
https://github.com/ZECTBynmo/tacnode
It's a library that allows node.js to be linked statically into a C++ application. It's definitely not polished, but I've used it to launch simple node scripts.
The official documentation has a page explaining how how to embed Node.js into C++. This has been around since Node 12.x.
There is a full example in the Node repo. Reproduced below for convenience:
#ifdef NDEBUG
#undef NDEBUG
#endif
#include "node.h"
#include "uv.h"
#include <assert.h>
// Note: This file is being referred to from doc/api/embedding.md, and excerpts
// from it are included in the documentation. Try to keep these in sync.
// Snapshot support is not part of the embedder API docs yet due to its
// experimental nature, although it is of course documented in node.h.
using node::CommonEnvironmentSetup;
using node::Environment;
using node::MultiIsolatePlatform;
using v8::Context;
using v8::HandleScope;
using v8::Isolate;
using v8::Locker;
using v8::MaybeLocal;
using v8::V8;
using v8::Value;
static int RunNodeInstance(MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args);
int main(int argc, char** argv) {
argv = uv_setup_args(argc, argv);
std::vector<std::string> args(argv, argv + argc);
std::unique_ptr<node::InitializationResult> result =
node::InitializeOncePerProcess(
args,
{node::ProcessInitializationFlags::kNoInitializeV8,
node::ProcessInitializationFlags::kNoInitializeNodeV8Platform});
for (const std::string& error : result->errors())
fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
if (result->early_return() != 0) {
return result->exit_code();
}
std::unique_ptr<MultiIsolatePlatform> platform =
MultiIsolatePlatform::Create(4);
V8::InitializePlatform(platform.get());
V8::Initialize();
int ret =
RunNodeInstance(platform.get(), result->args(), result->exec_args());
V8::Dispose();
V8::DisposePlatform();
node::TearDownOncePerProcess();
return ret;
}
int RunNodeInstance(MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args) {
int exit_code = 0;
node::EmbedderSnapshotData::Pointer snapshot;
auto snapshot_build_mode_it =
std::find(args.begin(), args.end(), "--embedder-snapshot-create");
auto snapshot_arg_it =
std::find(args.begin(), args.end(), "--embedder-snapshot-blob");
auto snapshot_as_file_it =
std::find(args.begin(), args.end(), "--embedder-snapshot-as-file");
if (snapshot_arg_it < args.end() - 1 &&
snapshot_build_mode_it == args.end()) {
const char* filename = (snapshot_arg_it + 1)->c_str();
FILE* fp = fopen(filename, "r");
assert(fp != nullptr);
if (snapshot_as_file_it != args.end()) {
snapshot = node::EmbedderSnapshotData::FromFile(fp);
} else {
uv_fs_t req;
int statret = uv_fs_stat(nullptr, &req, filename, nullptr);
assert(statret == 0);
size_t filesize = req.statbuf.st_size;
uv_fs_req_cleanup(&req);
std::vector<char> vec(filesize);
size_t read = fread(vec.data(), filesize, 1, fp);
assert(read == 1);
snapshot = node::EmbedderSnapshotData::FromBlob(vec);
}
assert(snapshot);
int ret = fclose(fp);
assert(ret == 0);
}
std::vector<std::string> errors;
std::unique_ptr<CommonEnvironmentSetup> setup =
snapshot ? CommonEnvironmentSetup::CreateFromSnapshot(
platform, &errors, snapshot.get(), args, exec_args)
: snapshot_build_mode_it != args.end()
? CommonEnvironmentSetup::CreateForSnapshotting(
platform, &errors, args, exec_args)
: CommonEnvironmentSetup::Create(platform, &errors, args, exec_args);
if (!setup) {
for (const std::string& err : errors)
fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
return 1;
}
Isolate* isolate = setup->isolate();
Environment* env = setup->env();
{
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Context::Scope context_scope(setup->context());
MaybeLocal<Value> loadenv_ret;
if (snapshot) {
loadenv_ret = node::LoadEnvironment(env, node::StartExecutionCallback{});
} else {
loadenv_ret = node::LoadEnvironment(
env,
// Snapshots do not support userland require()s (yet)
"if (!require('v8').startupSnapshot.isBuildingSnapshot()) {"
" const publicRequire ="
" require('module').createRequire(process.cwd() + '/');"
" globalThis.require = publicRequire;"
"} else globalThis.require = require;"
"globalThis.embedVars = { nön_ascıı: '🏳️‍🌈' };"
"require('vm').runInThisContext(process.argv[1]);");
}
if (loadenv_ret.IsEmpty()) // There has been a JS exception.
return 1;
exit_code = node::SpinEventLoop(env).FromMaybe(1);
}
if (snapshot_arg_it < args.end() - 1 &&
snapshot_build_mode_it != args.end()) {
snapshot = setup->CreateSnapshot();
assert(snapshot);
FILE* fp = fopen((snapshot_arg_it + 1)->c_str(), "w");
assert(fp != nullptr);
if (snapshot_as_file_it != args.end()) {
snapshot->ToFile(fp);
} else {
const std::vector<char> vec = snapshot->ToBlob();
size_t written = fwrite(vec.data(), vec.size(), 1, fp);
assert(written == 1);
}
int ret = fclose(fp);
assert(ret == 0);
}
node::Stop(env);
return exit_code;
}
It probably is, V8 is written in C++, node.js can run on V8, but unless you have an extremely good reason why you would run javascript through C++ you are probably much better served finding an appropriate C++ library and implementing the needed functionality directly in C++. The task of integrating scripting languages and native code is usually not trivial. E.g. V8 documentation. Qt offers a pretty decent integration between c++ and javascript and it still not trivial to move objects back and forth between script and code.
I was just checking out js-git which is made for Node.js and also depends on a few other Node.js modules.
However, the same developer wrote a tool tim-task to wrap up some common Node.js functions, most importantly require, and to pack together some Node.js modules in such a way that it should not depend on Node.js anymore. He used it to make git-web-platform, i.e. js-git packed as a JS file which can be used in browsers. The resulted packed file looks like this. This can probably also be used with minor modifications just in pure V8.
This might be useful for you. Note however that this approach will be limited.
There are many good reasons to embed node, including the ability to leverage npm.
Unfortunately JXCore is dying.
this artice gives some alternatives.
http://www.goland.org/nodeapps/

audio synthesis with MoMu STK

Has anybody successfully implemented an Instrument using MoMu STK on iOS? I am bit stacked with initialization of a stream for Instrument.
I am using tutorial code and looks like something missing
RtAudio dac;
// Figure out how many bytes in an StkFloat and setup the RtAudio stream.
RtAudio::StreamParameters parameters;
parameters.deviceId = dac.getDefaultOutputDevice();
parameters.nChannels = 1;
RtAudioFormat format = ( sizeof(StkFloat) == 8 ) ? RTAUDIO_FLOAT64 : RTAUDIO_FLOAT32;
unsigned int bufferFrames = RT_BUFFER_SIZE;
dac.openStream( & parameters, NULL, format, (unsigned int)Stk::sampleRate(), &bufferFrames, &tick, (void *)&data );
Error description says that output parameters for output device are invalid, but when I skip to assign device id then it's not working as well.
Any idea would be great.
RtAudio is only for desktop apps and there is no need to open stream when implementing on iOS.
example:
Header file:
#import "Simple.h"
// make struct to hold
struct TickData {
Simple *synth;
};
// Make instance of the struct in #interface=
TickData data;
Implementation file:
// init the synth:
data.synth = new Simple();
data.synth->keyOff();
// to trigger note on/off:
data.synth->noteOn(frequency, velocity);
data.synth->noteOff(velocity);
// audio callback method:
for (int i=0; i < FRAMESIZE; i++) {
buffer[i] = data.synth -> tick();
}
Yep, I have a couple of apps in the store with STK classes running on them. Bear in mind that the setup required to run STK on iOS is different from the one required to run it on your desktop.
Here's a tutorial on how to use STK classes inside an iOS app:
https://arielelkin.github.io/articles/mandolin

How to embed Node.js interpreter into C/C++?

I want to use Node.js scripts in my C/C++ applications. Some people suggested me to start with v8, libev and libeio; but it means rewriting Node.js from scratch.
So, is it possible to embed Node.js into C or C++?
You should first consider whether it would be sufficient to implement your application as a C++ module for Node and then glue the main part as a Node script.
Otherwise you may wish to "re-implement Node", by taking the core code as the example and
removing the parts which you don't need (e.g. HTTP module) and then putting your components
into it. The least painful way would be to do a sub-tree merge and ripping-out the build system, then adding prefixes in the build scripts to point to the directory where it lives.
Then you can stop certain parts from being built. However Node's build system contains several parts and it may be quite a difficult job to do.
You can also try re-packaging Node with your stuff loaded by default and changing the name of the executable. However, that is just a more complex way of taking the first approach I have described, you can just install a script in /usr/bin/ which will go as:
#!/usr/bin/node
var myAppMain = require('libmyApp');
myAppMain.withConfig(filename,
function(err, cnf) {
if (err) throw err; // parser or file access error
cnf.evalMe();
});
You can use a JSlint as your parser, then grep for dangerous calls and then eval(conf_script) or just use require(config.js), though you will need to add exports.someMethod = function (...) {...}. But require() is much safer in general, however you may wish to implement a pre-processor for your config which will substitute exports.someMethod = function (...) {...} instead of your functions and will append require('OnlyCallMySafeMethods') and reject any
attempts to require('fs') or other lib which you may be afraid of letting the someone to use.
This sort of safety is just an optional thing you may wish to have, it's all up to you really.
Though I suppose you might want to do the bit with exports.someMethod = .... substitution and have one require('myAppConfigLib) added on the top so the user will just use you API plus anything they may wish to put into their script/config!
UPDATE: There is a quite useful comment on line 66 of src/node.js:
// To allow people to extend Node in different ways, this hook allows
// one to drop a file lib/_third_party_main.js into the build
// directory which will be executed instead of Node's normal loading.
Please also note that the contents of src/ are being compiled to bytecode at build time.
Embedding Node.JS is now officially supported by a Node.JS fork JXcore. Embedding docs are available from this link.
I've build something close to what I think you're looking for:
https://github.com/ZECTBynmo/tacnode
It's a library that allows node.js to be linked statically into a C++ application. It's definitely not polished, but I've used it to launch simple node scripts.
The official documentation has a page explaining how how to embed Node.js into C++. This has been around since Node 12.x.
There is a full example in the Node repo. Reproduced below for convenience:
#ifdef NDEBUG
#undef NDEBUG
#endif
#include "node.h"
#include "uv.h"
#include <assert.h>
// Note: This file is being referred to from doc/api/embedding.md, and excerpts
// from it are included in the documentation. Try to keep these in sync.
// Snapshot support is not part of the embedder API docs yet due to its
// experimental nature, although it is of course documented in node.h.
using node::CommonEnvironmentSetup;
using node::Environment;
using node::MultiIsolatePlatform;
using v8::Context;
using v8::HandleScope;
using v8::Isolate;
using v8::Locker;
using v8::MaybeLocal;
using v8::V8;
using v8::Value;
static int RunNodeInstance(MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args);
int main(int argc, char** argv) {
argv = uv_setup_args(argc, argv);
std::vector<std::string> args(argv, argv + argc);
std::unique_ptr<node::InitializationResult> result =
node::InitializeOncePerProcess(
args,
{node::ProcessInitializationFlags::kNoInitializeV8,
node::ProcessInitializationFlags::kNoInitializeNodeV8Platform});
for (const std::string& error : result->errors())
fprintf(stderr, "%s: %s\n", args[0].c_str(), error.c_str());
if (result->early_return() != 0) {
return result->exit_code();
}
std::unique_ptr<MultiIsolatePlatform> platform =
MultiIsolatePlatform::Create(4);
V8::InitializePlatform(platform.get());
V8::Initialize();
int ret =
RunNodeInstance(platform.get(), result->args(), result->exec_args());
V8::Dispose();
V8::DisposePlatform();
node::TearDownOncePerProcess();
return ret;
}
int RunNodeInstance(MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args) {
int exit_code = 0;
node::EmbedderSnapshotData::Pointer snapshot;
auto snapshot_build_mode_it =
std::find(args.begin(), args.end(), "--embedder-snapshot-create");
auto snapshot_arg_it =
std::find(args.begin(), args.end(), "--embedder-snapshot-blob");
auto snapshot_as_file_it =
std::find(args.begin(), args.end(), "--embedder-snapshot-as-file");
if (snapshot_arg_it < args.end() - 1 &&
snapshot_build_mode_it == args.end()) {
const char* filename = (snapshot_arg_it + 1)->c_str();
FILE* fp = fopen(filename, "r");
assert(fp != nullptr);
if (snapshot_as_file_it != args.end()) {
snapshot = node::EmbedderSnapshotData::FromFile(fp);
} else {
uv_fs_t req;
int statret = uv_fs_stat(nullptr, &req, filename, nullptr);
assert(statret == 0);
size_t filesize = req.statbuf.st_size;
uv_fs_req_cleanup(&req);
std::vector<char> vec(filesize);
size_t read = fread(vec.data(), filesize, 1, fp);
assert(read == 1);
snapshot = node::EmbedderSnapshotData::FromBlob(vec);
}
assert(snapshot);
int ret = fclose(fp);
assert(ret == 0);
}
std::vector<std::string> errors;
std::unique_ptr<CommonEnvironmentSetup> setup =
snapshot ? CommonEnvironmentSetup::CreateFromSnapshot(
platform, &errors, snapshot.get(), args, exec_args)
: snapshot_build_mode_it != args.end()
? CommonEnvironmentSetup::CreateForSnapshotting(
platform, &errors, args, exec_args)
: CommonEnvironmentSetup::Create(platform, &errors, args, exec_args);
if (!setup) {
for (const std::string& err : errors)
fprintf(stderr, "%s: %s\n", args[0].c_str(), err.c_str());
return 1;
}
Isolate* isolate = setup->isolate();
Environment* env = setup->env();
{
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
Context::Scope context_scope(setup->context());
MaybeLocal<Value> loadenv_ret;
if (snapshot) {
loadenv_ret = node::LoadEnvironment(env, node::StartExecutionCallback{});
} else {
loadenv_ret = node::LoadEnvironment(
env,
// Snapshots do not support userland require()s (yet)
"if (!require('v8').startupSnapshot.isBuildingSnapshot()) {"
" const publicRequire ="
" require('module').createRequire(process.cwd() + '/');"
" globalThis.require = publicRequire;"
"} else globalThis.require = require;"
"globalThis.embedVars = { nön_ascıı: '🏳️‍🌈' };"
"require('vm').runInThisContext(process.argv[1]);");
}
if (loadenv_ret.IsEmpty()) // There has been a JS exception.
return 1;
exit_code = node::SpinEventLoop(env).FromMaybe(1);
}
if (snapshot_arg_it < args.end() - 1 &&
snapshot_build_mode_it != args.end()) {
snapshot = setup->CreateSnapshot();
assert(snapshot);
FILE* fp = fopen((snapshot_arg_it + 1)->c_str(), "w");
assert(fp != nullptr);
if (snapshot_as_file_it != args.end()) {
snapshot->ToFile(fp);
} else {
const std::vector<char> vec = snapshot->ToBlob();
size_t written = fwrite(vec.data(), vec.size(), 1, fp);
assert(written == 1);
}
int ret = fclose(fp);
assert(ret == 0);
}
node::Stop(env);
return exit_code;
}
It probably is, V8 is written in C++, node.js can run on V8, but unless you have an extremely good reason why you would run javascript through C++ you are probably much better served finding an appropriate C++ library and implementing the needed functionality directly in C++. The task of integrating scripting languages and native code is usually not trivial. E.g. V8 documentation. Qt offers a pretty decent integration between c++ and javascript and it still not trivial to move objects back and forth between script and code.
I was just checking out js-git which is made for Node.js and also depends on a few other Node.js modules.
However, the same developer wrote a tool tim-task to wrap up some common Node.js functions, most importantly require, and to pack together some Node.js modules in such a way that it should not depend on Node.js anymore. He used it to make git-web-platform, i.e. js-git packed as a JS file which can be used in browsers. The resulted packed file looks like this. This can probably also be used with minor modifications just in pure V8.
This might be useful for you. Note however that this approach will be limited.
There are many good reasons to embed node, including the ability to leverage npm.
Unfortunately JXCore is dying.
this artice gives some alternatives.
http://www.goland.org/nodeapps/

register for WindowServer CGScreenRefreshCallback CGScreenUpdateMoveCallback in C++

I'm trying to register for CGScreenRefreshCallback and CGScreenUpdateMoveCallback ( here's what apple's saying about http://developer.apple.com/mac/library/documentation/GraphicsImaging/Reference/Quartz_Services_Ref/Reference/reference.html#//apple_ref/doc/uid/TP30001070-CH1g-F16970 )
using C++ only.
I wrote this simple tester for the refresh callback in order to retrieve the changing rectangles:
#include "ApplicationServices/ApplicationServices.h"
#include <iostream>
using namespace std;
/////////////HEADER
static void DHRefreshCallback (CGRectCount count,const CGRect * rectArray,void * userParameter);
///////////////////
int main (int argc, char * const argv[]) {
CGRegisterScreenRefreshCallback(DHRefreshCallback, NULL);
while (true) {
// just hanging
}
return 0;
}
static void DHRefreshCallback (CGRectCount count,const CGRect * rectArray,void * userParameter){
cout << "something changed" << endl;
return;
}
...but didn't work.
I know I need a connection with WindowServer (Quartz Compositor \ Quartz Extreme \ Quartz Extreme 2D...still can't figure out the difference) and a running thread in order to get these callbacks, but I really don't know how to do this in C++ only (no Objective-C at all).
any direction?
thx in advance,
pigiuz
It's not about using/not using Objective-C. It's about the event loop in OS X apps in general, which is done by CFRunloop, which is a C API. See Run Loop management and CFRunLoop reference. You also need a connection to the window server, which can be established by calling
Instead of
while (true) {
// just hanging
}
just do
extern "C" void NSApplicationLoad(void);
NSApplicationLoad(); // establish a connection to the window server. In <Cocoa/Cocoa.h>
CFRunLoopRun(); // run the event loop
Don't forget to link against Cocoa.framework; just add -framework Cocoa in the command line of the compiler.
You can #import <Cocoa/Cocoa.h> but then you need to use Objective-C++ because of the Objective-C classes declared in it.
You could use
RunApplicationEventLoop(); //establish a connection to the window server
//and runs the event loop. In <Carbon/Carbon.h>
in an 32 bit app, instead of NSApplicationLoad + CFRunLoopRun, but it's not available in an 64 bit app.