Posts Tagged: haxe


20
Jan 13

NativeMirror : Easier way to make JNI/CPP calls from haxe

It’s still useful to know how to make native calls from haxe manually ( for debugging by example ) but there is a quicker and easier way.
It’s stricly type, flexible and simple.
It use a simple macro you can find here : here.

All you have to do is to add it on build of yours haxe class.

1
2
3
package org.shoebox.test;
@:build(org.shoebox.utils.JNIMirror.build( )) class Test{
}

Then all you need to do is to create mirrors for the native methods.
 

Mirrors for JNI Methods

Basic example:

In the following case the JNI class name and method name are not defined.
So the macro use the same classpath classname and function name than on the haxe side.

1
2
@JNI
static public function test( s : String , i : Int ) : String {}
If the haxe method name or package is not the same on the java side:

You can customize both by adding argments to the JNI meta:

1
2
@JNI("org.shoebox.Test","TestFunc")
static public function test( s : String , i : Int ) : String {}
For non native types:

It works too for non-native type if the class exists on both side ( with the same package and class name ).
By example we are trying to get the instance of the java class Test inside haxe, the method is defined this way:

1
2
3
@JNI
static public function getInstance( ):Test{
}

 

For CPP Methods

It works the same way, but the first meta argument ( library_name ) must be always defined ( for now ).
The second meta argument ( method_name ) is optional.

1
2
@CPP("library_name","method_name")
public function test_cpp( instance : Dynamic , sTest : String , i : Int , b : Bool ) : Void {}

Hope it helps.


18
Jan 13

NME Native Extension Part 2 : Calling CPP methods from haxe

Much more easier than JNI methods, all you have to do is using the “cpp.Lib” class ( “neko.Lib” for neko ).

1
Lib.load( libName , primitiveName , argsCount );

LibName:
It’s the cpp library name ( without path and extension ).

PrimitiveName:
The name of the primitive defined in the ExternalInterface class.
In the next article of the tutorial we will take a look at how to define the primitive in the ExternalInterface class, which is the backbone of the native extension.

ArgsCount:
Obviously it’s the argument count used by the primitive.

This will return like for JNI, a function which can be call with the correct number of arguments.


6
Jan 13

NME Native Extension Part 1 – Android : Calling Java methods from Haxe

The JNI class (nme.JNI) allow native haxe code to call Java methods.

For static method the function call is :

1
nme.JNI.createStaticMethod( package_name , "method_name" , signature )

for non-static method it’s :

1
nme.JNI.createMemberMethod( package_name , "method_name" , signature )

Package name:

The package is the full class package and class name separated by slash ( example: “org.shoebox.Test” is “org/shoebox/Test” )

The signature :

The signature of the method is a string:
( mapped arguments type ) return_type

First thing to know is than the arguments type must be mapped for Java.

For the basics types just follow the following table:

For the non basic types ( by example a class instance ) the mapping is:

Lpackage/of/the/ClassName;

Some examples:

On the java side :

1
2
3
4
5
static public DemoJNI getInstance( ){}

static public boolean test_ret_bool( ){}

public boolean test_method_nonstatic( i : Int , b : boolean ){}

 

On the haxe side for the statics methods :

1
2
3
4
var f1 = nme.JNI.createStaticMethod( "org/shoebox/DemoJNI" , "getInstance" , "()Lorg/shoebox/DemoJNI;" );
var instance = f1( );
var f2 = nme.JNI.createStaticMethod "org/shoebox/DemoJNI" , "test_ret_boo" , "()Z" );
var b = f2( );

 

For member methods calls you must pass as argument the JNI class instance ( by example the result of the getInstance( ) method )

1
2
var f3 = nme.JNI.createMemberMethod "org/shoebox/DemoJNI" , "test_method_nonstatic" , "(IZ)Z" );
f3( instance , 10 , false );

Quite easy isn’t it ? When you have understand the java mapping it’s quite easy to call any java method from Haxe.


1
Jul 12

HyperTouch : Haxe NME Native Gestures

Les Gestures dans les applications Android & iOS, sont le nerf de la guerre. Cela donne une impression de fluidité et de facilitée d’utilisation lorsqu’il sont bien implémentés.

Mais le problème actuel est que Haxe NME n’a actuellement aucun support pour la détection de gestures. Il existe des librairies HaXe très bien conçues qui permettent d’émuler des gestures à base de TouchEvent ( comme Gestouch ). Mais le résultat est rarement aussi parfait et sensible que les réglages crées par Google et Apple dans leurs SDK.

Les gestures émulés étant souvent basés sur des Timers entre deux TouchEvent, le délai pour un tap ( par exemple ) était bien souvent trop rapide pour tel ou tel personne. Cela avait un coté frustant de donner à tester à un tier une application et se rendre compte que celui-ci n’arrivait pas à ouvrir en menu qu’en faisant au moins trois tap sur l’écran…

Je me suis donc alors penché sur les librairies natives d’HaXe NME pour créer HyperTouch.

HyperTouch permet d’utiliser facilement et rapidement des gestures sous Android & iOS. il suffit de lier la librairie et de poser les écouteurs.

HyperTouch utilise le gestionnaire de gesture natif à iOS & Android, il n’y a pas besoin de librairies tiers, et c’est compatible avec toutes les versions d’iOS et d’android (à ma connaissance).

Utilisation

Il suffit juste d’ajouter le chemin vers l’extension dans votre description de projet NME (NMML)

1
<include path="extensions/hypertouch" if="mobile"/>

Ensuite via la classe singleton HyperTouch ajouter des écouteurs pour chaque type de gestures souhaité.

1
 
1
2
3
4
5
<em><span style="color: #000000;">var hyp = HyperTouch.getInstance( );</span></em>
<em> <span style="color: #000000;"> hyp.addEventListener( GesturePanEvent.PAN , _onPan , false );</span></em>
<em> <span style="color: #000000;"> hyp.addEventListener( GesturePinchEvent.PINCH , _onPinch , false );</span></em>
<em> <span style="color: #000000;"> hyp.addEventListener( GestureSwipeEvent.SWIPE , _onSwipe , false );</span></em>
<em> <span style="color: #000000;"> (...)</span></em><em></em>

A savoir

L’extension n’active à un instant T que les gestures qui sont écoutés sur la classe HyperTouch. Donc pensez bien à supprimer vos écouteurs lorsque vous en avez fini ;) ( ce qui est de toute manière chaudement recommandé ).

Les coordonnées de position de geste ( par exemple un simple Tap ) sont liées à la scène et à l’orientation courante. Il vous faudra donc les convertir en coordonnées locales dans certains cas.

Actuellement les gestures reconnus sont:

- Simple Tap / Double Tap
- Two Fingers Tap (seulement sous iOS pour l’instant )
- Pinch
- Rotate (seulement sous iOS pour l’instant )
- Swipe
- Pan

Todo

Il reste beaucoup à faire.

Ce qu’il faut savoir tout d’abord est que je ne suis pas un pro-coder en Java et encore moins en Objectif C, donc toute suggestion sera plus que bienvenue.

A part les quelques gestes qui reste à mettre en place, j’aimerai ajouter le support de la pression sous Android, une possibilité de changer le nombre de zones de touch nécessaires pour tel ou tel geste ( comme le pan et le swipe ). Régler quelques problème de concurrence entre certains gestes ( swipe vs pan par exemple )…

HyperTouch sur mon GitHub : ici.

A vous de toucher !