Thursday 6 October 2016

Constantly ignore file changes in git without changing .gitignore

(original from "eckes" on stackoverflow: http://stackoverflow.com/questions/10879783/git-doesnt-ignore-2-specifically-named-files?answertab=active#tab-top)
You'll need to use git update-index:
git update-index --assume-unchanged build/conf/a.conf
git update-index --assume-unchanged build/conf/b.conf
will achieve what you want: the files are always assumed unchanged.
If you want to track changes in these files again, use --no-assume-unchanged.
Finally, if you want to know which files are currently in the --assume-unchanged mode, ask git for
git ls-files -v | grep -e "^[hsmrck]"

Friday 29 July 2016

Take a screenshot of whole app in the Electron

First you need to enable usermedia-screen-capturing in your Chromium Electron,
add the following string into your main.js:
app.commandLine.appendSwitch('enable-usermedia-screen-capturing');

After that you can use the following function to take a PNG blob
/**
 * A simplified function which takes a screenshot with webkitGetUserMedia
 * and returns this screenshot as a PNG blob into the callback
 * @param callback (pngData: Blob) => void
 * @returns void
 */
function takeScreenShot (callback) {
    let screenConstraints = {
        mandatory: {
            chromeMediaSource: "screen",
            maxHeight: 1080,
            maxWidth: 1920,
            minAspectRatio: 1.77
        },
        optional: []
    };

    let session = {
        audio: false,
        video: screenConstraints
    };

    let streaming = false;
    let canvas = document.createElement("canvas");
    let video = document.createElement("video");
    document.body.appendChild(canvas);
    document.body.appendChild(video);
    let width = screen.width;
    let height = 0;

    video.addEventListener("canplay", function(){
        if (!streaming) {
            height = video.videoHeight / (video.videoWidth / width);

            if (isNaN(height)) {
                height = width / (4 / 3);
            }

            video.setAttribute("width", width.toString());
            video.setAttribute("height", height.toString());
            canvas.setAttribute("width", width.toString());
            canvas.setAttribute("height", height.toString());
            streaming = true;

            let context = canvas.getContext("2d");
            if (width && height) {
                canvas.width = width;
                canvas.height = height;
                context.drawImage(video, 0, 0, width, height);

                canvas.toBlob(function (data) {
                    video.pause();
                    video.src = "";
                    document.body.removeChild(video);
                    document.body.removeChild(canvas);
                    callback(data); // here the png blob returned to the callback
                });
            }
        }
    }, false);

    navigator.webkitGetUserMedia(session, function (stream) {
        video.src = window.webkitURL.createObjectURL(stream);
        video.play();
    }, function () {
        console.error("Can't take a screenshot");
    });
}

Wednesday 6 July 2016

Electron and ReactJS performance hint

If process.env.NODE_ENV is not set to 'production' react will do some performance consuming debug stuff. Set process.env.NODE_ENV to 'production' and it will bump the app performance.

Monday 30 May 2016

Produce html diff with diff2html-cli

It is handy to do with one nice JavaScript tool, which works on any platform:
https://www.npmjs.com/package/diff2html-cli

> npm install diff2html-cli
> diff -u fileA.txt fileB.txt | diff2html -F diff.html -i stdin


It is important to have -u option for diff command you pipe into diff2html, because it produces unified diff and diff2html expects unified diff.

It is also possible to do these two commands separatedly, without piping:

Write diff of a and b into a-b.diff file:
> diff -u a.txt b.txt > a-b.diff

Produce HTML file from the diff file:
> diff2html -F a-b.html -i file -- a-b.diff

Tuesday 26 April 2016

Call Rust from NodeJS via cross-platform C ABI with RuNo bridge

The RuNo bridge is a command line tool which generates C++ code for NodeJS addon from Rust code or from JSON definition (with JSON definition it should work with any C ABI compatible library, of course when implemented functionality is enough).

I've implemeted this tool after my last research on calling Rust from Node JS.

The parser of RuNo bridge does not do magical deep analysis of code, it just detects the following signatures in your code:

#[no_mangle]

pub extern "C" fn ...


it does not require any C++ knowledge from developer if you use primitives mentioned above and your Rust ABI interface complies with simple requirements:

  • All your ABI functoins should be listed in one Rust file;
  • Your library should use crate libc;
  • Each ABI function should be preceeded with #[no_mangle];
  • Each ABI function should be prefixed with pub extern "C";
  • ABI Functions should only take params of c_int,c_float,c_double or *c_char (as a C string with EOF);
  • ABI Functions should return either one of c_int,c_float,c_double or *c_char (as a C string with EOF)
It is tested on Windows, Mac OS and Ubuntu, however it has some limitations developer should know:


The package itself does not need Rust or C++ with node-gyp, it just emits a C++ source file.

However in order to build the source code, rust and C++ compiler should be compatible with NodeJS version installed. It is particularly important on Windows, where Rust target should be MSVC not GNU. For example, if one using 32 bit NodeJS on Windows this one should use target i686-pc-windows-msvc, if 64 bit Node then Rust should be configured with x86_64-pc-windows-msvc compile target. The same about C++: Everything is mostrly smooth on platforms with GCC, and a bit painful with MS Visual C++, please refer to node-gyp installation instructions for details.

You can find simple usage examples on the github: https://github.com/andruhon/runo-bridge-example

I will appreciate any comments or contribution.

Friday 26 February 2016

Call Rust from NodeJS via cross-platform C ABI

Rust language is quite elegant and looks like a decent replacement to C. There are already many useful packages in Crates available. It is quite good for developing libraries.

Let’s try to develop a Rust addon for NodeJS. It is possible to use node-ffi to call Rust from NodeJS, however FFI is very slow to init [results]. Node/V8 itself is written in C++ and it is possible to build custom C++ extensions and link the Rust library via the C ABI almost at no performance cost !

You can go directly to more complex example on github, if you can’t wait:
One critical moment to note: Rust and VC++ compilers should be of the same architecture as target NodeJS. Say if one using 32 bit NodeJS on windows one should use target i686-pc-windows-msvc, if 64bt Node then Rust should be configured with x86_64-pc-windows-msvc compile target. For linux x86_64-linux-gnu or i686-linux-gnu appropriately.

C++
#include <node.h>

using namespace v8;

extern "C" {
   extern int32_t add_in_rust(int32_t input, int32_t input);
}

void add_in_rust_wrapper(const FunctionCallbackInfo<Value>& args) {
   Isolate* isolate = Isolate::GetCurrent();
   HandleScope scope(isolate);
   int32_t value1 = args[0]->NumberValue();
   int32_t value2 = args[1]->NumberValue();
   args.GetReturnValue().Set(Number::New(isolate, add_in_rust(value1, value2)));
}

void init(Handle<Object> exports) {
   NODE_SET_METHOD(exports, "function_in_rust", add_in_rust_wrapper);
}

NODE_MODULE(addon, init)

Rust
#[no_mangle]
pub extern "C" fn fibonacci(v1: i32, v2: i32) -> i32 {
    v1 + v2
}
I used 32 bit int here, to simplify the example, however it is possible to accept and return `c_int` with crate libc, like that:
extern crate libc;
use libc::c_int;
//use `c_int` as platform int primitive, and ordinary `int` in the C++ addon.


Have a look at my examples set, to find something more useful than just an int:

https://github.com/andruhon/rust-in-node-examples , which generally contains following things:
  • int to int function
  • string to string function
  • numeric array to numeric array function
  • void to struct as an object
  • struct as object to bool
  • callbacks and mutable state

Other options:

https://github.com/rustbridge/neon/ - it is possible to do quite a lot with Neon, however it is more difficult than FFI because in Rust you have to be aware of underlying V8 types and perform manipulations with them. Neon also has platform compatibility issues and a bit overengineered on my opinion.

https://github.com/andruhon/runo-bridge - the command line tool: you feed Rust souce file with `no_mangle extern "C"` functions, or interface definition as a JSON and it will generate some C++ boilerplate code for addon. It just a prototype, which accepts/returns only `void`, `int`, `bool` and `*char`(C string) at a moment. I’ll keep improving it.


A few more articles on integrating Rust with NodeJS coming soon...

Tuesday 26 January 2016

OpenJDK finally ported to iOS

Someone Johan has recently "run an application using Gluon Charm (Material Design UI controls) on top
of JavaFX (OpenJFX 9) on top of Java on my iPad mini, so this is a real-world complete stack."

MobileJDK is still under heavy development, however it is a good result! Port to is achieved with Zero interpreter due to the fact that Apple does not allow dynamic code generation on iOS.

Thursday 14 January 2016

Tox - open source replacement for proprietary IM protocols (such as skype)

Tox is an open source instant messaging protocol supporting text, sending files,
video chats and so on.
qTox, µTox, Antox, Toxic, Antidote and others
are open source clients for this protocol.

Available on Linux, Windows, Mac OS, Android, iOS
and anywhere you ready to port it
https://tox.chat/

Unlike Skype and ICQ Tox using decentralized DHT network for p2p communication.
User ID (hash) looks like
0ECA261D206B8D3899A8B0B751BF37206E3CCD73ACE2C4C3B79A9CB9505B301C642D14F43AD7


Tox FAQ:
https://wiki.tox.chat/users/faq
Here's a list of Tox bootstrap nodes for DHT network:
https://nodes.tox.chat/

There's also so called ToxDNS for shorter and human readable contact names.
It is possible to use 3rd party DNS or to establish own one:
https://wiki.tox.chat/users/toxdns
(it is considered to be less safe than hash, however if you control own DNS it should not be a problem)

Link to the Tox Core repo:
https://github.com/irungentoo/toxcore (crossplatform C)