V8 modules exporting functions that call into c++ - v8

I am looking to embed v8 and have a module available that exports a function that calls into c++ code. For example, let's assume I have something like the following in main.js:
import {foo} from 'FooBar';
foo();
Is there a way to have foo call into native c++ code? Looking for a push in the right direction, thanks in advance!

If you're a very up-to-date version of V8, there a new subclass of Module called SyntheticModule which will let you create a virtual module where you can just directly set the exports.
https://cs.chromium.org/chromium/src/v8/include/v8.h?l=1406&rcl=d7cac7cb6a468995c1ec48611af283be8fb6c1ab
Local<Function> foo_func = ...;
Local<Module> module = Module::CreateSyntheticModule(
isolate, name,
{String::NewFromUtf8(isolate, "foo")},
[](Local<Context> context, Local<Module> module) {
module->SetSyntheticModuleExport(String::NewFromUtf8(isolate, "foo"), foo_func);
});
// link `module` just like a normal source-text module.

You can find various examples of this here: https://v8.dev/docs/embed
shell.cc is my goto example: https://github.com/v8/v8/blob/3a0f407d266ec6429a166cf2ec5132f6558d3a51/samples/shell.cc#L110-L114

Related

Typescript Type definition for d3 sankey

I have some javascript code which uses d3 sankey plugin for creating a chart. In my new project, I need to reuse the same code, but the new project is in typescript. I am looking for a DefinitelyTyped file for the plugin. I browsed through https://github.com/DefinitelyTyped/DefinitelyTyped, but couldn't find it.
Is there any other location where I can get this file from?
Sankey plugin link: https://github.com/d3/d3-sankey
Also, without a d.ts file for this plugin, is there a way to access it through typescript?
The code in d3 plugin looks something like this:
d3.sankey = function () {
// Rest of the code goes here
}
The way I use it in javascript is as below:
d3.sankey().nodeWidth(30).size([100,100]);
Would appreciate any help or guidance.
Thanks!
As a heads-up, I have just submitted a Pull Request #16051 to DefinitelyTyped which contains TS definitions for d3-sankey.
Once they are merged, they will be published as per standard process to npm/#types. I.e. npm install --save-dev #types/d3-sankey will do.
IMPORTANT: When I wrote them up, I noticed that the current API documentation in the d3-sankey repo appears to be in some need of rectification (e.g. missing methods, mentioning of accessor functions, which are not used in the code base)
When I have a second, I will file an issue there/submit a PR.
UPDATE (2017-05-01):
The "official" TypeScript definitions for d3-sankey are now available (see npm #types/d3-sankey). Simply use them with npm as indicated above.
The PR to update the actual API documentation of d3-sankey to reflect the source code is still awaiting a merge here.
You need to expand the definition of the d3 type to include the sankey() method and the methods it accepts.
At the absolute minimum, you need to extend the d3 module with a declaration file to make clear that d3 has been extended with the d3-sankey module. You do so by creating a definition file that you place within the #types directly with the following contents:
declare module 'd3' {
export function sankey(...args[]) : any;
}
This tells TS that there is a d3 module, and that it exports the function listed. If the d3 module already exists, it extends that module.
So you can then import the d3 service and use it:
import dd3 = require('d3');
dd3.sankey();
If you want to expand on the type file, you instead write the definition file as so:
declare module 'd3' {
interface ISankey {
nodeWidth() : number;
nodeWidth(width : number|{(arg: number) : number}) : void;
// Add Other d3.sankey Methods Here
}
export function sankey() : ISankey;
}

New Scala.js facade for Three.js -> "Cannot find module "THREE""

As https://github.com/antonkulaga/threejs-facade is heavily outdated I tried an approach like: https://github.com/Katrix-/threejs-facade and would like to create a facade for the new three.js library.
I am by no means a JS expert, nor am I a Scala.js expert, so odds are I am doing something really dumb.
After another question I am using this sbt-scalajs-bundler and sbt-web-scalajs-bundler
My build.sbt looks like this:
lazy val client = (project in file("modules/client"))
.enablePlugins(ScalaJSBundlerPlugin, ScalaJSWeb) // ScalaJSBundlerPlugin automatically enables ScalaJSPlugin
.settings(generalSettings: _*)
.settings(
name := "client"
//, scalaJSModuleKind := ModuleKind.CommonJSModule // ScalaJSBundlerPlugin implicitly sets moduleKind to CommonJSModule enables ScalaJSPlugin
,jsDependencies += ProvidedJS / "three.min.js"
)
lazy val server = (project in file("modules/server"))
.enablePlugins(PlayScala, WebScalaJSBundlerPlugin)
.settings(generalSettings: _*)
.settings(
name := "server"
,scalaJSProjects := Seq(client)
,pipelineStages in Assets := Seq(scalaJSPipeline)
//,pipelineStages := Seq(digest, gzip)
,compile in Compile := ((compile in Compile) dependsOn scalaJSPipeline).value
)
three.min.js is in the resources-folder of my client project.
One part of the Facade is e.g.
#js.native
#JSImport("THREE", "Scene")
class Scene extends Object3D {
and I want to use it like this: val scene = new Scene. On scala.js side this actually compiles just fine, but when I run it I get:
Error: Cannot find module "THREE"
in the browser and I wonder why. It's called like this in three.min.js after all.
Now I tried providing and serving the three.min.js file from the server side as well, because I thought that maybe it was just missing at runtime, but no, that does not seem to be the cause.
So now I wonder what am I doing wrong here?
Just to clarify: Rest of transpiled js works just fine, if I do not export any usage of the Facade!
As explained in this part of Scala.js documentation, #JSImport is interpreted by the compiler as a JavaScript module import.
When you use the CommonJSModule module kind (which is the case when you enable the ScalaJSBundlerPlugin), this import is translated into the following CommonJS import:
var Scene = require("THREE").Scene;
This annotation only tells how your Scala code will be interfaced with the JS world, but it tells nothing about how to resolve the dependency that provides the THREE module.
With scalajs-bundler you can define how to resolve JS dependencies from the NPM registry by adding the following setting to your client project:
npmDependencies += "three" -> "0.84.0"
(And note that you can’t use jsDependencies to resolve these modules with #JSImport)
Also, note that the correct CommonJS import to use three.js is "three" instead of "THREE", so your #JSImport annotation should look like the following:
#JSImport("three", "Scene")
Alternatively, if you don’t want to resolve your dependencies from the NPM registry, you can supply your CommonJS module as a resource file. Just put it under the src/main/resources/Scene.js and refer to it in the #JSImport as follows:
#JSImport("./Scene", "Scene")
You can see a working example here.

Elm find unused functions

Let us for example have app like this:
port module MyApp exposing (main)
import Html.App as App
main =
App.programWithFlags
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
Could we safely assume that only useful functions are the ones that are ports and anything that is called from init, view, update or subscriptions?
Because after some refactoring I stopped calling some function. Is any compiler flag or linter that could notify me that function could be safely removed?
You can only detect unused module imports while running elm-make with --warn flag.
That's all you could get from the compiler today.
Just remove stuff and compiler will tell you, if you have to put it back, I guess.

Cache won't work in Appcelerator

Titanium SDK version: 1.6.
iPhone SDK version: 4.2
I am trying out the cache snippet found on the Appcelerator forum but I get an error: [ERROR] Script Error = Can't find variable: utils at cache.js (line 9).
I put this one (http://pastie.org/1541768) in a file called cache.js and implemented the code from this one (http://pastie.org/pastes/1541787) in the calling script, but I get the error.
What is wrong? I copied the code exactly.
Your problems is whilst the first pastie defines utils.httpcache. The variable utils is not defined outside of this function closure (because it is not defined anywhere in global namespace). As below shows.
(function() {
utils.httpcache = {
};
})();
To make it all work in this instance add the following code to the top of your cache.js file.
var utils = {};
This declares the utils variable in global namespace. Then when the function closure is executed below it will add utils.httpcache to the utils object.
The problem is actually not specific to Appcelerator and is just a simple JavaScript bug. Checkout Douglas Crockfords book, JavaScript the Good Parts. Reading it will literally make you a more awesome JavaScript developer.
You can't use utils.httpcache.getFromCache(url) until you add this to your code:
var utils = {};
That's because how the author created his function, it's called JavaScript module pattern and it's generally used to structure the code.
I seem to lose this value "value.httpCacheExpire = expireTime;" when the code does the "Titanium.App.Properties.setString(key,JSON.stringify(value));" so when I get it back using the getString method, there's no longer the "value.httpCacheExpire.
Anyone else have this issue? Am I missing something to get this working?

Including DirectShow library into Qt for video thumbnail

I'm trying to implement http://msdn.microsoft.com/en-us/library/dd377634%28v=VS.85%29.aspx on Qt, to generate a poster frame/thumbnail for video files.
I have installed both Windows Vista and Windows 7 SDK. I put:
#include "qedit.h"
in my code (noting there is also one in C:\Qt\2010.04\mingw\include), I add:
win32:INCLUDEPATH += $$quote(C:/WindowsSDK/v6.0/Include)
to my *.pro file. I compile and get " error: sal.h: No such file or directory". Finding this in VC++ I add
win32:INCLUDEPATH += $$quote(C:/Program Files/Microsoft Visual Studio 10.0/VC/include)
And now have 1400 compile errors. So, I abandon that and just add:
win32:LIBS += C:/WindowsSDK/v7.1/Lib/strmiids.lib
to my *.pro file and try to run (without including any headers):
IMediaDet mediadet;
But then I get "error: IMediaDet: No such file or directory".
#include "qedit.h"
gives me the same error (it looks like it's pointing to the Qt version) and
#include "C:/WindowsSDK/v6.0/Include/qedit.h"
goes back to generating 1000's of compile errors.
Sigh, so much trouble for what should be 10 lines of code...
Thanks for your comments and help
Since you say you are "a C++/Qt newbie" then I suspect that the real issue may be that you are attempting to load the library yourself rather than simply linking your application to it?
To link an external library into your application with Qt all you need to do is modify the appropriate .pro file. For example if the library is called libfoo.dll you just add
LIBS += -L/path/to/lib -lfoo
You can find more information about this in the relevant section of the qmake manual. Note that qmake commonly employs Unix-like notation and transparently does the right thing on Windows.
Having done this you can include the library's headers and use whatever classes and functions it provides. Note that you can also modify the project file to append an include path to help pick up the headers eg.
INCLUDEPATH += /path/to/headers
Again, more information in the relevant section of the qmake manual.
Note that both these project variables work with relative paths and will happily work with .. to mean "go up a directory" on all platforms.
Note that qedit.h requires dxtrans.h, which is part of DirectX9 SDK.
You can find dxtrans.h in DirectX SDK from August 2006. Note that dxtrans.h is removed from newer DirectX SDKs.
Do you have access to the source of the external library? The following assumes that you do.
What I do when I need to extract a class from a library with only functions resolved, is to use a factory function in the library.
// Library.h
class SomeClass {
public:
SomeClass(std::string name);
// ... class declaration goes here
};
In the cpp file, I use a proxy function outside the extern "C" when my constructor requires C++ parameters (e.g. types such as std::string), which I pass as a pointer to prevent the compiler from messing up the signature between C and C++. You can avoid the extra step if your constructor doesn't require parameters, and call new SomeClass() directly from the exported function.
// Library.cpp
#include "Library.h"
SomeClass::SomeClass(std::string name)
{
// implementation details
}
// Proxy function to handle C++ types
SomeClass *ImplCreateClass(std::string* name) { return new SomeClass(*name); }
extern "C"
{
// Notice the pass-by-pointer for C++ types
SomeClass *CreateClass(std::string* name) { return ImplCreateClass(name); }
}
Then, in the application that uses the library :
// Application.cpp
#include "Library.h"
typedef SomeClass* (*FactoryFunction)(std::string*);
// ...
QLibrary library(QString("MyLibrary"));
FactoryFunction factory = reinterpret_cast(library.resolve("CreateClass"));
std::string name("foobar");
SomeClass *myInstance = factory(&name);
You now hold an instance of the class declared in the library.

Resources