OVH Cloud OVH Cloud

Renseignement

4 réponses
Avatar
Francois Lionet
Bonjour,

Je suis un programmeur C++, et j'etudie en ce moment la conversion du
runtime de notre application principale (un créateur de jeux videos) en
Java. J'ai lu les tutoriels chez Sun, realisé quelques exemples.
Une chose m'embete : l'absence de pointeur. Notre logiciel est fondé sur une
liste d'instructions, de structures qui se trouvent en mémoire. J'ai besoin
d'acceder dynamiquement à ces structures et recuperer les données qu'elles
contiennent. Pour couronner le tout, la taille des structures est variables
(éléments variables en fin de structure). En C++ c'est facile, je caste un
pointeur sur le debut de chaque structure est le tour est joué.
Comment puis-je y acceder en Java? Est-ce possible? (juste pour me mettre
sur la voie)

Merci! Francois

4 réponses

Avatar
TestMan
Bonjour,

Je suis un programmeur C++, et j'etudie en ce moment la conversion du
runtime de notre application principale (un créateur de jeux videos) en
Java. J'ai lu les tutoriels chez Sun, realisé quelques exemples.
Une chose m'embete : l'absence de pointeur. Notre logiciel est fondé sur une
liste d'instructions, de structures qui se trouvent en mémoire. J'ai besoin
d'acceder dynamiquement à ces structures et recuperer les données qu'elles
contiennent. Pour couronner le tout, la taille des structures est variables
(éléments variables en fin de structure). En C++ c'est facile, je caste un
pointeur sur le debut de chaque structure est le tour est joué.
Comment puis-je y acceder en Java? Est-ce possible? (juste pour me mettre
sur la voie)

Merci! Francois


Bonjour,

Ne te focalise pas sur les pointeurs ... ils ne te manqueront pas
longtemps ;-)

Si tu es à l'aise avec la programmation objet, tu devrais aussi creuser
du coté du concept d'interface. Le plus gros du travail sera de
reconstruire un diagramme de classe correspondant à l'application
existante (structures et instructions regroupées) et facilitant ensuite
le portage des algorithmes en objet ...
Si, ce n'est pas encore ton cas, commence par te baigner dans la POO et
réalise ensuite des petits exercices puis rapidement des exemples et
maquettes ...

Pour le reste : dynamicité, génération de bytecode dynamique ... il y à
tout ce qui faut dans et autour de Java pour ne pas être limité (sauf
par le temps et l'immagination).

Enfin, si tu es "joueur" essaye :
http://ovid.tigris.org/Ephedra/
http://tech.novosoft-us.com/product_c2j.jsp

A+
TM

Avatar
Laurent Bossavit
Salut François,

Je suis un programmeur C++, et j'etudie en ce moment la conversion du
runtime de notre application principale (un créateur de jeux videos) en


Tiens ça me dit vaguement quelque chose. ;)

Une chose m'embete : l'absence de pointeur. Notre logiciel est fondé sur une
liste d'instructions, de structures qui se trouvent en mémoire. J'ai besoin
d'acceder dynamiquement à ces structures et recuperer les données qu'elles
contiennent. Pour couronner le tout, la taille des structures est variables


A priori, une structure mémoire interprétable de taille variable pourra
être deux choses en Java:
- un tableau d'octets (byte[]) ou...
- une instance de classe...
...et souvent un mix des deux. Il faudrait voir un peu plus précisément
tes structures de données, mais à priori chacune relève d'un type
général: sprite, son, etc.

Il y a de bonnes chances pour que tu te retrouves avec une classe Java
pour chacun des principaux types possible. Tu peux quand même continuer
à encapsuler des données "binaires" dans des tableaux d'octets qui
seront des variables d'instance de ces classes.

Par exemple, si tu lis avec ton runtime Java un fichier binaire
contenant les définitions d'un jeu créé avec le moteur C++, je suppose
que la structure d'un élément ressemble grosso modo à ceci:
2 octet pour le type d'élément
2 octets pour la taille des données de l'élément
N octets pour la définition de l'élément

Au moment de la lecture, tu va lire les 4 premiers octets; ça te permet
a) de créer une instance "vide" de la classe appropriée pour son type
b) d'allouer un tableau d'octets de N octets

Le résultat en Java ressemblera à peu près à ceci:

// Lire le type, la taille, puis les données
int elementType = readIntFromFile();
int elementDataLength = readIntFromFile();
byte[] elementData = new byte[elementDataLength];
// Créer une instance de la bonne classe
AbstractElement element = createElement(elementType,elementData);

L'idée c'est que toutes les classes représentant tes divers éléments de
jeu sont des classes héritant d'une classe (ou encore mieux implémentant
une interface) qui permet de les traiter génériquement.

Dans chaque classe tu vas coder les manipulations spécifiques des
données binaires permettant de les interpréter correctement en fonction
du type de l'élément. Idéalement, tu auras des classes très génériques
pour manipuler des données communes (largeur, hauteur, etc) et des
classes plus spécifiques pour manipuler ce qui est spécifique à chaque
type.

C'est-y clair ? ;)

Laurent

Avatar
Francois Lionet
Salut Laurent! C'est sympa de te retrouver.

J'ai une autre question, pour Laurent ou pour toute personne qui pourra me
repondre.
Dans mon programme, il y a de grosses tables d'indirection vers des
routines, qui sont pointées par des valeurs de tokens. Peut-on faire des
tables de fonctions en Java? Ou doit-on passer par un switch / case massif?

Merci! Francois
Avatar
Laurent Bossavit
François,

Dans mon programme, il y a de grosses tables d'indirection vers des
routines, qui sont pointées par des valeurs de tokens. Peut-on faire des
tables de fonctions en Java? Ou doit-on passer par un switch / case massif?


L'idée en objet c'est que tu transformes les switch/case en héritage
("extends") ou polymorphisme ("implements").

Si tu as ça en C++:

typedef int (*TypePtrDeFonction)(int param);

extern int fonc_1(int param);
extern int fonc_2(int param);
TypePtrDeFonction maTableDeFonctions[2]
maTableDeFonctions[0] = &fonc_1;
maTableDeFonctions[1] = &fonc_2;

int token;
int resultat = *(maTableDeFonctions[token])(monParametre);

Tu vas avoir ça en Java:

public interface InterfaceRoutine {
public int appel(int param);
}

public class Routine_1 implements InterfaceRoutine { ...etc... }
public class Routine_2 implements InterfaceRoutine { ...etc... }

InterfaceRoutine maTableDIndirection = new InterfaceRoutine[2];
maTableDIndirection[0] = new Routine_1();
maTableDIndirection[1] = new Routine_2();

int token;
int resultat = maTableDIndirection[token].appel(param);

Si tes indirections ne sont pas trop tordues ce type de "portage" est
assez naturel. (Je dis bien "si" puisqu'en C/C++ on peut tout faire y
compris des choses qu'on regrette après...)

A+