Citation:
Envoyé par
BioKore
Oui. Pendant «*longtemps*» je travaillais plutôt avec Vim + Makefiles*; mais maintenant que j’ai une belle machine de guerre sous windows, je me dis, pourquoi pas utiliser un IDE*? Certes, Code::Blocks n’est pas forcément de premier choix mais je dois avouer que j’ai un peu de mal à choisir parmi tous ceux qui existent. J’ai bien pensé à MSVC ou même éclipse, mais l’un est un produit MS (et j’ai peur qu’un code qui compile nickel sous MSVC ne compile pas nécessairement aussi bien sous GCC),
Jusqu'à il y a quelques années, ta crainte aurait été parfaitement justifiée, car, jusqu'à la version 2015 de Visual Studio, les fonctions default et delete n'était par exemple pas supportées :D
Mais, depuis, les choses ont bien évolué, et les versions suivantes ont enfin fini par supporter ad minima correctement la dernière norme sortie (C++17 pour Vs 2017 et ultérieur au moment d'écrire ces lignes)
Ceci dit, cela reste une excellente habitude que de compiler son projet avec plusieurs compilateur pour voir les éventuelles différences entre eux ;)
Citation:
Envoyé par
BioKore
et l’autre tourne sur JAVA et franchement…. Les logiciels comme ça qui ont des dépendances explicites pour fonctionner, et en particulier sous JAVA, ça ne m’attire pas vraiment… Alors oui, il en existe certainement pleins d’autres qui répondent à mes critères et qui sont super biens, mais je ne les connais pas encore :aie:
Non, ca, je te comprends :D
Mais il y a d'autres EDI disponibles, comme QtCreator ou CLion, par exemple.
Bon, tu me dira que le premier vient avec tout un framework (Qt) que tu ne veux pas forcément utiliser, mais il est parfaitement possible d'avoir des projets qui n'utilisent pas Qt avec lui :D
De plus, il est maintenant parfaitement capable de travailler avec les CMakeFiles.txt que l'on utilise pour configurer son projet avec CMake (tout comme CLion il me semble, ainsi que visual studio, d'ailleurs)
Citation:
Cmake… A tester. Je connais de nom mais c’est tout. Je vais regarder ce que ça donne.
Disons que c'est très proche des autotools (autoconf, automake, autoheader et libtool) sous linux de par son objectif, mais sous une forme qui est à la fois
- plus simple (le langage de script est à mon sens plus simple que le M4 utilisé par autotools)
- plus automatique dans la gestion (et surtout le lancement) du projet: tu écris ton fichier CMakeLists.txt et "roulez jeunesse"
- portable : on peut l'utiliser sous windows, linux et Mac sans aucun problème (l'utilisation des autotools sous windows est parfois problématique :D)
Citation:
Passer une VM sur OpenBSD ou même une Distri sous débian est une bonne idée mais travailler sous VM…. J’aime pas trop non plus.
Et pourtant, dieu sait que cela présente quelques avantages :D
Citation:
Enfin, virer mon windows (ou passer en dual boot) et switch sur un distri du genre Mint (que je trouve pas trop mal, j’ai ça sur mon portable). Mais j’ai pas mal d’applis windows que j’utilise et que je ne veux pas utiliser en VM / Wine. Pour le dual-boot ce qui m’embête un peu plus c’est la gestion des boot-loaders. Grub bazarde celui de windows, or, j’aimerais pouvoir coller un linux sur un HDD / SSD tier, et que le simple retrait de ce Disque-Dur soit entièrement transparent pour windows. C’est certainement faisable, mais je dois me renseigner sur ce sujet.
En fait, la plupart des bios te permettent de sélectionner le disque dur sur lequel il doit démarrer. Du coup, si tu as deux DD (ou plus), tu peux placer le boot loader de windows sur l'un et grub sur l'autre, et ca fonctionne pas mal ;)
Il "n'y a qu'à" indiquer le disque dur à utiliser, et on peut même le faire sans vraiment passer par le bios (en appuyant sur <F12> pendant le check mémoire)
Citation:
Sinon j’aime beaucoup Notepad++ C’est pas vraiment un IDE mais je le trouve agréable d’utilisation (plus que Kate et Code::Blocks). Problème, il ne propose pas de compiler / linker. On en reviens donc à d’autres solutions proposées ci-dessus.
Citation:
Bref, après m’être bien écarté du sujet initial, j’ai simplement laissé les infos code::blocks dans le git car pas encore complètement configuré mon gitignore. De plus, je me suis dit que ça faisait un truc plug & play pour les quelques gens qui voudraient tester le projet. Pas besoin de reconfigurer tout un projet (enfin je crois)… Mais d’accord avec toi. 1) ça ne marche peut être même pas, 2) l’utilité est particulièrement restreinte 3) les vrais dev n’utilisent pas cet IDE → je vais virer tout ça.
Malheureusement, tu t'es gouré sur ce coup là...
J'ai personnellement du refaire la configuration d'édition de liens pour pouvoir compiler ton projet :aie:
Citation:
Maintenant, l’organisation de mon code…. Très vaste sujet. Pour être franc, j’ai cherché pendant un moment (peut être faudrait-il que je m’y remette?) des documents abordant cet aspect de manière assez claire et résultat*: rien.
Pour être franc, je ne suis pas sur du tout qu'il existe la moindre source sur le sujet, que ce soit en francais ou en anglais :aie:
Citation:
Je suis donc content de pouvoir enfin avoir un audit sur ce point. Ce que je cherchais à faire ici c’est justement de séparer la partie «*ECS*» de tout ce qui gravite autour. Les fichiers présents dans le document racine sont ceux qui ne sont là, normalement que pour des raisons de test.
Oui, mais, si tu les laisses dans le dossier racine, cela donne au contraire l'impression que ce sont des fichiers essentiels au projet (plus on s'enfonce dans l'arborescence, plus on se dirige vers des fonctionnalités spécifiques ;) )
Citation:
Ceux qui sont dans «*Tools*» sont ceux qui sont remplaçables. Par exemple, si un jour je développe un peu plus mon vecteur indexé, j’aurais juste à le remplacer tout en conservant le nom des principales fonctions et tout roule. Idem pour mon fichier ECS, ce dernier est donc «*Dépendant*» des fichiers qui gravitent autour, mais, autant que je sais le faire, indépendant de leurs implémentations.
Tout à fait, mais il faut voir où se situe la dépendance.
Car, d'un coté, tu as la partie "bibliothèques de fonctionnalités", qui représente -- faisons simple -- l'ensemble des fonctionnalités que l'on peut utiliser (ou non) dans plusieurs applications, et la partie purement applicative qui fourni -- faisons simple -- la fonction main() pour générer l'exécutable.
Le fait est que, dans la partie "bibliothèques de fonctionnalité", on trouve différents "niveaux", à savoir:
- la (les) vue(s), qui est spécifique à la bibliothèque externe utilisée pour l'affichage
- la partie "métier", spécifique à une (ou plusieurs) application(s) particulière(s)
- le "coeur" commun à n'importe quel ECS, quel que soit l'application qu'il permet de mettre en oeuvre
- les "outils" qui peuvent être utilisés par d'autres projets que l'ECS
Et, surtout, que ces niveaux dépendent les uns des autres dans un certain ordre:
- L'application dépend de la vue
- la vue dépend de la partie métier (car il faut bien qu'elle sache ce qu'elle va montrer :D)
- la partie métier dépend du coeur commun à n'importe quel ECS
- le coeur commun dépend des outils
- les outils ne dépendent a priori de rien (sauf, éventuellement, d'autres outils :D)
Et ce, même s'il se peut que la vue ou la partie métier fasse appel à quelques fonctionnalités spécifiquement fournies par différents outils (mais le coeur ou la partie métier aurait du arriver nous cacher ce fait ;) )
Et, au delà, tu as une série d'éléments que tu voudras sans doute rajouter à ton projet, tels que- des tests unitaires (pour les outils, pour le coeur, pour la partie métier)
- de la documentation (pour l'ensemble)
- des exemples d'utilisation (des outils, du coeur, de la partie métier et peut être même pour certaines vues)
- des applications spécifiques (ce n'est pas le cas ici, mais on pourrait envisager d'avoir une application client, une application serveur et, pourquoi pas, un client en version "smartphone" :D)
A partir de là, on se rend compte qu'il est important de placer chaque partie dans un dossier spécifique, ce qui nous emmène sans doute (quand toutes les parties sont présentes) à une arborescence proche de
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| dossier_racine
|- apps
| |-MyApp1
| | |- client
| | |- server
| |- OtherApplication
|- documents (/ doxygen)
|- examples
| |-business
| |-core
| |-tools
| | |- tool1
| | |- tool2
| | |- ...
| |- ... ???
|- lib
| |-business
| |-core
| |-tools
| |- ... ???
|- tests
| |-business
| |-core
| |-tools
| | |- tool1
| | |- tool2
| | |- ...
| |- ... ???
|- AUTHORS
|- ChangLog
|- LICENSE
|- README
|- ... ??? |
(et, pour être tout à fait franc, je pousse le vice jusqu'à séparer les fichiers d'en-tête -- que je place dans un dossier include -- et les fichiers d'implémentation, que je place dans un fichier src)
Citation:
Mon dossier ECS est sensé marcher, que l’on l’utilise avec SFML ou tout autre librairie (à l’exception du fichier Systems.hpp qui est pour le moment quasiment vide et remplis un peu n’importe comment car je voulais faire des tests rapidement). Après, j’aborde ce sujet avec ces affirmations, peut être car je n’ai jamais vraiment réalisé de «*gros*» projets et que du coup, les fois où j’intègre le résultat d’un de mes codes comme outil d’un autre, j’adapte l’implémentation… Il me faut plus d’expérience dans le domaine pour me rendre compte que mon idée n’est pas viable.
D'après mon expérience, c'est -- à peu de chose près -- l'arborescence qui ressort de la plupart des gros projets que j'ai pu croiser; même si on parle alors plutôt de "solutions" (d'ensemble de projets pouvant évoluer de manière indépendante) ;)
Une chose est sure: à par -- éventuellement -- un squelette de fichier (ex : config.h.in) qui servira, lors de la configuration du projet à générer un fichier d'en-tête utilisé pour la configuration globale, il n'y a absolument aucun fichier contenant du code dans le dossier racine ;)
Maintenant, tous les dossiers ne sont pas forcément présents; et d'autres peuvent apparaître.
Par exemple, on pourrait envisager de rajouter un dossier 3rdParty dans lequel on pourrait rajouter les dépendances externes qui pourraient être absente du système sur lequel la solution sera compilée.
Citation:
Cependant, comme je sais que j’ai une grande marge de progression à passer dans le cadre de l’organisation de mes fichiers (oui, sans grande surprise c’est autant le bordel dans mes fichiers persos aussi!), je vais passer du temps à analyser un peu la manière dont s’organisent les autres projets sur github. Tous ne sont sûrement pas des références en la matière mais mais je pense que pour une bonne partie, j’ai quand même pas mal à apprendre. Après, si tu as une méthode ou quelques références qui abordent ce sujet de manière efficace et intelligente j’achète de suite.
La seule méthode que je connaisse c'est de regrouper les éléments en fonction de leur but ou de leur utilisation, en respectant au mieux la phrase mythique
Citation:
Ce qui ce conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément
Citation:
D’ailleurs, l’organisation que tu propose est propre à ton expérience où c’est plutôt issu de bonnes pratiques que l’on retrouve régulièrement*?
Ce n'est sûrement pas issu d'un "guide de bonnes pratiques" (ou alors, je ne l'ai pas encore lu :D)
Mais c'est très clairement le genre de structure que l'on retrouve régulièrement ;)
Citation:
Là, tu me corrigeras si je me trompe, mais ça me semble incompatible avec mon «*cahier des charges*» Bien que les systèmes et composants soient nécessairement fortement liés avec le contexte (ici SFML), je veux pouvoir utiliser mon ECS dans d’autres applications qui n’utilisent pas forcément SFML… Et là, en écrivant cette phrase, je remarque qu’en fait cela n’a pas trop de sens. Le DOP est un paradigme. L’ECS n’est qu’une solution basée sur ce paradigme. Si je réalise un autre programme très différent par la suite, alors c’est la méthodo et les outils qui importent et non l’implémentation… Repartant de ce principe, ton organisation est alors bien plus appropriée (qui en aurait douté*!?)…
En fait, l'idée est vraiment de créer un schéma de dépendances à sens unique dans lequel les fonctionnalités de "plus haut niveau" dépendent des fonctionnalités de "plus bas niveau" et dans lequel tu peux décider de retrancher tout ce qui est "de plus haut niveau" pour ne garder "que la base".
- Tu as créé un système de particules qui utilise SFML pour l'affichage. Mais tu pourrais décider d'utiliser Qt, GLFW ou Glut pour afficher ton système de particules
- Tu as utilisé des fonctionnalités de base pour créer ton système de particules. Mais avec ces fonctionnalités de base, tu pourrais créer plein d'autres choses, dont l'affichage se ferait de manière totalement différente
- Tu as utilisé certains outils pour créer tes fonctionnalités de base. Mais ces outils pourraient être utilisé dans un contexte tout à fait différent de celui d'un ECS
La bonne question à se poser c'est:
Citation:
Comment pourrais-je organiser mes fichiers pour que je puisse décider de ne prendre qu'un (ou plusieurs) dossier en étant sûr d'avoir "tout ce qu'il faut" pour pouvoir lancer "un nouveau projet" :question:
Hé bien la meilleure réponse à donner est sans doute encore de mettre tout ce qui est "forcément" destiné à fonctionner ensemble dans un dossier spécifique ;)
Citation:
Là par contre, je suis un peu plus frileux. Autant pour des versions finales d’outils terminés et / ou tiers, ça tombe sous le sens. Autant pour pour les fichiers spécifiques à un projet j’aime moins. Et c’est d’ailleurs très certainement lié à l’IDE par contre. La manipulation proposée est propre à l’IDE et non au projet. La configuration reste sur les projets suivants, pouvant apporter conflits etc.
Non, il n'y a absolument aucun risque à ce sujet:
Quel que soit l'IDE que tu utilises, chaque projet va être décrit par un (ou plusieurs) fichier(s) qui sont propre au projet en question, et qui contient l'ensemble des informations qui permettront à l'IDE de faire son travail (qui, rappelons le, consiste essentiellement à lancer les différents outils dans le bon ordre, en leur transmettant les bons paramètres), telles que:
- le dossier dans lequel placer les fichiers objets générés (pour les différentes cibles : debug / release / autres)
- le dossier dans lequel placer les exécutables générés (pour les différentes cibles : debug / release / autres), s'il y en a
- les options de compilation à transmettre au compilateur (pour les différentes cibles : "globale" / rellease /autres)
- les options à transmettre à l'éditeur de liens (pour les différentes cibles)
- la liste des fichiers à prendre en compte,
- j'en passe et de meilleurs ;)
A titre d'exemple, Code::Blocks va générer un fichier dont l'extension est en *.cbp (Code Blocks Project :D) qui est un simple fichier xml dont voici le contenu tel qu'il se présente sur git:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="ecs" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/ecs" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/ecs" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Unit filename="Context.hpp" />
<Unit filename="Events.hpp" />
<Unit filename="ecs/Components.hpp" />
<Unit filename="ecs/Entities.hpp" />
<Unit filename="ecs/Signatures.hpp" />
<Unit filename="ecs/Systems.hpp" />
<Unit filename="ecs/components/All.hpp" />
<Unit filename="ecs/components/Physics.hpp" />
<Unit filename="ecs/components/Renderables.hpp" />
<Unit filename="ecs/entities/Particles.hpp" />
<Unit filename="ecs/systems/Physics.hpp" />
<Unit filename="ecs/systems/Renderable.hpp" />
<Unit filename="main.cpp" />
<Unit filename="tools/ivector.hpp" />
<Unit filename="tools/random.hpp" />
<Extensions>
<code_completion />
<envvars />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file> |
Quand tu crées un autre projet, même si le fichier *.cbp correspondant à ce projet fini par se trouver dans le même dossier qu'un autre, chaque projet reste très clairement distinct
Par contre, tu peux envisager de créer ce qu'ils appelle un "espace de travail" (workspace) et que Visual Studio appelle "solution" pour regrouper les deux projets et, pourquoi pas, indiquer qu'un des projets dépend de l'autre (et tu n'est bien sur pas limité à deux projets :D)
Citation:
Puis si je créé un fichier vector dans la racine (ce qui est idiot, mais plausible si l’on suit le raisonnement de mon organisation actuelle) quel fichier sera inclus*? Celui de la STL ou le mien*?
Appelle le Vector (avec un V majuscule) Cela résoudra le problème.
Ou bien, place le spécifiquement dans un dossier "tools", en utilisant le dossier parent comme dossier de recherche, et inclus le sous la forme de #include <tools/vector>. Cela évitera tout risque de confusion ;)
Citation:
Mais mon «*souci*» principal étant plus lié avec le sujet de la configuration de l’IDE, ce ne sera plus un problème si je passe sur au autre IDE ou sous make.
Humm... à voir...
Quel que soit l'IDE utilisé, ou même si tu utilises CMake pour la configuration de ton projet, la configuration générale restera sensiblement pareille et risque donc de poser les même problèmes (s'il y en a) :aie:
Mais, a priori, il y a toujours moyen de s'en sortir, même avec une configuration "fine tuned" ;)
Citation:
Là, tu m’e’n donne la raison juste en dessous*:
Code:
1 2 3 4
| std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<float> randomVelocity{.0f,60.f};
std::uniform_real_distribution<float> randomRz{.0f, 6.283f}; |
On a ça vs
random::get() ...
Ca m'a pris 15 secondes et demie d'écrire ce code. Combien de temps cela t'a-t-il pris pour trouver le fichier d'en-tête, le télécharger, trouver où le placer dans ton projet et comprendre comment l'utiliser :question:
Et puisque j'en suis à me chercher des excuses, ça sûrement un sens, mais quelle idée d’appeler sa classe mt19937 qui plus est dans la stl ?[/QUOTE]
Bien sur que cela a du sens: cela fait référence à la méthode de génération de valeurs aléatoires dite Mersenne Twister, dans la version utilisant le nombre premier obtenu par la valeur 219937-1
Citation:
Moi, ça me surprends beaucoup. La STL bouffe tous les noms de classes que l’on pourrait trouver intéressante à utiliser pour NOS propres classes, et pour un truc aussi « pointu » mt19937… Je ne comprends pas.
Tu t'imagines, devoir écrire std::mersenne_twister_19937 chaque fois que tu as besoin d'un générateur aléatoire :question: :aie:
Citation:
Mais bon, c’est pas très important. Franchement, j’ai utilisé ce fichier simplement par procrastination. Pas envie d’apprendre à utiliser le mt19937,
Au moins, tu le reconnais : c'est de la procrastination :D
Mais c'est un tord, car l'utilisation de la STL mérite vraiment que l'on se penche ardemment sur le sujet :D
Citation:
fichier simple a utiliser, en static… Bref. Voilà. Mais finalement on en reviens aux sujets d’organisation, ça fait clairement un fichier que je vais avoir envie de remplacer d’ici quelques temps sans avoir à remodifier tout le code qui l’utilise. La syntaxe random::get() me sied tout à fait !
Et, si tu ne l'utilisais pas, tu n'aurais pas plus difficile à travailler :D
Au pire, tu pourrais envisager (et tu pourrais le faire ici aussi, d'ailleurs) de définir des constantes pour les valeur minimale et maximales des distributions uniformes, histoire d'éviter les valeurs magiques, mais ca, c'est un autre débat :D