Forum de la communauté SFML

Général => Projets SFML => Discussion démarrée par: Cmdu76 le Novembre 29, 2013, 08:40:08 pm

Titre: Framework
Posté par: Cmdu76 le Novembre 29, 2013, 08:40:08 pm
Bonjour,

Je suis d'assez près les quelques projets de framework sur ce forum (en ce moment celui de Lolilolight avec sa 3D)

Je suis moi-même en train de développer une sorte de framework et je pense qu'au lieu de séparer les framework de chacun on devrait faire un framework ensemble avec un max de gens de la communauté SFML.

Et donc pourquoi pas créer un framework "SFGL" (idée de nom du framework de Lolilolight) par la communauté française (et pourquoi pas anglaise) enfin un truc de "fou" qui puisse justement être digne de la SFML

Je vais donner une liste de framework plus ou moins abouti que j'ai trouvé :

- https://github.com/SFML/SFML-Game-Development-Book, Le livre sur SFML qui présente un jeu plutôt pas mal avec les concepts importants

- https://github.com/tobsa/SFML-Framework, Ici un anglais mais c'est un framework avec des fonctionnalités sympas

- https://github.com/Lo-X/potato-framework, Un très bon framework, celui de Lo-x, un membre SFML français

- https://github.com/Cmdu76/GameTest, Le mien, fortement inspiré du livre SFML, je me sers de l'héritage sur des classes présentées dans le livre pour ne pas toucher à grand chose au final

- http://fr.sfml-dev.org/forums/index.php?topic=12616.0, Le projet de RPG 2D en réseau de Lolilolight

- http://fr.sfml-dev.org/forums/index.php?topic=13485.0, Le projet pour la 3D de Lolilolight, que je mentionne plus haut

- http://fr.sfml-dev.org/forums/index.php?topic=7617.0, Un projet plutôt abouti sur les jeux Sonic mais le code est très bien construit

EDIT : http://khayyam.developpez.com/articles/cpp/jeux/architecture/, Très bon article présentant une structure un peu différente mais intéressante

EDIT : https://github.com/TankOs/SFGUI, Je crois que c'est un des meilleurs (ou même le meilleur) système de GUI pour SFML

EDIT : http://code.google.com/p/gqe/, Un projet de moteur de jeu cité par Lo-x sur son devblog pour son système d'entités vraiment génial :)

EDIT : http://code.google.com/p/engenesis/, un framework développé par Lo-x

Lo-x si tu me lis, parle-moi de tes 2 frameworks :)

Bon voilà c'est des projets que certains connaissent bien et peut-être même que vous en êtes l'auteur, dans tout les cas, je pense que créer un github avec le nom de SFGL et se faire un framework qui soit digne de ce nom serait mieux ensemble :)

Titre: Re : Framework
Posté par: Cmdu76 le Novembre 29, 2013, 09:07:29 pm
Si un github il doit y avoir, je pense qu'on laissera Laurent le gérer (enfin s'il est d'accord) ça évitera des problèmes "bêtes" aussi on sera sûr que le code est reconnu par un expert et que le code sera bien "digne" de la SFML :)

Ensuite on doit pouvoir se mettre d'accord sur la structure du framework, comment on englobe tout, tout ce qui est State, les ressources ... Et ça, ça se réfléchit un minimum, surtout quand on est à plusieurs, voilà voilà :)


Titre: Re : Framework
Posté par: Laurent le Novembre 29, 2013, 09:21:35 pm
Citer
Si un github il doit y avoir, je pense qu'on laissera Laurent le gérer (enfin s'il est d'accord) ça évitera des problèmes "bêtes" aussi on sera sûr que le code est reconnu par un expert et que le code sera bien "digne" de la SFML
Là je t'arrête tout de suite. J'ai déjà pas le temps de m'occuper de SFML, alors... ;D

Sinon c'est évidemment une très bonne initiative, mais je pense que ça ne va rien donner. Les gens que tu as repéré font leur framework pour le fun, pour apprendre. C'est fun parce qu'ils y mettent ce qu'ils veulent, quand ils veulent, comme ils veulent. Faire un projet commun avec toute une équipe, c'est des contraintes, de l'organisation, des opinions différentes, etc. C'est déjà moins fun. Malheureusement.
Titre: Re : Framework
Posté par: Cmdu76 le Novembre 29, 2013, 09:39:36 pm
Je me doutais que tu serais trop pris, c'est pour ça aussi que j'ai précisé le "si tu étais d'accord" :)

En effet j'avais pas pensé que à ce côté contrainte comme tu le soulignes ...

Après si c'est sur github et qu'on travaille en communauté le but n'est pas de finir le framework en 1 mois, le but c'est que chacun apporte une ou plusieurs pierres à l'édifice et que sur le long terme on est un résultat plus que correct !

La plupart des projets que j'ai montré sont open-source et leurs proprios passent régulièrement ici, je pense que faire une "fusion" des idées/concepts/atouts de chaque projet peut mener à un très bon résultat si on arrive à former une équipe.

Si il y a des motivés, qu'ils se fassent connaître ici :)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 01, 2013, 04:37:58 pm
Harf je n'ai pas encore pu mettre le code source de mon framework sur git-hub. (Framework que j'utilise pour mon futur jeux en 2D (pour le projet Sorrok comme tu l'as cité plus haut) et plus tard pour des jeux en 3D.)
Mais j'essayerai de le mettre bientôt en ligne et de faire un petit tutoriel par la même occasion.
Je m'impose beaucoup de contrainte au niveau optimisation, gestion de ressources, et simplicité d'utilisation. (Afin que je puisse l'utiliser le plus simplement possible dans mes différents projets c'est à dire, l'éditeur de carte, le client et le serveur)
J'ai commencé avec SFML dans le but d'apprendre comme la plupart des membres ici je suppose et donc, de ce fait, mon framework ne peut s'utiliser que avec SFML et opengl. ^^ (Mais bon si il y a des personnes qui connaissent d'autre api comme par exemple la SDL, directX pour la 3D, etc...) je ne suis pas contre le fait qu'il y ai cette fonctionnalité mais ce que je vise avant tout c'est la performance et la simplicité et non la variété dans un 1er temps.

Enfin soit pour ma part je suis d'accord pour mettre tout ça en commun afin de créer quelque chose de vraiment plus communautaire.

Surtout au niveau performance, sécurité et simplicité je pense que ça pourrait être intéressant.

Je n'ai pas encore inclus le module réseau dans le framework par contre mais ça, j'ai le code source sur mon PC donc je n'aurai qu'à l'inclure, ça ira vite.
Faire un topic sur le forum anglais serait bien également car je sèche un peu sur certains points. :P
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 01, 2013, 05:00:07 pm
J'ai hâte de pouvoir ce qu'il en est de ton projet, ça m'a l'air vraiment pas mal :)

Citer
Mais bon si il y a des personnes qui connaissent d'autre api comme par exemple la SDL, directX pour la 3D, etc..

On pourrait mais moi aussi je voyais le framework sans forcément qu'il s'appuit sur d'autres API, je pense que la SFML fait déjà largement l'affaire :)
Qt peut aussi être un bon choix mais je ne maîtrise pas dutout et SFML propose un sytème de GUI qui (SFGUI) qui est aussi un très bon choix (je sais que SFGUI utilise un système de signaux/slots inspiré de celui de Qt)

Ce qu'on peut faire, c'est partir de ton framework comme base du framework communautaire , donc si tu es d'accord je te laisse créer le repertoire SFGL sur GitHub et tu mettras le lien dans ce topic.

Après faudrait un chat ou quelques choses pour pouvoir réfléchir en groupe afin d'obtenir un bon résultat et de choisir comment traiter l'utilisation de certaines parties (State;Graphisme;GUI;Collisions;Réseau;...)

Et ensuite faudrait une réel équipe avec des membres assignés à certaines parties.

Ensuite la communauté pourrait quand même travailler sur le projet en se réferrant aux différents responsables en fonction du sujet désiré
Titre: Re : Framework
Posté par: Lolilolight le Décembre 01, 2013, 05:16:06 pm
Oui sfml fait déjà très bien l'affaire.  :)

Au niveau des collisions moi j'ai fait un système simple, la map est composé d'une grille avec des cases, et le personnage peut soit passer sur la case ou soit ne pas passer sur la case. (Donc j'ai utilisé un simple booléen quoi)

Mais il y a surement moyen de faire autrement voir même mieux.

Au niveau du réseau j'ai fais un cryptage hétérogène avec la librairie openssl, ça aussi il faudra que je la link au framework (donc, un cryptage RSA pour transmettre la clé publique pour un cryptage aes)
Car la taille des messages est limitée pour le cryptage RSA à +/- la taille de la clé.
Et j'ai fais une classe Network qui stocke les messages reçu par le client ou le serveur, et qui les envoyes au client ou au serveur. (Ca dépend si on se situe du côté de l'api client ou du côté de l'api serveur)

Bref j'utilise un thread pour le réseau aussi pour recevoir et envoyé les messages.

De toute façon vous verrez ça dès que j'aurai créer le répertoire sur git-hub.
Et j'aimerais justement avoir des avis, pour le moment pour les guis avec les boutons et tout ça j'utilise QT mais sfgui pourrait convenir aussi en effet, mais, j'ai pas trop envie d'imposer une librairie pour l'utilisation de GUI, car, ça, ça varie beaucoup selon les différents types de jeux les gui donc je préfères que le créateur du jeux crée lui même ses guis avec la bibliothèque de son choix.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 01, 2013, 06:43:55 pm
Voilà j'ai créer un répertoire git-hub ou j'ai mis en ligne quelques sources (pas tout) du framework.
Car je voulais juste test le linkage avec CMake.
Voici le lien vers le repository : https://github.com/Lolilolight/SFGL (https://github.com/Lolilolight/SFGL)

Pour le compiler et l'installer c'est simple il suffit de faire comme pour la SFML. (Cf le tutoriel sur compiler SFML avec CMake donc)

Mais j'ai un soucis lorsque je veux utiliser le framework avec ces simple ligne de code :
#include <SFGL/World/2D/world.h>
using namespace sfgl;
int main () {
    TextureManager &tm = World::getTextureManager();
    return 0;
}
 

Le 1er soucis (qui n'en est pas vraiment un) c'est que je suis obligé de linker les .a de SFML à mon projet sinon j'ai des erreurs à l'édition de lien.

Mon second soucis c'est que j'ai un crash à l'exécution.

Donc voilà si quelqu'un pourrait m'aider se serait bien.

PS : je n'ai essayé que sur windows en 32 bits donc..., je ne peux pas garantir que la compilation de la librairie fonctionne sur des autres plateforme.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 01, 2013, 06:53:19 pm
Et voilà le message d'erreur que ça me met :
(cliquer sur l'image pour agrandir)
(http://img15.hostingpics.net/thumbs/mini_260893probleme.jpg) (http://www.hostingpics.net/viewer.php?id=260893probleme.jpg)

Et pourquoi il me met application 16 bits dans le titre du message ???
C'est une application que j'ai compilé en 32 bits pourtant, pas en 16 bits.
Titre: Re : Framework
Posté par: Excellium le Décembre 01, 2013, 07:17:05 pm
Je suis assez partant pour une collaboration.
Là je suis sur une GUI que je vais bientôt révéler à la communauté.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 01, 2013, 07:22:34 pm
Ok. :)
Titre: Re : Framework
Posté par: Laurent le Décembre 01, 2013, 07:29:54 pm
Citer
voilà le message d'erreur que ça me met
Ce post-ci sert à collecter les idées / contributions pour un framework commun, pas à résoudre les erreurs de ta bibliothèque, pour lesquelles tu as déjà créé un sujet sur le forum. Merci de ne pas t'éparpiller.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 01, 2013, 08:29:57 pm
Ok. :)
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 01, 2013, 11:34:02 pm
J'irais jeter un coup d'oeil au github demain, pour voir comment qu'ça marche :)

Pour les collisions, il faut prévoir que le jeu ne sera pas forcément constitué d'une tilemap, enfin presque mais le joueur ne se déplace pas forcément sur l'alignement des cases, il faut, je pense, une sorte de classe spéciale avec différents types de collisions. (Le système de collision du SpinyEngine est vraiment poussé là-dessus d'après ce que j'ai vu)

Pour les GUI, justement je pense qu'il faut que ça soit intégré au framework enfin dans la base, ensuite l'utilisateur envoit ses propres textures et des fichiers xml pour les découpages (enfin c'est comme ça que je vois le truc)

Ensuite, niveau réseau je suis pas trop trop callé mais un cryptage RSA est assez important donc parfait
Et le framework doit permettre de choisir si le jeu sera en réseau ou non.

Pareil pour les graphismes, il faut pouvoir laisser le choix du type 2d/3d.

Voilà, en tout cas je suis content de voir quelques intéressés :)
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 02, 2013, 12:01:55 am
Okay je viens de passer jeter un coup d'oeil rapide :)

Il y a des choses pas mal dutout !

Mais j'ai pas encore fait vraiment le tour  entier j'y repasserai demain quand j'aurai le temps :)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 02, 2013, 09:21:52 am
Ok, de mon côté, j'ai enfin réussi à déterminé d'ou venait ce crash, donc, j'ai enfin réussi à exécuté un projet utilisant SFGL, je vais donc mettre à jour tout ça sur git-hub et commencer à faire quelques tutoriels.
Mais il y a surement moyen d'encore améliorer l'installation du framework et de la rendre fonctionnelle sur d'autres plateformes, mais, comme je galère beaucoup avec CMake et que c'est mon tout premier framework je pense que je vais laisser le soin à un expert de s'en charger, de plus je n'ai pas de mac et je ne connais pas xcode.

J'ai oublié de préciser que SFGL utilise boost également donc, il faut installer boost. :)

Plus tard quand je mettrai le module réseau sur git-hub, il faudra aussi installer openssl que j'utilise pour le module réseau.

Un aperçu du code source  pour le réseau :
Classe qui se charge d'appliquer un chiffrement RSA aux octets envoyés sur le réseau
#include "rsa.h"
#include <stdlib.h>
#include <iostream>

int Rsa::size = 0;
X509* Rsa::x = X509_new();
EVP_PKEY* Rsa::evp_pkey = EVP_PKEY_new();
BIO* Rsa::pub = BIO_new(BIO_s_mem());
size_t Rsa::pub_len = 0;
char* Rsa::pub_key = NULL;
RSA* Rsa::keypair = generateKeys(2048);
int Rsa::getCertificate (unsigned char **out) {
    int len= i2d_X509(x, out);
    return len;
}

void Rsa::setCertificate(const unsigned char* in, int length) {
    x = d2i_X509(NULL,&in,length);
    evp_pkey = X509_get_pubkey(x);
    keypair = EVP_PKEY_get1_RSA(evp_pkey);
    PEM_write_bio_RSAPublicKey(pub, keypair);
    pub_len = BIO_pending(pub);
    free(pub_key);
    pub_key = (char*)malloc(pub_len + 1);
    BIO_read(pub, pub_key, pub_len);
    pub_key[pub_len] = '\0';
}
int Rsa::encryptWithPrKey (const char *data, size_t dataSize, char **encData) {
    *encData = new char[RSA_size(keypair)];
    int encDataLen = RSA_private_encrypt(dataSize, (unsigned char*) data, (unsigned char*)*encData, keypair, RSA_PKCS1_PADDING);
    if (encDataLen == -1) {
        char* err = (char*) malloc(130);
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
        return FAILURE;
    }
    return encDataLen;
}
int Rsa::decryptWithPrKey (const char *encData, size_t dataSize, char **data) {
    char *msg = new char[dataSize];
    int dataLen = RSA_private_decrypt(dataSize, (unsigned char*) encData, (unsigned char*)msg, keypair, RSA_PKCS1_OAEP_PADDING);
    if (dataLen == -1) {
        char* err = (char*) malloc(130);
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
    }
    *data = new char[dataLen+1];
    memcpy(*data, msg, dataLen);
    (*data)[dataLen] = '\0';
    delete[] msg;
    return dataLen;
}
int Rsa::encryptWithPbKey (const char *data, size_t dataSize, char **encData) {
    *encData = new char[RSA_size(keypair)];
    int encDataLen = RSA_public_encrypt(dataSize, (unsigned char*) data, (unsigned char*) *encData, keypair, RSA_PKCS1_OAEP_PADDING);
    if (encDataLen == -1) {
        char* err = (char*) malloc(130);
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
        return FAILURE;
    }
    return encDataLen;
}
int Rsa::decryptWithPbKey (const char *encData, size_t dataSize, char **data) {
    char *msg = new char[dataSize];
    int dataLen = RSA_public_decrypt(dataSize, (unsigned char*) encData, (unsigned char*) msg, keypair, RSA_PKCS1_PADDING);
    if (dataLen == -1) {
        char* err = (char*) malloc(130);

        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        free(err);
        return FAILURE;
    }
    *data = new char[dataLen+1];
    memcpy(*data, msg, dataLen);
    (*data)[dataLen] = '\0';
    delete[] msg;
    return dataLen;
}
 

Classe qui se charge de d'appliquer un chiffrement aes aux octets envoyé sur le réseau :

#include "aes.h"
using namespace std;

#include <iostream>

int AES_ENC::size = 0;
unsigned char* AES_ENC::key = new unsigned char[32];
unsigned char* AES_ENC::iv = new unsigned char[32];
unsigned char* AES_ENC::aesSalt = new unsigned char[32];
EVP_CIPHER_CTX* AES_ENC::e_ctx = new EVP_CIPHER_CTX;
EVP_CIPHER_CTX* AES_ENC::d_ctx = new EVP_CIPHER_CTX;
unsigned char* AES_ENC::aesPass = generateKey(256);

int AES_ENC::encrypt(const char* data, size_t dataSize, char **encData) {
    size_t blockLen  = 0;
    size_t encDataLen  = 0;
    *encData = new char[dataSize + AES_BLOCK_SIZE];
    if (EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, key, iv) == 0)
        return FAILURE;
    if (EVP_EncryptUpdate(e_ctx, (unsigned char*) *encData, (int*)&blockLen, (unsigned char*) data, dataSize) == 0)
        return FAILURE;
    encDataLen += blockLen;
    if(EVP_EncryptFinal_ex(e_ctx, (unsigned char*) *encData + encDataLen, (int*)&blockLen) == 0)
        return FAILURE;
    EVP_CIPHER_CTX_cleanup(e_ctx);
    return encDataLen + blockLen;
}
int AES_ENC::decrypt(const char* encData, size_t dataSize, char **data) {
    size_t dataLen   = 0;
    size_t blockLen = 0;
    *data = new char[dataSize];
    if (EVP_DecryptInit_ex(d_ctx, EVP_aes_256_cbc(), NULL, key, iv) == 0)
        return FAILURE;
    if (EVP_DecryptUpdate(d_ctx, (unsigned char*) *data, (int*)&blockLen, (unsigned char*) encData, (int)dataSize) == 0)
        return FAILURE;
    dataLen += blockLen;
    if (EVP_DecryptFinal_ex(d_ctx, (unsigned char*) *data + dataLen, (int*)&blockLen) == 0)
        return FAILURE;
    dataLen += blockLen;
    (*data)[dataLen] = '\0';
    EVP_CIPHER_CTX_cleanup(d_ctx);
    return dataLen;
}
void AES_ENC::setKey(char* sKey) {
   strncpy((char*) key, sKey, size / 8);
}
void AES_ENC::setIv(char* sIv) {
   strncpy((char*) iv, sIv, size / 8);
}
char* AES_ENC::getKey() {
   return (char*) key;
}
char* AES_ENC::getIv() {
   return (char*) iv;
}
 

Classes qui se charge de chiffrer les octets dans des paquets SFML :

#include "encryptedPacket.h"
#include "client.h"
using namespace std;
using namespace sf;

const void* EncryptedPacket::onSend (size_t& dataSize) {
    char* buffer = NULL;
    dataSize = Rsa::encryptWithPbKey(static_cast<const char*> (getData()), getDataSize(), &buffer);
    return &buffer[0];
}
void EncryptedPacket::onReceive (const void* data, size_t dataSize) {
    char* buffer = NULL;
    int newDataSize = Rsa::decryptWithPbKey(static_cast<const char*> (data), dataSize, &buffer);
    append(&buffer[0], newDataSize);
}
 

#include "symEncPacket.h"

using namespace std;
using namespace sf;

const void* SymEncPacket::onSend (size_t& dataSize) {
    char* buffer = NULL;
    dataSize = AES_ENC::encrypt(static_cast<const char*> (getData()), getDataSize(), &buffer);
    return &buffer[0];
}
void SymEncPacket::onReceive (const void* data, size_t dataSize) {
    char* buffer = NULL;
    int newDataSize = AES_ENC::decrypt(static_cast<const char*> (data), dataSize, &buffer);
    append(&buffer[0], newDataSize);
}
 

La classe client qui se charge d'établir une connexion sécurisée entre un client et un serveur du framework et d'envoyer des message sur le réseau :

#include "client.h"
#include "network.h"
using namespace sf;
using namespace std;
SrkClient::SrkClient () {
    running = false;
    selectedCanal = 0;
    remotePortUDP = 4568;


}
void SrkClient::setSelectedCanal (int canal) {
    this->selectedCanal = canal;
}
int SrkClient::getSelectedCanal () {
    return selectedCanal;
}
void SrkClient::getPublicKey () {

    string message = "GetPbKeyRsa";
    Network::sendTCPMessage(message);
    bool done, pbKeyRsaReceived;
    done = pbKeyRsaReceived = false;
    Packet packet;
    EncryptedPacket enc_packet;
    while (!done || !pbKeyRsaReceived) {
        if (!pbKeyRsaReceived) {
            if (clientTCP.receive(packet) == Socket::Done) {
                string message;
                packet>>message;
                Network::setPbKey(message);
                pbKeyRsaReceived = true;
                message = "GetPbKey";
                Network::sendTCPMessage(message);
            }
        } else if (pbKeyRsaReceived && !done) {
            if (clientTCP.receive(enc_packet) == Socket::Done) {
                string message;
                enc_packet>>message;
                Network::setSymPbKey(string(message));
                done = true;
            }
        }
    }
}
bool SrkClient::startCli(int portTCP, int portUDP, IpAddress adress) {

    if (!running) {
        if (clientUDP.bind(portUDP) != Socket::Done) {
            cout<<"Erreur : impossible d'écouter sur le port : "<<portUDP<<endl;
            return false;
        }
        if(clientTCP.connect(adress, portTCP) != Socket::Done) {
            cout<<"Erreur : impossible de se connecter au serveur!"<<endl;
            return false;
        } else {
            cout<<"Client started!"<<endl;

            m_thread = thread (&SrkClient::run, this);
            return true;
        }
    } else {
        cout<<"Client already started!"<<endl;
        return false;
    }
}
void SrkClient::stopCli() {
    if(running) {
        running = false;
        m_thread.join();
    } else {
        cout<<"Client already stopped"<<endl;
    }
}
void SrkClient::sendTCPMessage(Packet &packet) {
    lock_guard<recursive_mutex> locker(rec_mutex);
    if(clientTCP.send(packet) != Socket::Done)
        cout<<"Erreur!"<<endl;
}
void SrkClient::sendUDPMessage(Packet &packet) {
    lock_guard<recursive_mutex> locker(rec_mutex);
    if(clientUDP.send(packet, Configuration::serverAddress, remotePortUDP) != Socket::Done)
        cout<<"Erreur!"<<endl;
}
bool SrkClient::isRunning () {
    return running;
}
void SrkClient::run() {
    SymEncPacket packet;
    running = true;
    getPublicKey();
    short unsigned int port;
    IpAddress address;
    selector.add(clientTCP);
    selector.add(clientUDP);

    while (running) {
        if (selector.wait(seconds(10))) {
            lock_guard<recursive_mutex> locker(rec_mutex);
            if (selector.isReady(clientTCP)) {
                packet.clear();
                if(clientTCP.receive(packet) == Socket::Done) {

                    string message;
                    packet>>message;
                    Network::addResponse(message);

                }
            }
            if (selector.isReady(clientUDP)) {
                packet.clear();
                if (clientUDP.receive(packet, address, port) == Socket::Done) {

                    if (address == Configuration::serverAddress) {
                        string message;
                        packet>>message;
                        Network::addResponse(message);
                        remotePortUDP = (remotePortUDP != port) ? port : remotePortUDP;
                    } else {
                        cout<<"This message don't provide from the server."<<endl;
                    }

                }
            }
        }
    }
}

 

Et enfin, la classe Network qui permettra de récupérer tout les messages renvoyé par le serveur, et d'envoyer des messages au serveur :

#include "network.h"

using namespace sf;
using namespace std;
SrkClient& Network::cli = Network::getCliInstance();
Clock Network::clock = Clock();
vector<string> Network::messages = vector<string>();
Time Network::timeOut = seconds(3.f);
bool Network::startCli (int portTCP, int portUDP, IpAddress address) {

    return cli.startCli(portTCP, portUDP, address);
}
void Network::changeClientChannel(int channel) {
    cli.setSelectedCanal(channel);
}
int Network::getClientChannel () {
    return cli.getSelectedCanal();
}
void Network::stopCli () {
    cli.stopCli ();
}
void Network::addResponse(string message) {

    messages.push_back(message);
}
void Network::sendTCPMessage (string message) {
    if (message == "GetPbKeyRsa") {
        Packet packet;
        packet<<message;
        cli.sendTCPMessage(packet);

    } else if (message == "GetPbKey") {
        EncryptedPacket packet;
        packet<<message;
        cli.sendTCPMessage(packet);
    } else {
        SymEncPacket packet;
        packet<<message;
        cli.sendTCPMessage(packet);
    }
}
void Network::sendUDPMessage(string message) {
   SymEncPacket packet;
   packet<<message;
   cli.sendUDPMessage(packet);
}
bool Network::getResponse(string tag, string &response) {
    vector<string>::iterator it;
   //globalMutex->lock();
    for (it = messages.begin(); it != messages.end();) {

        if (it->find(tag) != string::npos) {
            response = *it;
            it = messages.erase(it);
            return true;
        } else {
            it++;
        }
    }
   // globalMutex->unlock();
    return false;
}
bool Network::hasResponse() {
    return messages.size() != 0;
}
string Network::getLastResponse () {
    string response = "";
    clock.restart();
    vector<string>::iterator it;

    while (response == "" && clock.getElapsedTime().asSeconds() < timeOut.asSeconds()) {
        if (messages.size() > 0) {
            it = messages.begin();
            response = *it;
            it = messages.erase(it);
        }
    }
    return response;
}
string Network::waitForLastResponse(string tag) {
    string response = "";
    clock.restart();
    vector<string>::iterator it;
    //globalMutex->lock();
    while (response == "" && clock.getElapsedTime().asSeconds() < timeOut.asSeconds()) {
        if (messages.size() > 0) {
            for (it = messages.begin(); it != messages.end();) {
                if (it->find(tag) != string::npos) {
                    response = *it;
                    it = messages.erase(it);
                    return response;
                } else {
                    it++;
                }
            }
        }
    }
    //globalMutex->unlock();
    return response;
}
void Network::setPbKey (string message) {
    Rsa::setCertificate(reinterpret_cast<const unsigned char*>(message.c_str()), message.length());
}
void Network::setSymPbKey (string pbKey) {
    vector<string> parts = split(pbKey, "-");
    AES_ENC::setKey(const_cast<char*>(parts[0].c_str()));
    AES_ENC::setIv(const_cast<char*>(parts[1].c_str()));
}
 

Titre: Re : Framework
Posté par: Cmdu76 le Décembre 02, 2013, 12:42:14 pm
Je suis en cours mais j'ai fait une liste des "systèmes" qu'un framework devrait posséder. Je posterais un .txt les listant ce soir

J'ai réfléchit et ce que je vais faire je vais push les classes de mon projet perso ensuite on va faire un bon gros tri.

Il faut que toutes nos classes soient comprises dans le namespace sfgl

Et oui le fait d'être dépendant de boost je trouve pas ça vraiment top... surtout que C++11 intègre beaucoup des fonctionnalités de boost :)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 02, 2013, 01:15:04 pm
Citer
Et oui le fait d'être dépendant de boost je trouve pas ça vraiment top... surtout que C++11 intègre beaucoup des fonctionnalités de boost :)

Ha oui, le c++11 intègre aussi la fonction tokenizer de boost ???
vector<string> split (const string &chaine, const string &separators) {
    vector<string> sousChaines;
    typedef boost::tokenizer<boost::char_separator<char> > myTok;
    boost::char_separator<char> sep(separators.c_str());
    myTok tok (chaine, sep);
    for (myTok::const_iterator it = tok.begin(); it != tok.end(); ++it) {
        sousChaines.push_back(*it);
    }
    return sousChaines;
}
 

Si oui bah je vais pouvoir enlever la dépendance de boost. :) (Ce qui me ferai en effet plaisir car moins il y a de dépendances plus simple ça sera pour l'installation)

A part ça, j'ai commencé à rédigé un petit tutoriel sur ce site :
http://www.jeux-libres.com/tutoriaux/tuto-679-chapitre-introduction-et-installation-de-sfgl.php (http://www.jeux-libres.com/tutoriaux/tuto-679-chapitre-introduction-et-installation-de-sfgl.php)

Qui illustre déjà un peu le principe de base.




Titre: Re : Framework
Posté par: Cmdu76 le Décembre 02, 2013, 02:35:42 pm
Pas mal le tutoriel, mais je trouve que l'utilisation est plutôt "brouillon"...

Aussi utilse les std::shared_ptr, c'est beaucoup plus safe :)

Liste de modules :
- Resources
- Graphismes
- Input
- States
- Gui
- Audio
- Network
- Errors
- Maths
- Files
- Application
- Physique
- Collisions
- Gameplay
- String
- Paramètres
- Surcouche
- Scripts
- XML
- SQL
- ...
Titre: Re : Framework
Posté par: Lo-X le Décembre 02, 2013, 03:19:39 pm
Salut,

Alors déjà merci de citer Potato dans la liste, ça fait toujours plaisir :)

Je suis un peu en retard dans la conversation, mais puisque tu le demande, voici des précisions sur mes frameworks.

Le plus vieux, Engenesis, n'est plus du tout à jour. Je débutais et je ne re-ferai plus rien de la même manière maintenant. Je le garde sur GitHub parce que j'ai pas le coeur à le supprimer, mais il ne faut pas aller le voir :p

Potato est un peu plus récent et se base beaucoup sur le livre "SFML Game Development" (que je recommande à tous une fois de plus).
Je ne l'ai pas mis à jour depuis quelques temps (enfin sur GitHub), mais j'ai une partie réseau, quelques ajouts et modifications à commiter une fois que ce sera propre. Cependant, Binary1259 sur le forum anglais m'a pris de cours en publiant son framework réseau, qui semble vraiment vraiment très bien, alors je vais peut-être utiliser sa lib plutôt que de refaire des choses. Néanmoins mon framework devrait être une bonne base, si tant est que vous êtes un peu débrouillard (y'a pas de doc).


Concernant la collaboration, j'aimerais dire que j'y participerai, la vérité c'est que je ne sais pas si j'aurai vraiment le temps. J'ai déjà pas le temps pour mes frameworks/jeux.
De plus je suis assez d'accord avec Laurent, personnellement ce que je publie sur GitHub c'est surtout de l'essai ou de l'apprentissage, je ne prétends pas être apte à créer une lib. Mais c'est fun, apprendre avec ce genre de projet c'est fun. Passer sur quelque chose de plus sérieux, ça l'est moins.

Donc, pour le moment, je ne sais pas. Il faut voir, s'il y a de bonnes idées. Je suivrai le projet de près bien sur, pourquoi pas faire un fork et y ajouter ma pierre. Mais je ne pense pas pouvoir faire partie des "fondateurs"
Titre: Re : Framework
Posté par: Lolilolight le Décembre 02, 2013, 03:30:30 pm
Citer
Pas mal le tutoriel, mais je trouve que l'utilisation est plutôt "brouillon"...

Aussi utilse les std::shared_ptr, c'est beaucoup plus safe :)

Je ne connais pas encore toutes les fonctionnalités du c++11 car ça n'existait pas encore quand j'ai commencé le framework donc je dois en effet faire quelques modifs encore.

Pour le peu que je sache comment les mécanismes du c++11 fonctionne. :) (Et si c'est encore en expérimental ou pas)

Citer
Liste de modules :
- Resources
- Graphismes
- Input
- States
- Gui
- Audio
- Network
- Errors
- Maths
- Files
- Application
- Physique
- Collisions
- Gameplay
- String
- Paramètres
- Surcouche
- Scripts
- XML
- SQL
- ...
Ca me semble faire un peu beaucoup de modules différents là. (Sachant qu'il faut tous les linker au projet j'aimerais n'en faire que 10 grand max)

Bref je vais m'amuser un peu en testant les shared_ptr et les std::array. :D

Le projet est en effet assez sérieux. (Mais même dans les projets sérieux, sans fun on y arrive pas)
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 02, 2013, 04:14:29 pm
Lolilolight,
Honnêtement dans la liste des modules, la plupart ne sont pas si complexe que ça.  Mon framework actuel les couvrent plus ou moins, mais après pour certains c'est clair que je ne suis pas tout à fait à l'aise... Genre la partie graphique :)

Je vais fork le github et poster mes modules dès ce soir

Lo-x
La plupart de mes modules sont très fortement inspiré du SFML Game Development que tu recommandes.
Par contre, l'EntitySyteme que tu mentionnes sur ton devblog me paraît vraiment bien, et je ne comprends pas pourquoi tu dis que "tu ne referais pas de la même manière" ? Ton EntitySyteme sur Engenesis est-il obsolète ?

En tout n'hésite pas, le but du projet est de réunir un maximum de monde, peu importe la quantité,  c'est surtout la qualité qui est importante et qui fera qu'on sera utilisé,  ensuite les gens soumettront eux-même des améliorations (comme pour SFML) et qui viendront grossir petit à petit le projet :)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 02, 2013, 04:41:13 pm
Ok bah rien ne t'empêche de rajouté tes modules, pas de soucis. :)

Je regarderai tout ça.

PS : j'ai essayé l'équivalent de boost avec c++11 mais mon compilateur ne le prend pas.
Est ce que std::sregex_token_iterator n'a pas encore été implémenté dans ma version actuelle que j'ai de mingw ?

Bref si c'est le cas dans une version futur de toute façon on pourra très bien se passer de boost.
Mais je pense que je vais l'utiliser en attendant que je trouve une version de mingw qui implémente ça.

Je ne sais pas non plus si le c++11 permet de faire l'équivalent de ce que fait boost::any et boost::variant.
Titre: Re : Re : Framework
Posté par: Lo-X le Décembre 02, 2013, 04:46:38 pm
Par contre, l'EntitySyteme que tu mentionnes sur ton devblog me paraît vraiment bien, et je ne comprends pas pourquoi tu dis que "tu ne referais pas de la même manière" ? Ton EntitySyteme sur Engenesis est-il obsolète ?

J'aime beaucoup le principe des entity-system et entity-components, mais :

1) Il faut en avoir besoin, typiquement sur un petit jeu, je pense que c'est se prendre la tête pour rien.
1.bis) Du coup, dans un framework, c'est difficile. Soit tu force l'utilisateur à choisir un ES ou une hiérarchie objet, soit tu trouves un moyen de proposer les deux (j'aimerai trouver cette solution, j'ai jamais eu d'assez bonne idée).
2) ça varie beaucoup d'un programmeur à l'autre (et pour moi même d'un mois à l'autre). Je lis régulièrement des articles dessus, à chaque fois je trouve que la façon de faire est meilleure ou que des choses sont à reprendre

Alors je ne sais plus ce que j'ai utilisé dans Engenesis (et du coup sur mon blog), je sais juste qu'étant donné  le temps qui s'est passé depuis la dernière mise à jour, j'ai du apprendre suffisamment de nouveautés pour ne plus le faire de la même manière.

Le top, dans mes frameworks et peut-être aussi dans celui que tu veux faire, serai d'intégrer un ES avec ce qu'on tire du bouquin, mais en laissant le choix à l'utilisateur de ne pas l'utiliser. (y'a du boulot :p )
Titre: Re : Framework
Posté par: Lolilolight le Décembre 02, 2013, 05:04:27 pm
Citer
Le top, dans mes frameworks et peut-être aussi dans celui que tu veux faire, serai d'intégrer un ES avec ce qu'on tire du bouquin, mais en laissant le choix à l'utilisateur de ne pas l'utiliser. (y'a du boulot :p )

C'est justement ce que je voudrais faire. :P

Laisser le choix à l'utilisateur d'utiliser l'ES du framework ou bien de ne pas l'utiliser. (Car pour les petits jeux utiliser juste SFML est en effet suffisant)

Mais comme tu l'as dis il faut de bonnes idées et il y a du boulot. :P
Titre: Re : Framework
Posté par: Lolilolight le Décembre 02, 2013, 05:57:25 pm
Sinon, je ne sais pas si tu as bien regardé les sources que j'ai mises sur github mais on est pas obligé de passer par l'entité système du framework, pour les plus petits jeux, comme le framework est compatible SFML, on peut dessiner directement des entités SFML de base (des sf::Sprite, des sf::ConvexShape, etc...) sans passer par les classes Entity qui se trouvent dans le module "graphics" du framework. :)

Hors les autres framework comme Irrlicht par exemple pour la 3D, je ne pense pas qu'ils permettent de faire ça.

Mais ici comme le framework se veut être utilisé par le plus de personnes possible, je ne veux rien imposer comme architecture (aussi bien au niveau du développement que au niveau de la 2D et de la 3D), donc on pourra aussi bien l'utiliser pour des jeux en 2D et en 3D, pour des petits jeux ou des jeux plus complexes, etc...
De plus je ne compte pas imposer de système pour remettre à jour les entités avec un thread, mais j'en fournirai peut être un dans le framework déjà fait histoire que l'utilisateur aie un exemple, mais, j'ai envie aussi de laisser le soin à l'utilisateur d'orchestrer tout ça un peu comme il le veut.
Je ne compte donc pas imposer une standardisation dont la plupart n'auront pas besoin et que ça sera finalement trop complexe pour eux à utiliser.

Donc voilà. :)

Par exemple dans le framework rien n'empêchera l'utilisateur de coder sa propre classe light si il a une autre idée, vu que le but est de justement rassembler des idées.
Il devra juste bien sûr redéfinir la fonction draw un peu comme dans les tutoriels de SFML, le framework fonctionne presque exactement comme SFML vu qu'il utilise SFML et n'impose pas d'entity system tout comme SFML.

Il faudra juste hériter des classes transformable et dessinable du framework et non plus de celles de SFML..., car, on ne peut ajouté que des entités du framework au monde, ce qui me semble logique.
Mais encore une fois l'utilisateur pourrait très bien coder son propre conteneur pour stocker ses entités, la classe World et la classe Map du framework sont juste une surcouche offerte par le framework.

Par la suite je compte rajouté d'autres classes que la classe gridMap (une classe quadtree et une classe bsptree) et laissé le choix à l'utilisateur d'utiliser le conteneur qu'il veut.
La classe gridMap est juste un conteneur simple que j'ai utilisé pour mon propre jeux, même chose pour mon système de lumière, pour information je me suis basé sur le moteur de jeux de holyspirit que j'ai amélioré à ma façon pour le fun. :P

Titre: Re : Framework
Posté par: Cmdu76 le Décembre 02, 2013, 09:04:21 pm
Okay c'est bon je suis sur le PC, j'ajoute mes "modules" de suite (enfin je renomme tout d'abord et je les intègre dans le namespace)

Lolilolight,
Tu utilises bien MinGW 4.7.2 ? En tout cas moi c'est celui que j'ai actuellement. Je sais qu'il ne gère pas encore tout le C++11 mais il gère ce que j'utilise pour le moment c'est-à-dire principalement les pointeurs intelligents.

Lo-x,
Oui le top serait de fournir le choix du système. Je pense qu'il faudrait du coup une classe GraphicsSettings qui permettent de choisir entre 2D/3D et aussi de choisir le système d'entités. Après je sais pas si GraphicsSettings est réellement le bon nom car en disant Settings on peut penser aux paramètres que le joueur va choisir lui-même (même si je sais pas si ça fera partit du framework pour le moment...)
La meilleure façon de laisser le développeur choisir est de fournir des classes plus ou moins abstraites que le développeur n'a plus qu'à hériter dans une classe perso et du coup il choisit les entités qu'il veut.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 02, 2013, 09:16:31 pm
Citer
Okay c'est bon je suis sur le PC, j'ajoute mes "modules" de suite (enfin je renomme tout d'abord et je les intègre dans le namespace)

Lolilolight,
Tu utilises bien MinGW 4.7.2 ? En tout cas moi c'est celui que j'ai actuellement. Je sais qu'il ne gère pas encore tout le C++11 mais il gère ce que j'utilise pour le moment c'est-à-dire principalement les pointeurs intelligents.

Non j'utilise mingw 4.8.0 mais j'aimerais bien trouvé une version de mingw plus récente qui gère les regex afin de pouvoir me passer de boost, j'ai essayé de le mettre à jour via l'installeur qu'ils fournissent sur le site de sourceforge pour avoir la version 4.8.1 mais ça n'a pas marché. (Du fait que j'avais oublié de virer mon dossier de mingw avant d'installer le nouveau)

Donc je dois recommencer, je ferai ça demain.

Citer
La meilleure façon de laisser le développeur choisir est de fournir des classes plus ou moins abstraites que le développeur n'a plus qu'à hériter dans une classe perso et du coup il choisit les entités qu'il veut.

Ouais je ne vois pas d'autre façon de faire alors j'ai proposé quelques classes dans le framework dont le développeur pourra hérité et redéfinir quelques fonctions abstraites, il peut ainsi définir ces propres type d'entité grâce à la std::map que j'ai mis dans la classe Entity qui lie un type d'entité et un id pour chaque type d'entité.
D'ailleurs mon composant 'map" ne gère pas un ensemble de type d'entité bien précis, mais n'importe quel type d'entité qui hérite d'une des classes de graphisme de base du framework. (DrawableEntity, DynamicDrawableEntity, TexturedDynamicDrawableEntity, AnimatedEntity et EntityWithShadow si on veut que notre entité aie une ombre)

Mais il n'y aura pas plus d'héritage que ça, après, ce sera au développeur de choisir si il décide d'utiliser un entity système ou pas pour les monstres, les personnages, les armes, etc...

Le framework ne stocke que des entités graphiques, pour les autres type d'entités il n'y a pas vraiment besoin de faire d'optimisation spécifique à l'affichage vu qu'elle ne s'affichage pas.

Mais les classes ne sont pas encore complète vu que cet architecture est récente, dans la classe animation je devrai rajouté une interpolation linéaire pour les transformations sur les différents entités de l'animations.

Je compte aussi ajouté la possibilité de faire des entités animée avec des ombres. :) (Et donc de rajouter autre chose que de simple tiles pour les animations)

Bref j'ai encore du boulot.


Je dois encore aussi faire le chargement des fichiers .obj et l'interpolation linéaire pour les animations, (je compte utiliser les même technique pour la 2D et la 3D pour les animations, les collisions, etc... afin de simplifier l'utilisation du framework un maximum)

Donc en 3D la grille ne sera plus composée de polygônes mais de cubes.

Bref j'ai encore du boulot vu que je dois encore implémenté tout ça mais pour avoir facile je compte me baser sur les même technique que ce que j'ai utilisé pour la 2D et si il y a lieu j'optimiserai après pour la 3D.

Il me faut aussi faire les lampes en 3D, etc...
J'ai séparé tout ce qui concerne la 2D et la 3D dans 2 namespaces différent, tout ce qui concerne la 3D est dans le namespace sfgl::sfgl3f (ou un truc comme ça je sais plus le nom exact du namespace pour la 3D)

Mais je pense que je vais m'inspirer des sources du projet sf3 du forum Anglais.

PS : je crois que je vais aussi ajouté la possibilité de changer la matice de projection dans la classe gridMap pour que on puisse aussi créer des jeux en 2D pure et non en 2D iso.


 
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 02, 2013, 09:49:15 pm
C'est bon la version actuelle de mon framework est commit !

Je dois juste re-vérifier que j'ai pas laissé d'erreurs dans les includes et ajuster toutes les implémentations.

Je vais aussi apporter quelques modifications à la version de mon framework.

Si tu veux voir un peu son fonctionnement, je te conseille https://github.com/Cmdu76/GameTest
car sur la version que j'ai postée tu as vraiment juste le framework. Mon projet GameTest montre les classes que tu dois refaire toi-même.

J'ai dit quelque part que ton projet était brouillon (j'espère que tu l'as pas mal pris :) ), ce que je voulais dire par là, c'est qu'il est très très complets et que je devrais mettre plusieurs jours afin de réellement comprendre tous tes concepts. Ensuite oui si tu utilises MinGW 4.8 tu as donc les pointeurs intelligents que tu n'utilises pas mais ça c'est pas le plus important pour le moment.
Ensuite ce code :

#include <iostream>
#include <SFGL/World/2D/world.h>
#include <SFGL/World/2D/tGround.h>
#include <SFGL/Graphics/2D/tile.h>
#include <SFGL/BoundingAreas/boundingRectangle.h>
using namespace sfgl;
using namespace std;
int main () {
    // création de la fenêtre
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

    //On récupère la vue courrante pour la passer à sfgl plus tard.
    sf::View currentView = window.getView();

    TextureManager &tm = World::getTextureManager();
    Map *currentMap = new Map(100, 50, 30);
    World::addMap(currentMap);
    currentMap->setName("Map test");
    World::setCurrentMap("Map test");

    if (!tm.loadTexture("tilesets/herbe.png"))
        cerr<<"Error : file not found"<<endl;

    Tile *t = new Tile(*tm.getTexture("tilesets/herbe.png"), Vec2f(0, 0), Vec2f(100, 50), sf::IntRect(0, 0, 100, 50), "E_GROUND");

    TileGround *tg = new TileGround(t);
    currentMap->addEntity(tg);

    BoundingRectangle viewRect (0, 0, currentView.getSize().x, currentView.getSize().y);

    currentMap->checkVisibleEntities(viewRect);

    vector<DrawableEntity*> vEntities = currentMap->getVisibleEntities("E_GROUND");

    // on fait tourner le programme tant que la fenêtre n'a pas été fermée
    while (window.isOpen())
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        while (window.pollEvent(event))
        {
            // fermeture de la fenêtre lorsque l'utilisateur le souhaite
            if (event.type == sf::Event::Closed)
                window.close();
        }
 
        // effacement de la fenêtre en noir
        window.clear(sf::Color::Black); /// Ici c'est du détail mais mettre la couleur à Black sert à rien sachant qur c'est la couleur par défaut :)
 
        // c'est ici qu'on dessine tout
        /// Ici on peut utiliser les itérateurs c'est plus otpimisés pour les conteneurs de la stl
        /// Et sinon on pourrait avoir une classe "EntitySystem" comme on en parle qui aurait juste une fonction draw()
        for (unsigned int i = 0; i < vEntities.size(); i++)
            window.draw(*vEntities[i]);
        // fin de la frame courante, affichage de tout ce qu'on a dessiné
        window.display();
    }
    /// Ici je vois pas pourquoi tu utilises cette fonction sachant que le texturemanager est sensé se vider seul ?
    tm.deleteTexture("tilesets/herbe.png");
    return 0;
 
}

me paraît rudement complexe aux premiers abords :)

EDIT : En fait après révision si on retire quelques optimisations en plus de celles que j'ai déjà repérée, et qu'on intègre ce système dans une classe (GameState ou World dans mon framework) on arrive à quelques choses d'un peu plus propre :)

Dans tous les cas, je pense que je vais te laisser t'occuper de la partie graphique :)
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 02, 2013, 11:36:22 pm
Bon c'est bon j'ai fini de mettre mon framework (j'y ai passé un temps fou pour tout mettre dans le namespace et enlever tous les "Cm" que j'avais mis devant les noms de classes...)

Donc faut qu'on fasse un tri je pense maintenant et qu'on réfléchisse à la meilleure architecture pour chaque module.

Afin que l'équipe réfléchisse ensemble, je viens de créer un serveur mumble gratuit (12 slots) :

- Nom : Simple&FastGameLibrary
- Adresse : srv22.mumblegratuit.com
- Port : 11924
- Password : sfgl

EDIT : J'ai failli oublier, pour ceux qui n'ont pas encore Mumble : http://www.mumblegratuit.com/index.php?rub=telecharger_mumble

Bon voilà, après je ne sais pas à quelle heure vous êtes connecté mais dans tous les cas parler de vive voix sera beaucoup plus pratique si l'on veut se mettre d'accord et s'organiser un peu plus correctement :)

(Petite parenthèse : On avait dit qu'un projet sans un minimum de fun ne marcherait pas, et honnêtement sans vocal ça me paraît compliqué :D)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 08:24:59 am
Ouais tu as raison d'ailleurs il y a des développeurs qui utilise mumble donc je suis ok, en plus, j'ai mumble.  :D

Bref il faut que je regarde le fonctionnement de ton framework et que l'ont fasse un tri.

Je vais juste te répondre :

Citer
J'ai dit quelque part que ton projet était brouillon (j'espère que tu l'as pas mal pris :) ), ce que je voulais dire par là, c'est qu'il est très très complets et que je devrais mettre plusieurs jours afin de réellement comprendre tous tes concepts. Ensuite oui si tu utilises MinGW 4.8 tu as donc les pointeurs intelligents que tu n'utilises pas mais ça c'est pas le plus important pour le moment.
Ensuite ce code : me parait complexe aux 1er abords.

C'est sûr que pour afficher juste une tile, ce code est trop complexe, mais je l'ai juste mis histoire d'avoir juste un aperçu de l'utilisation "globale" du framework, mais pour afficher juste une tile, il y a moyen de faire plus simple sans passer par les classe World et Map. :)
Ce qui rend le code moins complexe, et c'est ça l'intérêt du framework.

Ce code est juste à utiliser lorsqu'on veut dessiner pleins de choses, comme par exemple, dans ce cas-ci :

Vector2f v2 (view.getCenter().x - view.getSize().x * 0.5f, view.getCenter().y - view.getSize().y * 0.5f);
    //Rendu des ombres.
    Sprite spriteShadows;
   
    renderTextShadows.setView(view);
    renderTextShadows.clear(Color::White);

    if (day) {

        RectangleShape rect;
        rect.setPosition(Vector2f(v2.x, v2.y));
        rect.setFillColor((Color(100, 100, 100, 128)));
        rect.setSize(Vector2f (view.getSize().x, view.getSize().y));

        vector<Shadow*> visibleShadows = World::getCurrentMap()->getVisibleShadows();

        for (unsigned int i = 0; i < visibleShadows.size(); i++) {
                renderTextShadows.draw(*visibleShadows[i]);
                //draw(*visibleShadows[i]->getShadow());
        }

        renderTextShadows.draw(rect, RenderStates(BlendAdd));
        renderTextShadows.display();
        //draw(rect, RenderStates(BlendAdd));
    }



    //Rendu des lumières.
    renderTextLights.clear(ambientColor);
    if (!day) {

        vector<DrawableEntity*> visibleLights = World::getCurrentMap()->getVisibleEntities("E_LIGHT");

        for (unsigned int i = 0; i < visibleLights.size(); i++) {

            renderTextLights.draw(*visibleLights[i], RenderStates(BlendAdd));
        }
        renderTextLights.display();
    }

    //Rendu de la map. (partie visible à l'écran.)
    clear();
    setView(view);
    vector<DrawableEntity*> visibleTiles = World::getCurrentMap()->getVisibleEntities("E_GROUND+E_DECOR");

    bool shadowRendered = false;

    for (unsigned int i = 0; i < visibleTiles.size(); i++) {

         if (day && !shadowRendered && visibleTiles[i]->getZOrder() >= DEFAULT_SHADOW_Z_ORDER) {
             Sprite shadows (renderTextShadows.getTexture());
             shadows.setPosition(v2.x, v2.y);
             draw (shadows, RenderStates(BlendMultiply));
             shadowRendered = true;
         }
         draw(*visibleTiles[i]);
    }
    if (!day) {
        Sprite lights (renderTextLights.getTexture());
        lights.setPosition(v2.x, v2.y);
        draw (lights, RenderStates(BlendMultiply));
    }
 

Mais ce code est encore un peu brouillon comme tu dis, il faudrait que je définisse une fonction draw dans la classe map et un conteneurs de tiles dans la classe tGround pour dessiner toute la map avec un seul appel à draw. (Ainsi il n'y aura même plus besoin de se soucier des rendertextures. :))
Et on pourra écrire directement :
currentMap->applyView(currentView);
draw(*currentMap)

Donc je pense que je vais modifier ça. :P

Je préfère par contre laisser le soin à l'utilisateur d'utiliser la fonction currentMap->checkVisibleEntities(viewRect) que lorsqu'il en a besoin (par exemple lorsqu'on se déplace dans le monde uniquement) car c'est celle là qui bouffe le plus de perfs.

Bref je vais m'occuper de la partie graphique je pense.  :)

Les pointeurs intelligents pour information je n'ai pas besoin de les utiliser, car, je développe en c++ depuis bien longtemps, j'ai suivis des cours, etc..., on utilisait pas les pointeurs intelligent, on a appris à gérer nous même la mémoire en c++ donc..., je n'ai jamais eu besoin d'utiliser les pointeurs intelligent qui gère la mémoire tout seul.
Donc si on ne les utilise pas c'est moins grave, car, on peut s'en passer.
Je dois juste encore rendre certaines classes non copyable, et voir pour les const et puis bien sûr générer la doc à la fin.
Pour mumble je suis là le soir vers 18h ça me va. (Juste le temps que je regarde tout code)

PS : ha oui je dois aussi faire des classes template pour les vecteur et les matrices pour que l'on puisse aussi travailler avec des int, des double, etc... et pas que des flottants.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 09:53:04 am
Bon j'ai regardé ton code et ça m'a l'air pas mal du tout.  :)

Je pense que je vais reprendre ton système de commande pour lier des actions au player et ton système de gui. :)

Il me faudra juste le temps maintenant pour lier tout ça à mon projet actuel. ^^

PS : et je vais également m'inspirer de ton resourcemanager pour stocker les shaders, les sons, les textures, etc..., car le mien pour le moment ne s'occupe que des textures, il me faut également rajouté une classe pour géré les game-states (qualité des lumières, etc...)







Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 12:12:55 pm
Bon je pense que je vais créer 2 fichiers .cpp et .h (Game et GameStates), pour rendre le code moins brouillons, et ensuite je m'occuperai des GUI et du système de commandes.

PS : il faut juste pas oublié que on doit pouvoir aussi utiliser la renderwindow dans un QWidget. :)
Titre: Re : Framework
Posté par: Lo-X le Décembre 03, 2013, 01:21:19 pm
Si je dis pas de bêtises, sa façon de gérer les événements et les ressources vient tout droit du Livre "SFML Game Develpment", si tu veut plus d'infos dessus je te conseille vraiment de le lire (on y apprend des tas de choses)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 02:12:24 pm
C'est pas comme si je voulais lire ce qu'il y avait dedans, même si il y a des choses intéressante j'avoue, bref, j'ai fait rajouté une classe game qui se chargera de rendre une frame, et une classe gamestates qui contient états du jeux. (Si il faut rendre les ombres ou pas, si il faut rendre les lumières ou pas, la configuration de la renderwindow, etc...)

Ce code sera moins brouillon et il suffira de faire un simple game.render() qui se chargera d'afficher la frame courante du monde. :)

Mais bon c'est assez haut niveau donc, on pourra aussi faire sa propre classe game si on ne veut pas utiliser l'entity system du framework. (A condition de redéfinir la fonction render)

En gros ma classe game correspond à la classe Application.
Titre: Re : Framework
Posté par: Lo-X le Décembre 03, 2013, 02:20:28 pm
Je sais pas si c'est parce que tu vas un peu vite dans tes posts, mais j'ai l'impression que tu mélanges un peu tout.

J'ai pas tout suivi de votre projet, mais avant de commencer à programmer, vous avez fait une liste/schémas/brouillon écrit de ce qu'il y aura et à peu près comment ? Je suis le projet de l'extérieur, mais ça semble aller dans tous les sens du point de vue du spectateur.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 02:42:04 pm
Il me faudrait en effet un shéma brouillon surtout pour l'architecture de base c'est à dire le state, le state manager, l'even handler, etc... en y intégrant mes propres classes du framework.

Car là, j'ai eu le fork de CmdDu76 mais, je n'ai pas vraiment de shéma au niveau de l'architecture donc je m'y perd un peu en effet.

De toute façon on va discuter de ça sur mumble tout à l'heure.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 03:37:22 pm
Bref j'ai pu allégé le code source grâce au code du bouquin
#include <SFGL/utilities.h>
#include <vector>
#include <iostream>
#include <SFGL/World/2D/world.h>
#include <SFGL/World/2D/tGround.h>
#include <SFGL/Graphics/2D/tile.h>
#include <SFGL/BoundingAreas/boundingRectangle.h>
#include <SFGL/Game.h>

using namespace sfgl;
using namespace std;
int main () {
    // création de la fenêtre
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
    //On récupère le gestionnaire de texture et on charge les textures du jeux.
    TextureManager &tm = World::getTextureManager();
    if (!tm.loadTexture("tilesets/herbe.png"))
        cerr<<"Error : file not found"<<endl;
    //Crée une nouvelle carte et l'affecte au monde. (Le monde peut être composé de plusieurs cartes.
    Map *currentMap = new Map(100, 50, 30);
    World::addMap(currentMap);
    currentMap->setName("Map test");
    World::setCurrentMap("Map test");
    //On ajoute créer une tile et on l'ajoute au sol.
    Tile *t = new Tile(*tm.getTexture("tilesets/herbe.png"), Vec2f(0, 0), Vec2f(100, 50), sf::IntRect(0, 0, 100, 50), "E_GROUND");
    TileGround *tg = new TileGround(t);
    //On ajoute le sol à la carte.
    currentMap->addEntity(tg);
    /*On définit le contexte de rendu du jeux en passant les paramètre suivants :
    *(Fenêtre de rendu, qualité des lumières (ici 0 vu qu'on en a pas), si on veut afficher les lumière,
    si on veut afficher les ombres et si on veut afficher la mini carte, on met tout à false ici vu que
    on a pas de lumières ni de bâtiments*/

    Game game (GameStates::Context(window, 0, false, false, false));
    game.update();
    // on fait tourner le programme tant que la fenêtre n'a pas été fermée
    while (window.isOpen())
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        while (window.pollEvent(event))
        {
            // fermeture de la fenêtre lorsque l'utilisateur le souhaite
            if (event.type == sf::Event::Closed)
                window.close();

        }
        //On affiche la frame courante du jeux
        game.render();
        // fin de la frame courante, affichage de tout ce qu'on a dessiné
        window.display();
    }
    //On libère notre texture de la mémoire car on en a plus besoin.
    tm.deleteTexture("tilesets/herbe.png");
    return 0;

}
 
Titre: Re : Framework
Posté par: Lo-X le Décembre 03, 2013, 03:39:50 pm
A terme, ton main contiendra autant de code ?
Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 03:50:16 pm
Non car je ne fais jamais la création d'entités dans le main, je le fais avec un éditeur de carte donc, et je ne crée par non plus la render window dans le main.

Donc à terme, le main ne contiendra que quelques lignes de code.

Ici j'ai effectué tout dans le main pour montrer un exemple de ce qui a déjà été implémenté.
Mais le framework possédera sa propre classe Renderwindow qui pourra être aussi utilisée avec les Widget de QT. :)

Il y aura en plus possibilité de définir un curseur et une icône avec bien sûr, un propre event handler.
Bref en gros c'est ce qu'il me reste à faire au niveau du graphisme avec bien sûr la création de gui 2D IG.

PS : et je dois aussi regrouper tout les headers des différents module dans un fichier .hpp

Titre: Re : Framework
Posté par: Cmdu76 le Décembre 03, 2013, 05:36:53 pm
Lo-x a totalement raison, et au passage oui, mon code est très très fortement inspiré du livre, j'ai modifié juste quelques petites choses par-ci par là pour le rendre vraiment opérationnel en tant que framework alors que le livre ne propose "qu'un usage unique"

Je crois qu'on part un peu mal, on devrait commencer dès ce soir, sur mumble, à choisir vraiment l'architecture de base. Ensuite on pourra ajouter tout ce qui est module plus ou moins élevé.

Donc pour commencer on discute sur la structure donc moi je pense que les States fournit par le livre sont vraiment ce que j'ai vu de mieux comme système de State, car contrairement à bon nombre de système de ce type, tu dessines vraiment tous les States du Stack, et ça c'est vraiment cool parce qu'en plus de pouvoir faire des trucs stylés, l'utilisateur peut aussi choisir vraiment s'il ne veut qu'un State dans le Stack avec les fonctions Clear/Pop

Ensuite, au niveau du main, dans le code final, on ne devrait avoir que genre 5 lignes grand max, le main est l'entrée du programme mais on ne doit rien faire dedans à part instancier notre classe de base.

Sinon oui sur mon fork j'ai pas partagé entre différents modules car faire un module entier pour 3 ou 4 fichiers je trouve ça un peu bête pour le moment, surtout sachant que ça risque de changer dans les prochains jours

Sinon je pensais aussi retravailler sur ma classe Application afin de l'optimiser un petit peu : Héritage direct de sf::RenderWindow et de StateManager et de Player et d'encore quelques classes ... Ducoup je peux supprimer tout ce qui est State::Context, ce qui simplifie pas mal je trouve :)

Enfin bref je go travailler pendant encore 15min et j'arrive sur mumble
Titre: Re : Framework
Posté par: Lolilolight le Décembre 03, 2013, 05:51:02 pm
Ok je suis sur le mumble là pour m'a part j'ai réussi à virer la dépendance de boost mais j'ai encore quelque soucis avec les "states".

Il Faudrait que je m'y fasse mais bon..., ça me fait pas mal pensé à pushGlStates et popGlStates de SFML, c'est un truc du même genre ou pas.

Bref il faudra qu'on discute de ça..., du moment que ce n'est pas une architecture qui s'applique à un jeux de type unique ça me vas.

Il ne vaut pas oublier que pour les commandes, il faudra aussi pouvoir envoyer des commandes en réseau. (Ce qu'il ne fait pas dans le livre)
Genre j'appuie sur une touche j'envoie un message au seveur pour lui dire que le player effectue tel action.

Dans le main il ne devra y avoir que la création du contexte, le définition de quelque paramètre pour le réseau (l'adresse ip, le port, etc...), ainsi que un exec pour démarer la boucle de jeux.
Le chargement des maps devra se faire avec la classe UpsFileManager et le création des cartes, monstres, quête et tout ça, j'utilise un éditeur maison qu'on peut très bien faire facilement avec le framework et QT. :)

Mais je ne mettrai pas encore ce code là dans les exemples car il est encore un peu brouillon. (Même chose pour le code source du module réseau)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 08:49:12 am
Ce soir je vais essayer de poster sur git-hub un diagramme (vite fait) et une liste de tout ce qui a déjà été implémenté, et de tout ce qui reste à implémenter histoire que ça soit plus claire pour les contributeurs.

Par contre je vais le faire un Anglais car je compte créer aussi un thread sur le forum Anglais de SFML.t.

Si j'ai le temps je ferai des tutoriels et un forum temporaire car je n'ai pas le temps de faire le site web pour le moment. (J'ai déjà assez de boulot avec sfgl)
Titre: Re : Re : Framework
Posté par: Lo-X le Décembre 04, 2013, 09:15:05 am
Il ne vaut pas oublier que pour les commandes, il faudra aussi pouvoir envoyer des commandes en réseau. (Ce qu'il ne fait pas dans le livre)
Genre j'appuie sur une touche j'envoie un message au seveur pour lui dire que le player effectue tel action.

Tu n'as pas lu le livre jusqu'au bout alors, parce que c'est expliqué dans la dernière partie, la partie Networking.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 09:48:52 am
Ok.  :)
Titre: Re : Framework
Posté par: Excellium le Décembre 04, 2013, 10:18:18 am
Salut,

Est-ce que je peux éventuellement m'occuper de la partie GUI ?
Je bosse depuis pas mal de temps sur la mienne, j'aurai juste à adapter un peu le code pour la rendre opérationnelle.

PS: Voilà je me suis Mumblelisé  :D
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 10:41:10 am
Salut, bien sûr tu peu t'en occupé si ça te chante. :)

Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 11:56:29 am
Bon, j'ai réussi à virer boost en utilisant de simple fonctions find et substr, étant donné que le compilateur mingw-tdm ne marche pas chez moi je pense que je vais opté pour sfml pour tout ce qui est thread. (Tant pis je ne vais pas m'occuper du c++11 pour l'instant je vais attendre je pense que tout ça soit plus stable)
Sinon je pense que pthread offre aussi la possibilité d'utiliser d'autre primitive de synchronisation que le mutex non ?
Bref là je dois m'absenter, je posterai une liste et un diagramme ce soir.


Titre: Re : Framework
Posté par: Cmdu76 le Décembre 04, 2013, 01:53:19 pm
Salut Excellium,

J'ai une mini-base de Gui mais elle est loin d'être optimisée :)

Ducoup je te laisse travailler sur cette partie si tu veux :)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 03:32:20 pm
Sinon, j'utilise ce code source pour sauvegarder et restaurer des actions dans mon éditeur de map :

#ifndef UPS_ACTION_PARAMETER_H
#define UPS_ACTION_PARAMETER_H
#include "upsActionParameter.h"
#include <boost/any.hpp>
#include <string>
class UpsActionParameter {

    private :
        boost::any value;
        std::string name;

    public :
        UpsActionParameter (boost::any value, std::string name = "UnknowParameter") :
             value (value), name (name) {
                 this->value = value;
        }

        boost::any  getValue () const {
            return value;
        }
        void setValue (boost::any value) {
            this->value = value;
        }


        std::string getName() const {
            return name;
        }
        void setName(std::string name) {
            this->name = name;
        }
        ~UpsActionParameter() {

        }
};


#endif
 



class UpsAction {


    private :
        std::string name;
        bool (*function) (UpsAction &a);
        bool (*contFunction) (UpsAction &a);
        std::vector<UpsActionParameter*> parameters;
        UpsAction& operator= (const UpsAction &p);
        static int nbActions;

    public :

        UpsAction (std::string name, bool (*function) (UpsAction &a),
                   bool (*contFunction) (UpsAction &a));

        template <typename T> bool addParameter (std::string name, T value) {

            UpsActionParameter *p = new UpsActionParameter (value, name);

            for (unsigned int i = 0; i < parameters.size(); i++) {
                if (parameters[i]->getName() == name) {
                    delete p;
                    return false;
                }
            }

            parameters.push_back(p);
            return true;
        }
        template <typename T> bool addParameter (std::string name, T* value) {

            UpsActionParameter *p = new UpsActionParameter (value, name);

            for (unsigned int i = 0; i < parameters.size(); i++) {
                if (parameters[i]->getName() == name) {
                    delete p;
                    return false;
                }
            }

            parameters.push_back(p);
            return true;
        }
        bool removeParameter (std::string name);
        const UpsActionParameter& getParameter (const std::string name) throw (sfgl::Erreur) {
                for (unsigned int i = 0; i < parameters.size(); i++) {
                    if (parameters[i]->getName() == name) {

                        return *parameters[i];
                    }
                }
                throw sfgl::Erreur(5, "No such parameter for this action : " + name, 2);
        }
        template <typename T> void changeParameter (const std::string name, T value) {
            UpsActionParameter& parameter = getParameter(name);
            parameter.setValue(value);
        }
        std::string getName () const;
        void setName (std::string name);
        friend bool addTileAction(UpsAction &a);
        friend bool removeTileAction(UpsAction &a);
        friend bool removeTilesAction (UpsAction &a);
        friend bool addTilesAction (UpsAction &a);
        friend bool addAnimAction (UpsAction &a);
        friend bool removeAnimAction (UpsAction &a);
        friend bool selectTilesAction (UpsAction &a);
        friend bool deselectTilesAction (UpsAction &a);
        friend bool addLightAction (UpsAction &a);
        friend bool removeLightAction (UpsAction &a);
        friend bool setCollisionAction (UpsAction &a);
        bool execute ();
        bool executeContrary ();

        static int getNbActions () {
            return nbActions;
        }
        ~UpsAction () {
            for (unsigned int i = 0; i < parameters.size(); i++) {
                delete parameters[i];
            }
            parameters.clear();
            nbActions--;
        }
};
bool addTileAction(UpsAction &a);
bool removeTileAction(UpsAction &a);
bool removeTilesAction (UpsAction &a);
bool addTilesAction (UpsAction &a);
bool addAnimAction (UpsAction &a);
bool removeAnimAction (UpsAction &a);
bool selectTilesAction (UpsAction &a);
bool deselectTilesAction (UpsAction &a);
bool addLightAction (UpsAction &a);
bool removeLightAction (UpsAction &a);
bool setCollisionAction (UpsAction &a);
#endif

 

Je pense que je vais le réadapter pour sauvegarder et restaurer des states...(Les states pourront avoir n'importe quel type de paramètres et autant de paramètre qu'on veut)

Exactement comme pour les actions dans mon éditeur de map et il y aura un conteneur de states qui servira à sauvegarder et restaurer les states. :P

Il faut juste que je trouve un moyen de virer boost mais je pense qu'un pointeur sur void* devrait faire l'affaire. :P




Titre: Re : Framework
Posté par: Excellium le Décembre 04, 2013, 03:40:05 pm
OK. Je suis sur Mumble, j'attend que quelqu'un se connecte pour poser quelques questions.
Titre: Re : Re : Framework
Posté par: Lo-X le Décembre 04, 2013, 04:29:39 pm
Il faut juste que je trouve un moyen de virer boost mais je pense qu'un pointeur sur void* devrait faire l'affaire. :P

Tu peux pas passer par des templates ? En général on essaie d'éviter d'utiliser du void*
Titre: Re : Framework
Posté par: Laurent le Décembre 04, 2013, 04:37:40 pm
boost::any n'est pas difficile à réimplémenter :

class Holder
{
public:

    virtual std::typeinfo id() const = 0;

    virtual void* get() const = 0;
}

template <typename T>
class HolderImpl
{
public:

    HolderImpl(T value) : m_value(value) {}

    virtual std::typeinfo id() const
    {
        return typeid(T);
    }

    virtual const void* get() const
    {
        return &m_value;
    }

private:

    T m_value;
}

class any
{
public:

    template >typename T>
    void set(T value)
    {
        delete m_holder;
        m_holder = new HolderImpl<T>(value);
    }

    template <typename T>
    T get() const
    {
        if (typeid(T) != m_holder->id())
            throw bad_type;
        return *(const T*)m_holder->get();
    }

private:

    Holder* m_holder;
};

Plus ou moins (et sans les constructeurs / destructeurs / opérateurs = / etc.). Pour les détails cf. le code source de boost.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 05:12:27 pm
Ca, c'est une bonne nouvelle. :)

Ca veut dire qu'il ne me restera plus qu'à implémenter ce système de states et améliorer l'ES du framework.  :) (Car je compte changé quelques petites choses (regrouper quelques classes abstraites, en rajouté quelques unes, etc...)

Je ne vais pas tarder à poster le diagramme et la liste sur gith-hub, j'attend juste que Cmdu se co, je viens de finir la liste pour l'architecture du framework.  :)
Titre: Re : Framework
Posté par: Lo-X le Décembre 04, 2013, 05:34:33 pm
Juste par curiosité, plutôt que de réinventer la roue, pourquoi tu te donnes tant de mal pour ne pas utiliser boost ? C'est super bien boost !
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 05:54:53 pm
Je ne me donne pas de mal surtout que je n'ai besoin que de très peu de fonctionnalités de boost.

Et moins il y a de dépendances plus c'est facile pour moi à gérer car, plus il y a de librairies plus c'est rapide au niveau encodage mais plus c'est galère à installé surtout quand elles ne sont pas toutes compilées avec le même compilateur ou la même version du compilateur.

Toutes les librairies ne sont pas forcément à jour, et, je n'ai pas le temps de m'occuper de la partie c++11 maintenant, donc, je vais d'abord me charger d'ajouter ce qui doit être ajouté et je m'occuperai de résoudre ces problèmes de compilation plus tard, quand les compilateurs seront plus stable et que je n'aurai plus ces problèmes d'incompatibilité à la compilation qui ne sortent je ne sais même pas d'ou. :/
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 07:26:10 pm
Voilà j'ai update en mettant une liste reprenant l'architecture de base du framework. (Je vais la modifier un peu)

Le système de states et le module réseau ne sont pas encore intégré j'attend d'avoir le diagramme complet pour le mettre sur github.

Et ensuite je créerai un thread sur le forum Anglais.
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 04, 2013, 08:03:33 pm
Desolé Excellium j'ai pas pu passer aujourd'hui mais sinon tu peux poser tes questions ici :)

En effet je suis moi aussi pour le fait qu'on arrive à virer boost, moins on repose sur d'autres lib plus c'est simple pour l'utilisateur

Ensuite je vois pas réellement pourquoi tu te galères à retoucher les States, ils marchent déjà très très bien comme ça :)
Après toutes les utilisations que j'ai pu en faire, j'ai pas réellement trouver de moyen de les optimiser

Normalement je t'ai envoyé le diagramme "final" par Skype
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 09:09:53 pm
Si tu peux me renvoyé le diagramme sur skype se serait bien ça n'a pas marché.

Ok, je vais regardé ton système pour les states alors, c'est pas vraiment le fait que je galère c'est juste que sans diagramme j'ai du mal de comprendre donc je pense que je vais imposé aux contributeurs de me fournir un diagramme et une liste résumant leurs idées plutôt qu'un bout de code tiré d'un bouquin ou je dois relire 2-3 fois le code et parcourir une dizaines de fichier pour comprendre l'idée. :/

Mais avec ton diagramme ça ira ne t'inquiètes pas.  ;)

J'ai mis un fichier texte sur github pour l'architecture, je pense que je vais rajouté un générateur pour pouvoir générer des entités aléatoirement et implémenté une fenêtre de rendu personnalisée dans le framework pour le tutoriel, ça allégera le main, ça rendra donc le code moins brouillon et ça fera moins peur à certains. :)

PS : tes states sont très bien certes je n'ai jamais pensé le contraire mais c'est juste que j'aimerais y apporter ma petit touche si ça ne te dérange pas.  :)
Ma façon de faire n'est pas fort différente de ce qu'il y a dans le bouquin.
Mais la chose que j'ai toujours reproché aux bouquin c'est que ça manque souvent d'illustrations, et souvent j'ai du mal de comprendre l'idée. (Je dois relire plusieurs fois le bouquin pour comprendre parfois)
Je tombe aussi souvent parfois sur des tutoriels sur internet ou ce n'est pas assez détaillé, ou bien, le code source n'est pas bon. (Alors j'ai du mal à comprendre l'idée et à modifier le code source)
Bref je ne voudrais pas parler de ce qui qualifie un bon d'un mauvais tutoriel ici, donc, je pense que l'on va revenir au sujet.  :)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 04, 2013, 10:20:48 pm
Ou bien si tu le fork ça, ça me va aussi.

PS : j'ai regardé tes fichiers sources sur github et La fonction draw je ne la mettrai pas dans la classe State par contre, je ne vois pas trop comment on pourrait dessiner un état, moi je mettrai la classe renderwindow dans la classe application et je dessinerai tout avec cette classe.

Sinon pour le reste (popStates, pushStates, etc...), je trouve ça super.





Titre: Re : Framework
Posté par: Cmdu76 le Décembre 05, 2013, 10:44:47 am
Bon okay dessiner un State c'est pas vraiment bien choisi, mais faut plus voir ça comme le fait dessiner tout ce qui représente ce State par exemple le système de Gui, le monde ou n'importe quoi d'autres que l'utilisateur va rajouter  tant qu'objet de son State.

N'hésite pas à aller voir mon projet GameTest sur Github qui justement utilise ce système,  tu vas voir que la fonction draw s'y prête très très bien.

Et je ne comprends pas ce que tu as voulu dire, la classe Application va dessiner juste le StateManager qui dessine ensuite tous les States chargés ça t'évite d'avoir trop d'objets dans l'Application et de pouvoir gérer les States un par un pour l'affichage
Titre: Re : Framework
Posté par: Lolilolight le Décembre 05, 2013, 11:16:31 am
Ha, ok, je comprend mieux ce que tu veux faire maintenant. ^^

Bah moi en fait moi ce que je voulais faire c'est quelque chose comme ceci : (A part que je ne dessine que avec le state courant car je ne vois pas l'intérêt de dessiner plusieurs states, je sais pas, je trouve que ça complique un peu les choses)

void Application::render()  {
Map *currentMap = World::getCurrentMap();
    View view = getContext().window.getView();
    Vector2f v2 (view.getCenter().x - view.getSize().x * 0.5f, view.getCenter().y - view.getSize().y * 0.5f);
    if (getContext().renderShadows) {
        renderTextShadows.setView(view);
        renderTextShadows.clear(Color::White);
        RectangleShape rect;
        rect.setPosition(Vector2f(v2.x, v2.y));
        rect.setFillColor((Color(100, 100, 100, 128)));
        rect.setSize(Vector2f (view.getSize().x, view.getSize().y));

        vector<Shadow*> visibleShadows = currentMap->getVisibleShadows();

        for (unsigned int i = 0; i < visibleShadows.size(); i++) {
                renderTextShadows.draw(*visibleShadows[i]);
        }

        renderTextShadows.draw(rect, RenderStates(BlendAdd));
        renderTextShadows.display();
    }
    if (getContext().renderLights) {
        vector<DrawableEntity*> visibleLights = currentMap->getVisibleEntities("E_LIGHT");

        for (unsigned int i = 0; i < visibleLights.size(); i++) {

            renderTextLights.draw(*visibleLights[i], RenderStates(BlendAdd));
        }
        renderTextLights.display();
    }
    vector<DrawableEntity*> visibleTilesGround = currentMap->getVisibleEntities("E_GROUND");
    for (unsigned int i = 0; i < visibleTilesGround.size(); i++) {
         getContext().window.draw(*visibleTilesGround[i]);
    }
    if (getContext().renderShadows) {
         Sprite shadows (renderTextShadows.getTexture());
         shadows.setPosition(v2.x, v2.y);
         getContext().window.draw (shadows, RenderStates(BlendMultiply));

    }
    vector<DrawableEntity*> visibleTilesDecor = currentMap->getVisibleEntities("E_DECOR");
    for (unsigned int i = 0; i < visibleTilesGround.size(); i++) {
         getContext().window.draw(*visibleTilesGround[i]);
    }
    if (getContext().renderLights) {
        Sprite lights (renderTextLights.getTexture());
        lights.setPosition(v2.x, v2.y);
        getContext().window.draw (lights, RenderStates(BlendMultiply));
    }
}
 

En gros dans la fonction render on récupère le state courant et en fonction des paramètres du state courant, on affiche ce qu'on veut. dans la renderwindow de l'application.  :)
On pourra à tout moment changer le state courant avec pushState et popState du statemanager.

Bref, je ne sais pas pour toi mais moi je trouve ça, plus simple.

PS : ou alors encore plus simple on ne fait qu'un seul state qu'on modifie en fonction de ce qu'on veut chargé, par exemple, le states contient un vector de variable booléennes qui définisse si il faut afficher une gui ou pas.

Bon, maintenant, définir toutes les guis dans la classe application n'est peut être pas top non plus, mais bon..., au final peut être que je vais opter pour ton système avec un state dans lequel on rajoute les guis à dessiner pour ce state.

Ouais non oublie ce que j'ai dis je crois que je vais opter pour ton système.




Titre: Re : Re : Framework
Posté par: Lo-X le Décembre 05, 2013, 11:53:18 am
(A part que je ne dessine que avec le state courant car je ne vois pas l'intérêt de dessiner plusieurs states, je sais pas, je trouve que ça complique un peu les choses)

Alors comment tu fais pour dessiner un menu pause en transparence par dessus ton jeu ?
Comment tu fais dans un jeu en réseau pour que le menu pause n’empêche pas le state du jeu de continuer de tourner ?

Ensuite, c'est pas à Application de connaître World, Map, les entités, et tout le reste à dessiner (car pour un menu par exempe, y'a pas de Map)

Citer
Bon, maintenant, définir toutes les guis dans la classe application n'est peut être pas top non plus, mais bon..., au final peut être que je vais opter pour ton système avec un state dans lequel on rajoute les guis à dessiner pour ce state.

ça c'est une meilleure piste. il suffira de définir un State par état (ce qui semble logique, tiens) et chacun de ces State sait ce qu'il doit contenir (le state MenuPrincipal sait qu'il doit afficher une GUI pour le menu, le state Game sait qu'il faut afficher et faire tourner le jeu [logique, dessin], etc...)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 05, 2013, 12:44:34 pm
Ok, expliqué de cette façon là, je comprend mieux. :)


Titre: Re : Framework
Posté par: Lolilolight le Décembre 05, 2013, 10:35:46 pm
Voila un shéma et une liste des classes ont été ajouté sur github, il ne reste plus qu'à lier nos 2 code sources, pour ma part je vais rajouté aussi la partie réseau.

Une fois ça de fais je pense qu'il serait bon de faire un site web avec quelques tutoriels et sortir une 1ère version stable.

Je ne compte pas implémenter toutes la partie 3D dans la 1ère version par contre. (Car il me faudrait déjà pouvoir faire une version stable pour les jeux en 2D là, en ce moment.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 06, 2013, 10:10:55 am
Bon aujourd'hui je vais essayer de réorganiser les différents modules (je vais regroupé tout ce qu'il y a dans lighting et world et les mettre dans le module graphique)

Et je vais améliorer mon système de resource holder pour qu'il puisse gérer n'importe quel type de ressource (son, texture, font, shader, etc...) et si j'ai encore du temps (si pas je le ferai demain), je vais relier le système de states de Cmdu76 à mon framework.

Titre: Re : Framework
Posté par: Laurent le Décembre 06, 2013, 10:19:32 am
Si je peux me permettre un conseil, vous devriez avant toute chose nettoyer votre dépôt. Le répertoire de build, les fichiers Code::Blocks, les bibliothèques compilées : tout ça n'a rien à y faire.
Titre: Re : Re : Framework
Posté par: Lo-X le Décembre 06, 2013, 10:37:44 am
Si je peux me permettre un conseil, vous devriez avant toute chose nettoyer votre dépôt. Le répertoire de build, les fichiers Code::Blocks, les bibliothèques compilées : tout ça n'a rien à y faire.

Et il serait bien que vous adoptiez une convention de codage, là y'a des choses en français, d'autres en anglais, des conventions différentes pour les attributs, etc...
Titre: Re : Framework
Posté par: Lolilolight le Décembre 06, 2013, 10:47:31 am
Ha oui ça je le savais déjà pour les choses en français et en Anglais, il faut juste que je mette tout en Anglais.

Bref je vais nettoyer tout ça déjà.
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 06, 2013, 02:36:34 pm
Ouais je suis d'accord le dépôt sur github est très mal organisé... Jai ajouté le fichier .gitignore après que tu es ajouté les fichiers "inutiles"
Je pense qu'on pourrait virer tou ce qui est fichiers Cmake tant qu'on sort pas une version "stable"

Ensuite il a pas vraiment besoin de lier nos fichiers, c'est l'utilisateur qui va utiliser nos classes comme il veut nous on propose un "pack" après les utilisateurs en font ce qu'ils veulent
Titre: Re : Framework
Posté par: Lolilolight le Décembre 06, 2013, 03:04:47 pm
J'ai virer les fichiers et dossiers inutiles dans le dossier github sur mon pc mais lorsque je fais un git add, git commit et puis un git pull il ne me les vire pas du repository sur git-hub, comment ça se fait ?
Titre: Re : Framework
Posté par: Lo-X le Décembre 06, 2013, 03:15:18 pm
git rm
Titre: Re : Framework
Posté par: Lolilolight le Décembre 06, 2013, 05:07:03 pm
J'ai retiré les fichiers code::block et le dossier de build avec les lib, je vais aussi retirer les autres fichiers cmake je pense ça sert à rien de les laisser tant que je n'ai pas de version stable.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 06, 2013, 08:03:08 pm
J'ai rajouté un peu aussi la partie réseau (partie client, la partie serveur viendra après je dois juste réorganiser un peu le code source pour ne mettre que la partie commune à tout les jeux) mais il faut avoir openssl d'installé. (Là, c'est obligé d'avoir une lib car les grands nombres et le chiffrement c'est vraiment ce qui a de plus casse tête, encore plus que la 3D et la physique. :/
Et au moins ainsi c'est sûr que se seras sécurisé contrairement à mes propres algorithme qui risquent d'être moins sûr que ceux d'un projet opensource)

Bref demain j'améliore mon système de chargement de ressource et j'essayerai de commencer à tester ce système de state et d'input pour afficher des menus.
Et une première version stable devrait arriver dans +/- un mois le temps de faire le site-web, les tutoriels et de générer la doc avec doxygen.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 06, 2013, 11:04:29 pm
Erf je viens de voir que ça n'a rien remis à jour, bref, je viens de refaire le repository.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 07, 2013, 10:32:41 am
Bon je vais commencer à implémenter le système de resource holder du bouquin ainsi que les states, et, je compte séparer les states en 2 parties :

-Les "GameStates" qui seront les options de rendu du jeux (Le mode vidéo,  les options de rendu (affichage des lumières, ombres, shaders ?) et tout les states qui ne se dessinent pas.
-Les "GuiStates" qui concerneront plutôt l'affichage des menus et des gui IG, la gestion de l'input et des commandes, etc...

Mais il me faut trouvé un compilateur qui supporte le c++11 et le dwarf 2 sinon ça ne compile pas chez moi, le compilateur TDM qui ne gère que le sjlj, ça ne marche pas. :/
Titre: Re : Framework
Posté par: Lolilolight le Décembre 07, 2013, 12:36:33 pm
Bon, j'en ai presque fini avec le resource holder par contre je préfère vraiment gérer les ids via une variable statique pour être sur que les ids se suivent et qu'ils soient vraiment unique. (Encore un truc que j'ai appris à l'école xd)

Je pense que je ne vais pas utiliser le c++11 pour l'instant car les nouveaux compilateurs ne semble pas compatible avec toutes les librairies... (Bref de mon côté le système sjlj me pose problème au niveau de la compatibilité)

Bref les mutex et les thread de sfml devraient faire l'affaire pour l'instant, au pire je me renseignerai sur pthread pour savoir comment utiliser d'autres primitive de synchronisation avec cette librairie.
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 07, 2013, 01:45:30 pm
Je crois que tu n'as pas vraiment compris le but des States, la classe State doit être abstraite, c'est au développeur qui va créer son jeu de la reutiliser comme il le veut. Il peut creer un State qui melange le Monde et des GUI, il peit mettre un State qui est une sprite et des GUi... enfin bref il choisi tout ce qu'il veut au niveau de l'affichage, lui imposer des states speciaux est inutile si tu réduis les possibilités qui sont permises à la base...
Et pour le resource, le système que je t'avais envoyé par Skype avec des enums est plus simple et plus compréhensible pour l'utilisateur car il associe lui même les ID et il peut en faire autant qu'il veut
Titre: Re : Framework
Posté par: Lolilolight le Décembre 07, 2013, 02:17:33 pm
Ok, je vois pour les states, donc en gros tu veux par exemple que je fasse un state qui affiche les lumières, un autre qui n'affiche pas les lumières, etc..., et dessiner celui que je veux.
Ca pourrait en effet être intéressant.

Mais je n'aime pas trop l'idée de pouvoir laisser l'utilisateur mettre ce qu'il veut comme id.

Qu'est ce qui se passerais si l'utilisateur met 2 fois le même id pour 2 ressources différentes ?

Bref, pour moi, chaque id doit être unique à chaque objet et atomique. (c'est à dire composé d'une seule variable (par exemple un char, un int, un long, un short, etc...))

Le but d'un id est justement de désigner un objet de manière unique.

C'est un peu comme un pointeur si tu veux à l'exception que l'id ne référence pas une adresse mémoire unique, mais c'est juste un nombre (comme l'indice d'un tableau par exemple) qui permet de référencer un objet unique dans un ensemble d'objets.

MySQL utilise se système d'ailleurs, pourquoi ne pas le réutiliser ici ?

De plus je trouve ça vraiment plus pratique pour faire des références à des objets grâces à des int dans un fichier ou une base de donnée que de le faire avec n'importe quel type d'id qui pourrait référencer plusieurs objets et compliquer ainsi les choses.
Bref moi on m'a toujours conseillé de travailler avec un id unique pour chaque objet créer avec une classe, ou bien avec un système de gestion de base de données, ou bien avec n'importe quel autre système.


#ifndef RESOURCEMANAGER_HPP_INCLUDED
#define RESOURCEMANAGER_HPP_INCLUDED

#include <map>
#include <string>
#include <memory>
#include <stdexcept>
#include <cassert>

namespace sfgl
{


template<typename R> class ResourceManager
{
        public:
                void            load(const std::string& filename);
                R                       getByPath(const std::string& path) const;
                R                       getById(const int id) const;
                void        deleteResource (const std::string &path);
        private:
                struct Resource {
                Resource (std::string path, R* resource) {
                    this->path = path;
                    this->resource = resource;
                }
                ~Resource() {
                    delete resource;
                    nbResources--;
                }
                R resource;
                std::string path;
                int id;
            };
                void insertResource(const std::string &path, R* resource);
                void updateIds(const int &id);
                static int nbResources;
        std::map<int, Resource*>        mResourceMap;
};

///////////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION                                                            //
///////////////////////////////////////////////////////////////////////////////
template <typename R> int ResourceManager<R>::nbResources = 0;
template <typename R>
void ResourceManager<R>::load(const std::string& filename)
{
        // Create and load resource
        R* resource(new R());
        if (!resource->loadFromFile(filename))
                throw Erreur(6, "ResourceManager::load - Failed to load ",0);
        // If loading successful, insert resource to map
        insertResource(resource);
}

template <typename R>
R ResourceManager<R>::getById(int id) const
{
        Resource &found = *mResourceMap.find(id);
        if(found == mResourceMap.end())
        return nullptr;
        return found->second.resource;
}

template <typename R>
R ResourceManager<R>::getByPath(const std::string &path) const
{
    typename std::map<int, Resource*>::iterator it;
    for (it = mResourceMap.begin(); it != mResourceMap.end(); it++) {
        if (it->second.path == path)
            return it->second.resource;
    }
        return nullptr;
}

template <typename R>
void ResourceManager<R>::insertResource(const std::string &path, R* resource)
{
        // Insert and check success
        Resource* r = new Resource (path, resource);
    mResourceMap.insert(std::make_pair(nbResources, r));
}
template <typename R> void ResourceManager<R>::updateIds (const int &id) {
    typename std::map<int, Resource*>::iterator it;
    for (it = mResourceMap.begin(); it != mResourceMap.end(); it++) {
        if (it->first > id) {
            it->first--;
        }
    }
}
template <typename R> void ResourceManager<R>::deleteResource(const std::string &path) {
    typename std::map<int, Resource*>::iterator it;
    for (it = mResourceMap.begin(); it != mResourceMap.end();) {
        if (it->second.path == path) {
            updateIds(it->first);
            delete it->second;
            mResourceMap.erase(it);
        } else
            it++;
    }
}
}

////////////////

namespace sf
{
    class Texture;
    class Font;
    class Shader;
    class SoundBuffer;
}

namespace sfgl
{

typedef ResourceManager<const sf::Texture*>      TextureManager;
typedef ResourceManager<const sf::Font*>         FontManager;
typedef ResourceManager<const sf::Shader*>       ShaderManager;
typedef ResourceManager<const sf::SoundBuffer*>  SoundBufferManager;

}


#endif // RESOURCEMANAGER_HPP_INCLUDED
 

Par contre faudrait que je revois un peu la redéfinition de template si je veux que R soit absolument un pointeur constant. (Vu que il faudrait éviter de modifier les ressources via le CPU)

J'ai essayer de redéfinir R en const R* pour toutes les fonctions cependant, j'ai une erreur à la compilation comme quoi il me dit qu'il ne peut pas convertir const Texture const* en const Texture* lorsque j'utilise un get.
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 07, 2013, 02:31:30 pm
Nan c'est pas dutout ce que je voulais dire, justement même tout le contraire !
Finalement on crée un State qui ne dessine RIEN, c'est l'utilisateur qui va choisir ce que son State va dessiner en créant par exemple une classe GameState (qui PAR EXEMPLE peut dessiner le monde + des GUI + des sprites banales (ce qui est presque inutile mais c'est pour montrer que c'est lui qui choisi))

Ensuite dans un enum, chaque entrée est associé à une valeur unique donc on a pas le problème de l'avoir deux fois...
Titre: Re : Framework
Posté par: Lolilolight le Décembre 07, 2013, 02:49:17 pm
Oui, mais une enum ça sert plutôt pour le développeur ça, pour définir un ensemble restreins de valeurs possibles que peut prendre une variable.

Je ne vois pas comment on pourrait utiliser ça pour créer des ids.

Surtout que, les ids ne sont pas prédéfini à l'avance contrairement aux valeurs des l'enums.

Le développeur peut créer autant d'objets qu'il veut. (Et avec ton idée il faudrait donc, rajouté des valeurs dans l'enum à chaque fois que le développeur va recréer un nouvel objet)

Bref, je trouve pas ça si bien personnellement ou alors je n'ai pas très bien compris ce que tu veux faire.

En tout cas moi, je crée un objet, il a l'id 0, j'en recrée un deuxième, il a l'id 1, et ainsi de suite..., et lorsque j'en supprime un, bah tout ceux qui ont un id plus élevé que lui voient leur id diminué de 1. (Ainsi j'ai toujours des id qui se suivent pour tout les objets que j'ai créer et je me retrouve pas 2 fois avec le même id)

Je doute fort qu'on sache faire ça avec des enums ou alors faudrait vraiment que tu me montre un exemple de code source qui le fait parce que là je ne te suis vraiment pas. :o
Titre: Re : Framework
Posté par: Cmdu76 le Décembre 07, 2013, 03:07:54 pm
Le problème est que du coup peut etre que les id sont bien ordonnes (mais au final avec les enmus c'est pas si important)
mais après il fait récuperer l'id et le ressortir a chaque fois...

Par contre je pense que ducoup le getByPath peut être une solution

Aussi tant qu'à faire,

R get(const std::string& path) const;
R get(const int id) const;

C'est plus simple comme ça et ça ne perd pas son sens dans la doc

Et du coup je parlais de retourner l'id, donc tant quà faire :

/// \return The id of the loaded resource
int load(const std::string& filename);

Sinon comment moi (enfin je tire ça du livre SFML une fois de plus) je procède :

- L'utilisateur crée un fichier "ResourceIdentifiers.hpp" dedans il crée le namespace Textures avec l'enum en question contenant une entrée avec une valeur pour chaque texture qu'il voudrait utiliser.
- Ensuite dans la classe Application, tu donnes en paramètres de load(Textures::ID id, std::string const& filename);
- Du coup quand tu veux utiliser la texture ailleurs, tu as juste à faire : get(Textures::ID id);

Oui, mais une enum ça sert plutôt pour le développeur ça, pour définir un ensemble restreins de valeurs possibles que peut prendre une variable.

Du coup, dans mon exemple tu limites tes valeurs aux ID que tu veux.

Ainsi j'ai toujours des id qui se suivent pour tout les objets que j'ai créer et je me retrouve pas 2 fois avec le même id

Je ne vois pas en quoi le fait d'avoir des id qui ne se suivent pas est gênant...
Et moi non plus je ne peux pas me retrouver avec deux fois la même ID, mon Id (mon Id corresponds à une case un tableau basique ( monVector[ID] ) ) sera juste redéfinie avec le 2ème fichier que je donne.

Encore une fois pour les exemples, n'hésite pas à aller voir le livre SFML ou à checker mon projet GameTest sur GitHub : https://github.com/Cmdu76/GameTest
Titre: Re : Framework
Posté par: Lolilolight le Décembre 07, 2013, 05:20:43 pm
Bof, je ne suis pas fan du système qu'il y a dans le livre, je trouve que ça complique bien les choses surtout que mon système permet de faire exactement la même chose mais en plus simple! (Sans devoir recréer un fichier ResourceIdentifiers.hpp et tout ce bazar auquel je n'y comprend absolument rien)

Mais comme tu dis je pourrai très bien rajouter des méthodes :

R get(const int id) const;
/// \return The id of the loaded resource
int load(const std::string& filename);
 

Je compte d'ailleurs le faire par la suite, ainsi on pourra récupérer la ressource, soit suivant sont path, ou bien avec son id, ou bien même retourner l'id d'une resource à partir de son path ou bien à partir de la ressource elle même, ou bien charger plusieurs ressources d'un coup.
Bref, ça, ce sera comme lui le développeur le veux, tout ce que je veux c'est proposer des classes qui offrent le maximum de possibilités de manière la plus simple qui soit.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 08, 2013, 12:37:53 pm
Voilà j'ai fini d'améliorer la classe qui gère les ressources.

Demain je commencerai à faire le système de states et de gui, et ensuite, je commencerai à faire les tutoriels pour tester tout ça et le forum sur des sites temporaire afin de sortir une première version stable. (En attendant d'avoir mon propre site web)

Car je n'ai pas le temps de m'occuper du site web de SFGL pour l'instant.


Titre: Re : Framework
Posté par: Lo-X le Décembre 08, 2013, 01:38:09 pm
Le soucis de l'enum c'est que c'est contraignant, cepandant il permet plus de modularité que les autres, je m'explique :

Gérer les ressources uniquement en fonction du filepath, c'est le plus simple pour l'utilisateur, mais ça peut devenir très embêtant. En effet, si soudainement notre texture de vaisseau utilisée par 10 classes dans le jeu vient à changer de nom, il faut changer ça en 10 endroits du code. Avec un Texture::ID il ne faut le faire qu'à un seul endroit

Avoir des IDs imposés pour l'utilisateur ça rime à rien, en effet il faut qu'il retienne quelque part que l'ID retourné c'est telle texture, donc il doit faire le boulot des ResourceHolder au final.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 08, 2013, 02:42:24 pm
Oui le but du ressource holder c'est justement ça : si on change le path de la texture, on n'a qu'à le changer à un endroit dans le code et pas a 10 endroits différents si plusieurs entités utilisent la même texture. (Ce qui peut bien sûr arriver)

Et l'utilisateur n'est pas obligé de retenir l'id de la texture, l'id de la texture me sert juste à lier une texture à une entité dans le fichier de sauvegarde du monde. (Donc si il sait ou la texture se trouve c'est suffisant, il n'uara qu'à faire un getResource(path) pour la récupérer, il n'a pas besoin de retenir l'id)

Si le path de la texture change, il n'a qu'à le changer lors de l'appel à la fonction load du resource holder..., donc, il n'y a pas vraiment besoin que l'utilisateur puisse créer ses propres id pour faire ça.

Maintenant si tu veux faire un alias vers l'id de la texture pour la récupérer d'une autre manière que de part son id ou son path, cela revient à recréer son propre resource holder en effet...
Mais personnellement je n'en vois pas trop l'intérêt, le chemin relatif vers la texture est suffisant.

A la limite je pourrai toujours rajouté plus tard la possibilité au développeur de créer un alias vers le path de la texture, mais, pour le moment, ce n'est pas ma priorité.

PS : Et si il veut récupérer l'id de la texture il n'a qu'à appeler la fonction getId(path) du resource holder et garder l'id de la texture en mémoire un peu comme le fait opengl avec ses fonctions pour créer des textures, des shaders, ou n'importe quoi.
PS 2 : et de toute façon dans mon framework, je n'utilise le path qu'à un seul endroit, c'est au chargement de la texture ensuite je garde l'id de la texture en mémoire, (ou le path peut importe) et puis, je passe un pointeurs sur la texture à mon entité.

string pathToTexture = "PathToTexture";
holder.load(pathToTexture);
int id = holder.getId(pathToTexture);
Entity entite = new Entity(holder.getResource(id), position, size, origin, type);
 

Ou bien :
string pathToTexture = "PathToTexture";
holder.load(pathToTexture);
Entity entite = new Entity(holder.getResource(pathToTexture), position, size, origin, type);
 

Donc voilà si je change le path il n'y a qu'à changer la 1ère ligne de code.

Maintenant bien sûr il ne faut pas faire ça :
holder.load("PathToTexture");
Entity entite = new Entity(holder.getResource("PathToTexture"), position, size, origin, type);
 
Sinon là il faudra changer le code source à 2 endroits.
Mais je préfère laisser le soin au développeur de gérer lui même ses variables pour le stockage des id ou path vers les textures dans le programme ou bien dans un fichier.

Donc pour répondre à ta question, si il veut utiliser autre chose comme identifiant (une enum par exemple) il faudra en effet qu'il recrée son propre ressource holder.

Mais je pense pas que ça soit nécessaire de le faire, en tout cas moi dans le projet Sorrok je n'ai pas eu besoin de le faire.
Sinon, comment tu ferais si le développeur a envie de sauver les paths de textures ou les id de texture dans un fichiers ???
(Chose que je fais avec le projet Sorrok)

Titre: Re : Framework
Posté par: Lolilolight le Décembre 08, 2013, 06:15:42 pm
Bien que ce n'est pas très compliqué à faire et je crois que je vais d'ailleurs le faire, mais pas vraiment besoin d'utiliser une enum pour faire ça, un string suffit, il faut juste que je m'arrange pour que l'alias soit unique pour chaque texture :

holder.load("pathToTexture", "AliasToTexture");
Texture *t = holder.getResource("AliasToTexture");
 

Je pense que j'ai enfin compris ce que tu veux as voulu me dire.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 08, 2013, 10:09:54 pm
Bon voilà c'est fait j'ai rajouté un alias pour chaque texture, j'essaye de mettre ça sur git hub bah, dès que ce git commit et ce git push marcheront...

Soit je vais finir la 1ère version du framework je pense (en me basant sur le système de state, gui et command de Cmdu76.

Et ensuite, je mettrai tout d'un coup sur github. (Une fois que j'aurai testé tout ça)

Et enfin je ferai les tutoriels et la doc.

Ca devrait me prendre +/- 1 mois...

Titre: Re : Framework
Posté par: Lolilolight le Décembre 09, 2013, 05:00:47 pm
Salut, je pensais faire un conteneur dans la classe Application ou j'ajouterai tout les ressources holder.


TextureManager tm;
FontManager fm;
SoundManager sm;
Application::addResourceManager(TextureManager, "TextureManager");
Application::addResourceManager(FontManager, "FontManager");
Application::addResourceManager(SoundManager, "SoundManager");
 

Cependant étant donné que ma classe ResourceManager est template, je peux pas le faire, car, je peux pas faire ceci :
template <typename R> std::map<std::string, ResourceManager <R> > resourceManagers;
 

Bref je ne vois pas d'autre moyen que de le faire en utilisant un code source du genre boost::any.

template <typename R> std::map<std::string, any> resourceManagers;
 

Surtout que chaque resource holder devrait être unique à l'application.

J'ai pensé à faire une classe super classe mais cela na marche pas non plus car si je fais des fonctions template virtuelle le compilateur n'est pas content.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 10, 2013, 06:08:37 pm
Bon j'ai enfin réussi à compiler et à tester le système de resource holder et ça semble fonctionner! :D

//#include <SFGL/utilities.h>
#include <vector>
#include <iostream>
#include "SFGL/Core/game.h"
#include "SFGL/Core/ResourceManager.h"*/
#include <SFML/Graphics.hpp>
#include "SFGL/Graphics/2D/tile.h"
using namespace sfgl;
using namespace sf;
int main () {
    TextureManager tm;
    tm.load("tilesets/herbe.png", "HERBE");
    Tile *t = new Tile(tm.getResourceByAlias("HERBE"), Vec2f(0, 0), Vec2f(100, 50),IntRect(0, 0, 100, 50), 0);
    // create the window
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

    // run the program as long as the window is open
    while (window.isOpen())
    {
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }

        // clear the window with black color
        window.clear(sf::Color::Black);

        // draw everything here...
        window.draw(*t);

        // end the current frame
        window.display();
    }
    delete t;
    tm.deleteResourceByAlias("HERBE");
}
 

Bref ceci n'est qu'un test, plus tard il faudra redéfinir les méthodes init, update et render de la classe application ceci afin de réduire le nombres de lignes de code dans le main.

La méthode init : c'est dans cette méthode qu'il faudra faire tout chargement de ressources, le chargement de la map, etc.... (que ça soit à partir d'un serveur ou bien de la machine locale)

La méthode update (c'est là dedans qu'il faudra remettre à jour la frame courante pour le rendu, traiter les évènement, etc...)

La méthode render (c'est là dedans qu'il faudra afficher les states courants)

A terme le main ressemblera donc à ceci :

int main () {
     Application app;
     return app.exec();
}
 
C'est dans la méthode exec que je compte appeler les méthodes init, update et render. (Je sais je m'inspire un peu de QT mais je trouve ça vraiment pas mal.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 11, 2013, 03:40:49 pm
Sinon, je ne comprends pas pourquoi on devrait éviter d'utiliser des pointeurs sur void*, car, je trouve ceci beaucoup plus pratique que d'utiliser un any.get<Type>() :

#ifndef APPLICATION
#define APPLICATION
#include "stateManager.h"
#include "resourceManager.h"
namespace sfgl {
class Application {
public :
    Application(sf::RenderWindow &window) : window(window) {
        app = this;
    }
    template <typename R> void addResourceManager (ResourceManager<R>& rmi, std::string name);
    template <typename R> ResourceManager<R>& resourceManager(std::string name);
    virtual void load () = 0;
    virtual void render () = 0;
    sf::RenderWindow& getWindow() {
        return window;
    }
    void addClock(sf::Clock clock, std::string name)  {
        std::map<std::string, sf::Clock>::iterator it = clocks.find(name);
        if (it != clocks.end())
            throw Erreur (13, "This clock already exist!", 0);
        clocks.insert(std::make_pair(name, clock));
    }
    sf::Clock getClock(std::string name) {
        std::map<std::string, sf::Clock>::iterator it = clocks.find(name);
        if (it == clocks.end())
            throw Erreur (14, "Clock not found!", 0);
        return it->second;
    }
    StateManager& getStateManager() {
        return stm;
    }
    static Application *app;
private :
    StateManager stm;
    sf::RenderWindow &window;
    std::map<std::string, sf::Clock> clocks;
    std::map<std::string, ResourceManager<void*>&> resourceManagers;
};
template <typename R>
void Application::addResourceManager(ResourceManager<R>& rmi, std::string name) {
    std::map<std::string, ResourceManager<void*>&>::iterator it = resourceManagers.find(name);
    if (it != resourceManagers.end())
        throw Erreur (11, "Resource manager already added!", 0);
    resourceManagers.insert(std::make_pair(name, rmi));
}
template <typename R>
ResourceManager<R>& Application::resourceManager(std::string name) {
    typename std::map<std::string, ResourceManager<void*>&>::iterator it = resourceManagers.find(name);
    if (it == resourceManagers.end())
        throw Erreur (12, "Resource manager not found!", 0);
    return reinterpret_cast<ResourceManager<R>&>(it->second);
}
Application* Application::app = nullptr;
}
#endif // APPLICATION
 

Ce qui me donne au final comme code :

#ifndef MY_APPLI
#define MY_APPLI
#include "SFGL/Core/application.h"
#include <SFML/Graphics.hpp>
#include "SFGL/Graphics/2D/tile.h"
using namespace sfgl;
using namespace sf;
class MyAppli : public Application {
    public :
    MyAppli(sf::RenderWindow &window) : Application (window) {
        TextureManager tm;
        addResourceManager<Texture>(tm, "TextureManager");
    }
    void load() {
        TextureManager &tm =  resourceManager<Texture>("TextureManager");
        tm.load("tilesets/herbe.png", "HERBE");
    }
    void render() {
        TextureManager &tm =  resourceManager<Texture>("TextureManager");
        Tile *t = new Tile(tm.getResourceByAlias("HERBE"), Vec2f(0, 0), Vec2f(100, 50),IntRect(0, 0, 100, 50), 0);
        while (getWindow().isOpen())
        {
        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (getWindow().pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                getWindow().close();
        }

        // clear the window with black color
        getWindow().clear(sf::Color::Black);

        // draw everything here...
        getWindow().draw(*t);

        // end the current frame
        getWindow().display();
        }
        delete t;
        tm.deleteResourceByAlias("HERBE");
    }
    ~MyAppli() {

    }

};
#endif // MY_APPLI
 

#include <vector>
#include <iostream>
#include <SFML/Graphics.hpp>
#include "myApplication.h"
using namespace sf;
int main () {
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
    MyAppli app(window);
    app.load();
    app.render();

}
 

C'est déjà plus court comme main.  :)

Bref, je suis presque arrivé à terme il ne me reste plus que les classes Cursor, Player, Icon et sfgl::renderWindow à implémenter.

Et ensuite je commencer les tutoriels.  :D
Pour les tutoriels je pense que je vais faire un système de génération de monde aléatoire se sera le plus simple.

Le développeur pourra rendre différents states (les states décriront les états du jeux à un moment donné (menus, monde, ressources à charger, options du jeux, etc...)), on pourra basculer d'un state à l'autre via le statemanager de la classe application.

Ceci permettra de revenir à un menu du jeux par exemple sans devoir tout recharger à la main.

Il faudra hériter et redéfinir certains méthode dans les classes states et application car celles-ci sont abstraites :

States :

reload : rechargement des textures du state. (des menus par exemple)
init : recréation des guis des menus par exemple.
draw : affichage du monde en fonction des options de rendu, des menus correspondant à l'état du jeux, etc...
update : mise à jour de l'état des states en fonction du temps.

Application :

load : chargement des ressources de départ.
init : création du monde.
render : rendu du monde.
update : c'est là dedans que le développeur mettra à jour les states et autres objets du framework en fonction des évènements d'entrée.

Voilà je pense que ça ira comme ça au niveau architecture.






Titre: Re : Framework
Posté par: Nexus le Décembre 11, 2013, 03:47:48 pm
Quelques idées:
Tu peux aussi regarder comme j'ai resolu quelques problems avec la gestion de resources en Thor (tutoriel (http://www.bromeon.ch/libraries/thor/v2.0/tutorial-resources.html), documentation (http://www.bromeon.ch/libraries/thor/v2.0/doc/group___resources.html)). C'est un peu plus compliqué que ce que tu veux faire, mais ça peut quand même aider. Par exemple, thor::MultiResourceCache est capable de mémorizer plusieurs types de resources -- sans void* ou boost::any. Le principle s'appelle "type erasure".
Titre: Re : Framework
Posté par: Lolilolight le Décembre 11, 2013, 04:16:08 pm
Merci pour ses idées, je pense que je vais :

-Libérer les ressources automatiquement à la fin.
-Utiliser une enum plutôt qu'un string.
-Regarder ton système de type erasure.
Titre: Re : Framework
Posté par: Lo-X le Décembre 11, 2013, 05:09:33 pm
Si tu ne veux pas utiliser les enums parce que ça force l'utilisateur a en remplir un et de le situer à un endroit précis et imposé dans le code (ce que je peux comprendre), le système des "Key" de Thor est vraiment très très bien (un peu compliqué à implémenter, mais très pratique par la suite)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 11, 2013, 05:42:33 pm
Ton code utilise les std::function du c++11 non ?

Si j'ai bien compris tu stockes les fonctions qui chargent la ressource et celles qui récupèrent les ressources dans une classe.

Moi aussi je faisais comme ça avant avec mon éditeur de map :
Je stockais une fonction qui effectuait une action et l'autre qui la déseffectuait. (Histoire de pouvoir faire les actions annuler/rétablir)

Mais j'ai arrêté car il y a un inconvénient :

-Pour chaque fonctions rajoutées, il faut redéfinir un nouveau pointeur de fonction, en plus de redéfinir la fonction. (Dans ton cas il n'y a que la fonction load (et search) donc ça va encore, ça  ne fait qu'un seul pointeur de fonction à redéfinir, mais, pas dans des cas ou l'on utilise pleins de fonctions différentes avec un nombre d'arguments différents comme c'est le cas dans mon éditeur de map.

Hors que avec mon système, il suffit juste de rajouter la fonction dans mon "resource holder".
Plutôt que de devoir passer par 36 000 classes pour avoir au final pleins de fonctions avec le même type de retour et le même nombre d'arguments. (Ca, c'est comme je faisais avant)

-Dans ton cas la ressource se détruit si plus rien ne la référence si j'ai bien compris le système des shared pointeurs. (Donc, lorsque la clé qui contient le shared pointeur est détruite vu que je vois que tu n'utilise aucune collection pour stocker la clé dans ta classe multicache.)

Bref c'est chouette, c'est plus sûr et on ne risque pas d’accéder à une ressource qui n'existe plus mais ce n'est pas vraiment nécessaire avec le principe RAII comme tu dis :
J'ai toujours appris à programmer sans utiliser des shared pointeurs et en gérant la mémoire moi même. (car les shared pointeurs ont plusieurs défaut : on ne peut pas les utiliser dans une classe copiable, notamment, et ni dans un vector, un array, etc...)
De ce fait j'ai toujours opté pour le système qui se rapproche de java : ArrayList maList<?> ou le ? réprésente n'importe quel type tout comme le pointeur sur void du c++.

Mais ça, c'est juste une question de goût.

De plus j'ai vu que tu utilises les shared pointeurs et unique pointeurs du c++11, qui me pose certains problèmes de compatibilité suivants les différents compilateurs. (Bon au départ je pensais utiliser le c++11 mais dès que j'ai eu des problèmes d'incompatibilités entre les versions 64 bits et 32 bits de compitateurs dont certains implémentaient déjà les nouvelles fonctionnalités du c++11 et d'autres pas)

Je me suis dis, autant en revenir à la méthode plus ancienne. (Moi sûr mais qui fonctionne aussi bien que la nouvelle méthode pour autant qu'on la maîtrise)

Pour les identifieurs, je ne suis pas pour non plus, car, je trouve ça chiant de devoir déclarer un identifiant dans le code source pour chaque ressource, je préfère récupérer mes ressources via une variable constante. (une chaine de caractère constante)

Si il se trompe dans le nom de l'alias certes ça plantera à l'exécution, mais au pire y'a la fonction rechercher/remplacer je pense que ça ira plus vite que de devoir déclarer tous pleins de variables de type key ou autre pour récupérer une texture.

Sinon je me demande si en c++ il y a moyen de lancer une exception à la compilation, ça, je trouve ça dommage que les compilateurs ne permettent pas de le faire. :/

Titre: Re : Framework
Posté par: Lolilolight le Décembre 11, 2013, 05:59:13 pm
Et au sujet des variables statique et globales, elles sont pratiques dans certains cas. (pour certains type d'objets qui ne peuvent être qu'unique)

PS : et puis, si c'est pour refaire un système comme thor, autant réutiliser thor. (Je pensais l'utiliser avec SFGL mais, ce n'est pas vraiment mon but au final)
Titre: Re : Framework
Posté par: Excellium le Décembre 11, 2013, 06:17:36 pm
Citer
Sinon je me demande si en c++ il y a moyen de lancer une exception à la compilation, ça, je trouve ça dommage que les compilateurs ne permettent pas de le faire. :/

tu peux utiliser assert, non ?
Titre: Re : Framework
Posté par: Lolilolight le Décembre 11, 2013, 06:41:28 pm
Ha oui il faut juste que je regarde comment ça fonctionne, mais sinon, oui je pense que je vais utiliser ça! :P
Titre: Re : Re : Framework
Posté par: Nexus le Décembre 11, 2013, 07:44:52 pm
Ton code utilise les std::function du c++11 non ?
Oui. Mais il y a std::tr1::function depuis le TR1 (2005).

Pour chaque fonctions rajoutées, il faut redéfinir un nouveau pointeur de fonction, en plus de redéfinir la fonction.
Tu parles de quelles fonctions et pointeurs ? Il faut seulement en définir si les clés (thor::ResourceKey) existantes ne suffisent pas.

-Dans ton cas la ressource se détruit si plus rien ne la référence si j'ai bien compris le système des shared pointeurs.
Il y a deux strategies : L'un est comme tu dis, l'autre garde les ressources jusqu'à ce que tu les enlève (ou le cache et le dernier shared_ptr se détruisent).

Bref c'est chouette, c'est plus sûr et on ne risque pas d’accéder à une ressource qui n'existe plus mais ce n'est pas vraiment nécessaire avec le principe RAII comme tu dis :
J'ai toujours appris à programmer sans utiliser des shared pointeurs et en gérant la mémoire moi même.
Tu as raison, mon système de ressources est plutôt compliqué, pour la plupart de cas un approche plus simple suffit.

(car les shared pointeurs ont plusieurs défaut : on ne peut pas les utiliser dans une classe copiable, notamment, et ni dans un vector, un array, etc...)
Ce n'est pas 100% vrai : Tu peux les utiliser dans des classes copiables et dans des containers, mais il faut savoir que l'objet référencé n'est pas copié.

Si tu veux que le pointeur copie aussi l'objét, tu peux utiliser aurora::CopiedPtr (http://www.bromeon.ch/libraries/aurora/v1.0/tutorial-smartptr.html), une autre classe que j'ai développée.

De ce fait j'ai toujours opté pour le système qui se rapproche de java : ArrayList maList<?> ou le ? réprésente n'importe quel type tout comme le pointeur sur void du c++.
void* n'est pas "typage-sûr", tu ne sais pas ce qui se cache derrière. Et tu ne peux rien faire sans savoir. C'est à cause de ça qu'il y a des téchniques très elegantes, comme type erasure.

De plus j'ai vu que tu utilises les shared pointeurs et unique pointeurs du c++11, qui me pose certains problèmes de compatibilité suivants les différents compilateurs.
Il y a std::tr1::shared_ptr qui existe depuis 2005, et std::auto_ptr depuis 1998. Malgré qu'il faut être prudent en utilisant auto_ptr, c'est beaucoup mieux que gérér la mêmoire manuellement. En plus, une petite classe smart-pointeur comme boost::scoped_ptr est écrit dans une quart d'heure.

Si il se trompe dans le nom de l'alias certes ça plantera à l'exécution, mais au pire y'a la fonction rechercher/remplacer je pense que ça ira plus vite que de devoir déclarer tous pleins de variables de type key ou autre pour récupérer une texture.
Ca depend. Récemment j'ai écrit un système de scripte Lua, où tout est géré avec des strings. C'est plus dynamiques, mais j'ai déjà eu pleine des erreurs parce que les strings n'ont pas été correctes, et j'ai dû debugger quelque temps. Si tu as un projet moyen où tu n'as pas besoin de la fléxibilité des identifiers dynamiques, les enums peuvent valoir la peine.

Sinon je me demande si en c++ il y a moyen de lancer une exception à la compilation
static_assert

Mais naturellement, il n'est pas possible de vérifier les strings pendant la compilation, alors ça ne t'aide pas.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 11, 2013, 10:08:50 pm
Citer
Oui. Mais il y a std::tr1::function depuis le TR1 (2005).
Ok
Citer
Tu parles de quelles fonctions et pointeurs ? Il faut seulement en définir si les clés (thor::ResourceKey) existantes ne suffisent pas.

Oui ça suffit pour ton système de ressource, mais pas pour des autres systèmes plus complexes, moi j'ai plusieurs fonctions différentes, avec un association de string à un id, je stocke aussi le path pour le sauver dans un fichier avec des ids. (de type int)
Histoire de ne plus avoir à recharger à chaque fois les textures dès que je lance mon éditeur de map.

Citer
void* n'est pas "typage-sûr", tu ne sais pas ce qui se cache derrière. Et tu ne peux rien faire sans savoir. C'est à cause de ça qu'il y a des téchniques très elegantes, comme type erasure.

Je n'ai jamais entendu parler de type::erasure, il est vrai que derrière le type void* on ne sait pas ce qui se cache derrière et ça peut paraître moins élégant mais je pense que pour les conteneurs ça suffit, je n'ai pas vraiment besoin de savoir que le "resource holder" que je stocke dans mon application est un resource manager de texture.
Et puis pour le réseau par exemple de SFML, Laurent utilise aussi un pointeurs sur void*.

Et chez moi ça fonctionne et ça me suffit donc je ne vais pas trop compliqué les choses. (Je pense que dans mon cas le pointeurs void* suffit vu que ça me sert juste à définir un type pour le stockage de mes ResourceManager dans l'application) :

std::map<std::string, ResourceManager<void*> >
 

Puis, je n'ai qu'à faire une reconversion en ResourceManager<R> lorsque je récupère le resourceManager. (donc je ne touche pas au type, je le convertis juste en void* avec reinterpret_cast pour pouvoir le stocker dans le conteneur)
Avec lequel je récupère ensuite toutes les informations sur les ressources pour stocker tout dans un fichier. (path, id) lors du sauvegarde.
Ton système ne me permet pas de faire ça.



Citer
Ca depend. Récemment j'ai écrit un système de scripte Lua, où tout est géré avec des strings. C'est plus dynamiques, mais j'ai déjà eu pleine des erreurs parce que les strings n'ont pas été correctes, et j'ai dû debugger quelque temps. Si tu as un projet moyen où tu n'as pas besoin de la fléxibilité des identifiers dynamiques, les enums peuvent valoir la peine.

Je ne connais pas les scripts lua, et puis pour se tromper dans un nom d'alias il faut déjà y aller fort, mais, je me débrouillerai pour que ça mette une erreur de compilation.

PS : et puis hum derrière un template tu ne sais pas non plus ce qui se cache derrière, à moins de spécialisé le template comme je l'ai fait là avec R* car ça peut être aussi bien un pointeur, qu'une référence..., et à partir du moment ou tu manipule de la mémoire sur des void* au lieu d'utiliser un template ou un shared_ptr alors là oui en effet ce n'est pas élégant du tout.

Mais ici, ce n'est pas le cas. (Car je n'ai pas utilisé de pointeur sur void dans ma classe ResourceManager, je sais donc que je manipule un pointeur sur un template)

Bref pour moi, nos deux systèmes sont à peu prêt équivalent.

Titre: Re : Framework
Posté par: Laurent le Décembre 11, 2013, 10:48:15 pm
Citer
Je n'ai jamais entendu parler de type::erasure
C'est très exactement ce que fait l'équivalent de boost::any que j'ai posté il y a quelques jours : tu "effaces" (-> erase) le type réel derrière une façade générique. L'avantage c'est qu'en interne, derrière la façade, les informations de typage de l'objet sont conservées, contrairement à un void*. Tu peux donc les exploiter lorsqu'il le faut.

Citer
il est vrai que derrière le type void* on ne sait pas ce qui se cache derrière et ça peut paraître moins élégant mais je pense que pour les conteneurs ça suffit, je n'ai pas vraiment besoin de savoir que le "resource holder" que je stocke dans mon application est un resource manager de texture.
Si tu le stockes, c'est que tu as besoin de t'en reservir plus tard. Si tu t'en sers, c'est forcément en le re-typant (puisque tu ne peux rien faire avec un void*), et en re-typant ton objet il y a un risque d'erreur. Alors que si tu t'es debrouillé pour garder le type d'une quelconque manière, le compilateur va te crier dessus si tu fais un truc incorrect.

Citer
Et puis pour le réseau par exemple de SFML, Laurent utilise aussi un pointeurs sur void*.
Pas pour stocker et réutiliser des objets. Juste pour passer des paramètres de type "adresse mémoire", ce qui est la définition même du type void*.

Citer
Et chez moi ça fonctionne et ça me suffit donc je ne vais pas trop compliqué les choses.
Tu codes pour apprendre non ? Dommage de s'arrêter sur des "ça marche alors ça me va", alors que tu peux t'améliorer sur certains points avec l'aide des gens du forum ;)

Citer
Puis, je n'ai qu'à faire une reconversion en ResourceManager<R> lorsque je récupère le resourceManager
C'est ultra dangereux ce que tu fais. Bien qu'issus du même template, ResourceManager<R> et ResourceManager<U> ne sont pas le même type. Convertir de l'un à l'autre n'est par définition pas correct -- même si en pratique ça marche. Evite ce genre de pratique.

Citer
je le convertis juste en void* avec reinterpret_cast pour pouvoir le stocker dans le conteneur
Pas besoin de reinterpret_cast ici :
- T* vers void* est automatique
- void* vers T* peut être réalisé avec un static_cast

On pinaille, mais un static_cast est plus strict qu'un reinterpret_cast, du coup le compilateur te criera plus volontiers dessus si tu te foires.

Citer
mais, je me débrouillerai pour que ça mette une erreur de compilation.
Comme déjà dit, ce n'est pas possible. Pour avoir des erreurs de compilation sur des identificateurs inconnus, il faut déclarer les identificateurs connus... donc avec un enum ;)

Citer
et puis hum derrière un template tu ne sais pas non plus ce qui se cache derrière
Si, tu le sais. Du moins tu peux le savoir. Ce qui est important c'est que le type réel soit toujours là. Si tu n'en as pas besoin alors tant mieux, si tu en as besoin alors tu peux toujours l'exploiter. C'est ça la force des templates.

Citer
Bref pour moi, nos deux systèmes sont à peu prêt équivalent.
Sauf que l'un est une approche naïve, qui pourra marcher certes, mais qui révèlera ses faiblesses sur le long terme. Mais il faut bien se rendre compte par soi-même pour apprendre, non ? ;)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 12, 2013, 09:42:06 am
Citer
C'est très exactement ce que fait l'équivalent de boost::any que j'ai posté il y a quelques jours : tu "effaces" (-> erase) le type réel derrière une façade générique. L'avantage c'est qu'en interne, derrière la façade, les informations de typage de l'objet sont conservées, contrairement à un void*. Tu peux donc les exploiter lorsqu'il le faut.

Ha ok là je comprends mieux donc ce que tu essayes de me dire c'est que ça :

void* nb = 5;
type_info(nb);
 

Ca ne marche pas.

Du coup ce n'est pas bien parce que je ne peux pas vérifier le type de la variable lorsque je la récupère ?

Dans ce cas je n'ai qu'à conserver le type de la variable dans ma classe ResourceManager<R> et le problème est réglé. :) (Tout comme dans le code source que tu m'as montré plus haut)

Citer
Si tu le stockes, c'est que tu as besoin de t'en reservir plus tard. Si tu t'en sers, c'est forcément en le re-typant (puisque tu ne peux rien faire avec un void*), et en re-typant ton objet il y a un risque d'erreur. Alors que si tu t'es debrouillé pour garder le type d'une quelconque manière, le compilateur va te crier dessus si tu fais un truc incorrect.

Mais je pensais vraiment que le cast me renverrait une erreur en compilation dans ce cas là.  (Enfin normalement il est sensé me crier dessus)

Citer
Pas pour stocker et réutiliser des objets. Juste pour passer des paramètres de type "adresse mémoire", ce qui est la définition même du type void*.

Donc void* ne sert que qu'à passer des paramètres de type adresse mémoire, pas à les stocker....

Citer
C'est ultra dangereux ce que tu fais. Bien qu'issus du même template, ResourceManager<R> et ResourceManager<U> ne sont pas le même type. Convertir de l'un à l'autre n'est par définition pas correct -- même si en pratique ça marche. Evite ce genre de pratique.

C'est vrai,  void* et R sont du même type.

Citer
Pas besoin de reinterpret_cast ici :
- T* vers void* est automatique
- void* vers T* peut être réalisé avec un static_cast

On pinaille, mais un static_cast est plus strict qu'un reinterpret_cast, du coup le compilateur te criera plus volontiers dessus si tu te foires.

Ok.

Citer
Sauf que l'un est une approche naïve, qui pourra marcher certes, mais qui révèlera ses faiblesses sur le long terme. Mais il faut bien se rendre compte par soi-même pour apprendre, non ?

Ouais.

Bref je vais conserver le type de mon template dans la classe ResourceManager et faire une vérification de type moi même alors, mais si le compilateur me crie dessus si je me trompe de type pour le template lors du cast bah, alors là, il n'y a pas vraiment de problème ni d'approche naïve puisque de toute façon ça ne compilera pas.

Halala les collections en java qui acceptent n'importe quel type d'objet me manque. (Juste comme ça part hasard il y en aurait pas en c++) ?

Sur ce je vais faire mon générateur aléatoire de map pour continuer mes tutoriels et ça va cartonner grave.  :D
Titre: Re : Framework
Posté par: Lolilolight le Décembre 12, 2013, 09:53:56 am
CQFD :

class MyAppli : public Application {
    public :
    MyAppli(sf::RenderWindow &window) : Application (window) {
        TextureManager tm;
        addResourceManager<Texture>(tm, "TextureManager");
    }
    void load() {
        TextureManager &tm =  resourceManager<Font>("TextureManager");
        tm.load("tilesets/herbe.png", "HERBE");
    }
 

Citer
||=== TestSFGL, Debug ===|
C:\SFGL\include\SFGL\Core\any.h|39|warning: 'sfgl::any' has a field 'sfgl::any::m_holder' whose type uses the anonymous namespace [enabled by default]|
D:\Projets\Projets-c++\TestSFGL\myApplication.h||In member function 'virtual void MyAppli::load()':|
D:\Projets\Projets-c++\TestSFGL\myApplication.h|15|error: invalid initialization of reference of type 'sfgl::TextureManager& {aka sfgl::ResourceManager<sf::Texture>&}' from expression of type 'sfgl::ResourceManager<sf::Font>'|
C:\SFGL\include\SFGL\Core\..\..\..\include\SFGL\Core\resourceManager.h||In instantiation of 'void sfgl::ResourceManager<R>::load(const string&, const string&) [with R = sf::Texture; std::string = std::basic_string<char>]':|
D:\Projets\Projets-c++\TestSFGL\myApplication.h|16|required from here|
C:\SFGL\include\SFGL\Core\..\..\..\include\SFGL\Core\resourceManager.h|65|warning: suggest parentheses around '&&' within '||' [-Wparentheses]|
||=== Build finished: 1 errors, 4 warnings (0 minutes, 4 seconds) ===|
[/code]
Titre: Re : Framework
Posté par: Laurent le Décembre 12, 2013, 06:11:06 pm
Citer
Dans ce cas je n'ai qu'à conserver le type de la variable dans ma classe ResourceManager<R> et le problème est réglé.
Oui enfin je parlais de manière plus globale, pas spécialement du std::type_info correspondant au type. On a très rarement besoin de jouer avec std::type_info en réalité. Dans ton cas, avoir un typage plus fort (que du void*) peut aussi vouloir dire passer par des fonctions virtuelles, ou autre chose (j'ai pas regardé ce que tu fais de tes managers, donc je peux pas en dire plus).

Citer
Mais je pensais vraiment que le cast me renverrait une erreur en compilation dans ce cas là.  (Enfin normalement il est sensé me crier dessus)
Comment le compilateur pourrait savoir quel est le type de l'objet qui se cache derrière ton void* ? Pour lui, un void* c'est juste en entier.

Citer
C'est vrai,  void* et R sont du même type.
???

Citer
mais si le compilateur me crie dessus si je me trompe de type pour le template lors du cast bah, alors là, il n'y a pas vraiment de problème
On est d'accord. Mais ce n'est pas le cas ;)

Citer
Donc void* ne sert que qu'à passer des paramètres de type adresse mémoire, pas à les stocker....
On peut aussi stocker des variables de type void*. Le truc important c'est que ça ne doit pas être un moyen de stocker "tout et n'importe quoi" pour s'en reservir plus tard. La "bonne" utilisation de void*, c'est pour définir une adresse mémoire (peu importe ce qui se cache derrière), rien d'autre.

Citer
Halala les collections en java qui acceptent n'importe quel type d'objet me manque. (Juste comme ça part hasard il y en aurait pas en c++) ?
Non il n'y en n'a pas, et c'est tant mieux.

Citer
CQFD
Ca n'a rien à voir. Tu affectes une variable de type ResourceManager<Font> à une variable de type ResourceManager<Texture>, qui sont deux types incompatibles. C'est comme si tu écrivais "std::string str = 5".
Le problème dont on parle, c'est ça :

class MyAppli : public Application {
    public :
    MyAppli(sf::RenderWindow &window) : Application (window) {
        TextureManager tm;
        addResourceManager<Texture>(tm, "ManagerMysterieux");
    }
    void load() {
        FontManager &tm =  resourceManager<Font>("ManagerMysterieux");
        tm.load("arial.ttf");
    }

Personne ne te criera dessus quand tu vas transtyper ton ResourceManager<void*> stocké sous le nom de "ManagerMysterieux" en ResourceManager<Font>, puisque personne ne saura qu'il s'agit en fait d'un ResourceManager<Texture>.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 12, 2013, 07:08:34 pm
Tu n'as pas vu mon code en entier alors parce que :

Il ne peut pas transtyper car si il veut ajouter un ressource manager dans le cache, il est obligé de passer par la fonction template du cache.

Qui est celle-ci :
addResourceManager<Texture>(tm, "TextureManager");
 

Le pointeur sur void* n'est pas dans ma classe ResourceManager, mais bien dans un cache qui se charge de stocker tous les ressources managers dans une map et de les transtyper.

Un peu comme le fait boost::any d'ailleurs, à part que là, ça stocke plusieurs type de ressources comme le multicahe de thor.

map<string, ResourceManager<void*> > resourceManagers;
 

Mais le développeur n'a pas accès au conteneur directement, il est obligé de passer par le cash de l'application qui va lui même se charger de transtyper ça en void* pour que le cache puisse contenir des ressources manager contenant n'importe quel type de ressources. (Texture, son, etc...)

Donc en gros j'ai 2 conteneurs, le "resource manager" qui est comme les classe holder et holder<impl> de ton code et le cache qui correspond à la classe any à part qu'elle peut contenir plusieurs pointeurs sur void* et pas qu'un seul.
Ca ressemble un peu à un boost::variant du coup plutôt qu'à un boost any. (D'ailleurs pour pas te le cacher c'est sur ça que je me suis basé pour créer le resource holder de SFGL)
Mais sinon je suis d'accord avec toi hein sur le fait qu'on ne devrait pas pouvoir accéder directement à un void* si l'on s'en sert dans un conteneur.

D'ailleurs tu vois bien que je n'ai pas fait ça :

map<string, void*> resourceManagers
 

A ne pas confondre avec mon bout de code précédent.
Et je trouve que ça simplifie grandement les choses comparé au système de key de la librairie thor qui est, trop complexe pour moi, les pointeurs sur les fonctions et les shared pointeurs n'est pas quelque chose que je maîtrise vraiment très bien. :/ (Vu que à l'université j'ai appris à m'en passer)

Je pense que je vais essayer de update le code source sur git-hub ce soir (en recréant le repository), ça permettra à certains de mieux comprendre ce que je fais.

De plus j'ai besoin de conserver les paths vers les textures dans mon holder, pour les stocker dans un fichier, ceci m'évite de devoir recréer un conteneur pour chaque application contenant les path vers les ressources que j'utilise.

Donc la seule et unique fonction de thor pour récupérer un pointeur sur une ressource ne me suffit pas. :/

Et ce code me permet d'éviter de devoir passer par divers foncteurs.
C'est ce qui fait d'ailleurs la force des langages compiler contrairement au langage interprêtés (principalement ceux des scripts) ou là, la seconde méthode avec les pointeurs de fonction est à privilégié.

D'ailleurs certains langage comme le javascript permettent de le faire automatiquement tout comme les nouveautés du c++11. (Mais pour moi ceci n'est pas indispensable dans un langage compilé et typé, car, le type erasing comme tu le cites permet de régler le problème)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 12, 2013, 10:37:59 pm
Voilà j'ai tout remis à jour sur git-hub, je pense que je vais mettre un paramètre facultatif comme nom pour le ResourceManager, ainsi si le développeur ne veut pas utiliser de string, il n'aura qu'à faire ceci :


TextureManager grass;
grass.load("path");
TextureManager rock;
rock.load("path");
app.addResourceManager<Texture>(grass);
app.addResourceManager<Texture>(rock);
 

Je pense que je vais aussi simplifier cela en renommant la classe ResourceManager en ResourceCache, créer une classe ResourceMultiCache qui fera une itération sur tout les ResourceCache pour récupérer la bonne ressource.
Un ResourceCache pourra contenir une ou plusieurs ressource du même type. (Si le développeur ne veut pas utiliser de string comme identifiant, il pourra utilise un resourceCache par ressource et le cache servira alors d'identifiant, je n'aurai qu'à redéfinir l'operateur== pour comparé les id (de type int) pour le cache.)

Je pense que c'est le meilleur moyen d'offrir au développeur un compromis entre flexibilité et robustesse.

Donc en gros une ressource pourra avoir un alias ou pas, si il n'en a pas, alors c'est le nom du cache qui servira d'identifiant. (Et je parle bien du nom de la variable cette fois)
Titre: Re : Framework
Posté par: Nexus le Décembre 12, 2013, 11:00:42 pm
Je pense que je vais aussi simplifier cela en renommant la classe ResourceManager en ResourceCache
Je ne sais pas si c'est un bon nom. J'ai appellé la classe comme ça en Thor exactement à cause des choses que ton implementation n'offre pas: Les shared_ptr et la résolution des duplicates.

Ton système les resources contient les resources, alors je crois qu'il y a des meilleurs noms. ResourceManager est peut-être général, mais ce n'est pas une description mauvaise ;)
Titre: Re : Re : Framework
Posté par: Lo-X le Décembre 13, 2013, 08:59:07 am
les pointeurs sur les fonctions et les shared pointeurs n'est pas quelque chose que je maîtrise vraiment très bien. :/ (Vu que à l'université j'ai appris à m'en passer)

Plutôt que d'apprendre à t'en passer, tu devrais apprendre à les utiliser. Ce sont des outils très puissants et qui deviennent indispensables (avec l'arrivée de C++11, la RAII, ...)


Et ce code me permet d'éviter de devoir passer par divers foncteurs.
C'est ce qui fait d'ailleurs la force des langages compiler contrairement au langage interprêtés (principalement ceux des scripts) ou là, la seconde méthode avec les pointeurs de fonction est à privilégié.

Je ne sais pas d'où tu sors que les langages de scripts "sont prioritaire" sur les langages compilés pour les foncteurs, mais les foncteurs sont l'un des outils les plus puissants et les plus utiles de la programmation et ont été tellement simplifiés en C++11 que ça en devient de la rigolade (à utiliser). Franchement, dans un jeu, c'est juste impossible de faire sans. Alors je ferai le même commentaire qu'au dessus : au lieu de les éviter, utilise les, ça te simplifiera la vie.


Sinon je crois que c'est mon dernier message ici, je suis un peu découragé de tenter de t'aider et que tu refuses toute aide (de moi ou de n'importe quel intervenant dans ce thread). Non pas qu'on détient la vérité absolue, mais certaines personnes ici ont plus d'expérience et c'est dommage de ne pas écouter (au cas où les choses ne sont pas claires : je ne parle pas de moi).
Titre: Re : Framework
Posté par: Lolilolight le Décembre 13, 2013, 10:14:01 am
Je crois que tu n'as rien compris, c'est pas que je ne veux pas écouter les autres, hein, c'est que chacun utilise des techniques +/- complexe en fonction de leur besoin, le but de SFGL est de faire un système simple pour développeurs débutant. (Pour être plus expérimenté que moi il faut déjà y aller, j'espère que tu te rend comptes de ce que tu dis, excuse moi mais ce n'est pas un développeur qui fait ça en tant que passionné qui va m'apprendre à développer)

En java, les pointeurs de fonction n'existent pas, j'ai commencé par apprendre ce langage avant de passez au c++, et bien, je peux te dire qu'il  bien fallut se débrouiller sans et ça marche très bien.

Et puis il y a moyen de faire vachement plus simple dans mon cas que le système utilisé dans thor ou bien d'utiliser une enum ou une clé comme identifier, autant utiliser le nom de la ressource (ou du manager) lui même : (Car dans mon cas le manager contient la ressource)

ResourceManager<Texture> herbe;
herbe.load("path");
multCache.add(herbe);
Texture* herbe = multCache<Texture>.get(herbe);
 

Alors oui, les pointeurs de fonctions sont plus utiliser dans les langages comme le javascript par exemple que dans les langages compilés ou semi-compilé comme le java ou bien le c++ .

Bref je vais m'arrêter de te répondre, nexus avoue lui même que son système est trop complexe dans mon cas.
Je pense que c'est plutôt toi qui pense détenir la vérité absolue.

Le c++11 est plus un ajout qu'autre chose selon moi, un gadget non négligeable certes mais pas indispensable. (D'ailleurs le c++11 se base beaucoup sur boost et certaines librairies qui utilisaient déjà des concepts avancé du langages c++ bien avant qu'apparaissent le c++11.)

J'ai commencé à coder SFGL avant l'arrivée du c++11, il a donc bien fallut que je me débrouiller sans.

Donc oui il y a quelques nouvelles fonctionnalités utile avec le c++11 qui simplifie le code source, mais, ce n'est pas indispensable.

Mon système n'utilise en effet pas de shared-pointer ni la résolution de duplicate, il applique juste le principe du RAII qui supprime toutes les ressources dans les destructeurs de ResourceManager et de Application.

Titre: Re : Framework
Posté par: Lo-X le Décembre 13, 2013, 10:25:46 am
Okay...

Je ne vais pas m'amuser à montrer que tu as tort sur la plupart des points de ton dernier post parce que tu en referai un identique, et je ne vais pas m'engager dans une discussion qui va partir en vrille.

Si je t'ai offensé, excuse moi, mais c'était pas voulu. J'ai juste partagé mon expérience ainsi que mon ressenti. Que tu le prennes en compte ou non n'appartient qu'à toi.

Bref, je ne participe plus à ce sujet. Bonne chance pour ton framework.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 13, 2013, 10:27:01 am
Citer
Okay...

Je ne vais pas m'amuser à montrer que tu as tord sur la plupart des points de ton dernier post parce que tu en referai un identique, et je ne vais pas m'engager dans une discussion qui va partir en vrille.

Si je t'ai offensé, excuse moi, mais c'était pas voulu. J'ai juste partagé mon expérience ainsi que mon ressenti. Que tu le prennes en compte ou non n'appartient qu'à toi.

Bref, je ne participe plus à ce sujet. Bonne chance pour ton framework.

Ok, merci quand même.
Titre: Re : Re : Framework
Posté par: G. le Décembre 13, 2013, 10:33:47 am
Pour être plus expérimenté que moi il faut déjà y aller, j'espère que tu te rend comptes de ce que tu dis, excuse moi mais ce n'est pas un développeur qui fait ça en tant que passionné qui va m'apprendre à développer
Magique !!!  :D :D :D
Titre: Re : Framework
Posté par: Excellium le Décembre 13, 2013, 03:16:40 pm
Pinaise, ça exsude la modestie ici :D
Tu es peut être chevronné niveau théorie avec les cours que tu as fait à la fac, mais quand bien même tu obtiendras ton diplôme tu auras très peu de pratique en situation réelle, tu n'auras peu ou prou bossé sur un projet d'envergure. J'ai un peu l'impression que tu as été formaté sur certains trucs par tes profs, comme la non utilisation des pointeurs intelligents, car tu a appris a bien gérer la mémoire. Si ça marche pour de petits projets , c'est loin d'être évident dans de gros.
Si tu viens poser des questions ici c'est que quand même il te reste des trucs à apprendre, tu n'es pas au summum programmatiquement parlant. D'ailleurs, qui pourrait l'être ?
Y'a de bons conseils sur ce forum, avec des gens passionnés comme tu dis qui tentent de répondre à tes questionnements sur la meilleure façon de faire. Je te conseille d'écouter et de puiser un maximum de ressources, toi qui souhaite en faire ton boulot plus tard, sinon en monde professionnel tu seras vite concurrencé par de simples '42' sans diplôme (comprenne qui pourra) parce qu’ils seront plus productifs et innovants que toi, ou tout simplement car "tu te la ramèneras devant ton supérieur".
Tu arrêtes pas de parler du Java, tu as l'air vachement nostalgique de sa simplicité, mais en C++ il y a des subtilités qu'il faut prendre le temps d'assimiler et des innovations qu'il faut appréhender car elles simplifient grandement le code. Les pointeurs de fonction en sont une, et le temps que tu investiras en ouverture d'esprit tu le gagneras en pratique par la suite. Tu veux faire un framework simple, mais simple pour toi ou simple pour l'utilisateur ? Je te laisse le soin de répondre toi même à cette question.
A bon entendeur...  ::)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 13, 2013, 04:58:38 pm
Oui et il m'arrivera encore de poser des questions sur des techniques de programmation que je n'ai pas pratiquée et que d'autres ont pratiquées. (Car je ne connais pas la vérité absolue, si tel était cas je n'aurai pas besoin de venir ici sur le forum)

Mais mes compétences suffisent largement à traduire les idées en code source et à savoir lesquelles il est bon de m'en inspirer, je ne copie donc rien. (A vrai dire je ne fais que de regarder les idées de chacun. (et pas le code source) afin de choisir la ou lesquelles sont les meilleures dans mon cas)
Innover c'est bien mais le faire de façon intelligente c'est mieux.

Je veux faire un famework simple d'utilisation pour le développeur. (Et pas un framework qui utilise de la technologie de pointe)

Et je n'ai jamais eu l'occasion de travailler dans le monde professionnel, que je n'aime pas car on privilégie plus souvent l'innovation mauvaise, l'escroquerie et la médisance (à moins de tomber vraiment dans la bonne boîte mais ce n'est pas si simple que cela surtout en ce moment)
Donc, il faut bien que je me démerde, car, il n'y a personne du monde professionnel qui va faire sa pour moi. (Et maintenant vu la difficulté à trouver un job dans le domaine cela ne va pas s'arranger au niveau de mes capacités dans le domaine du monde professionnel)

Mais bon il y a certains projets qui s'en sortent très bien même en ayant aucune connaissance du monde professionnel.
Donc il faut bien que je me batte, j'ai quand même des qualités malgré mes difficultés dans certains domaines, donc, je ne vais pas changer ma façon de faire juste à cause de 2-3 mecs qui sont dans le monde professionnels depuis des années et qui n'ont pas eu les problèmes que moi j'ai.
Mais je voudrais pas parler de ça ici car c'est de ma vie privée.
Titre: Re : Re : Re : Framework
Posté par: Laurent le Décembre 13, 2013, 05:57:46 pm
Pour être plus expérimenté que moi il faut déjà y aller, j'espère que tu te rend comptes de ce que tu dis, excuse moi mais ce n'est pas un développeur qui fait ça en tant que passionné qui va m'apprendre à développer
Magique !!!  :D :D :D
Je la garde pour le bêtisier de Noël ;D
Titre: Re : Framework
Posté par: Lolilolight le Décembre 13, 2013, 06:43:51 pm
Oui garde là pour le bêtisier de Noël si tu veux mais tu riras moins quand j'aurai un truc complet à présenter.  :) (Et encore moins si un jour je te concurrence)

Donc ne remet pas en cause mes compétences à chaque fois à cause de ma personnalité parce que ça commence largement à me gaver et puis je pense que je vais arrêter de te répondre...

Mais bon quand le moment sera venu tu verras de toute façon mais évite tes propos offensants.

Titre: Re : Framework
Posté par: Excellium le Décembre 13, 2013, 07:17:31 pm
Okay messieurs, gardons notre sérieux et laissons de côté le caractère récréatif de certaines réponses (on enfonce pas une porte ouverte). Un framework réalisé en commun est une très bonne idée en-soi, le forum pulule de projets de membres isolés, mais ou sont les grands projets communautaires qui feraient du bien à la SFML ?!  ;)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 14, 2013, 09:34:09 am
La dernière fois que j'ai fais un projet communautaire (lorsque j'ai commencé Sorrok) et je ne l'avais pas commencé tout seul d'ailleurs.

L'ex second chef de projet n'a fait que de faire preuve d'un manque total de sérieux puis à fini par quitté le projet en rejetant la faut sur moi hors qu'il n'a fait que de m'influencer depuis le début.
Bref ceci est du passé mais ça explique pourquoi je me méfie des projets communautaire et que beaucoup de membres font des projets plutôt isolé.

Plutôt que un gros projet communautaire ou l'on se fait influencé par des gens bizarre d'un peu partout sur internet qu'on ne connait même pas et qui ont pour seul but de faire tomber notre projet à l'eau. (Prétendant s'y connaitre, avoir fait des études et même avoir travaillé dans le milieu professionnel)

Bref un peu de fun dans le projet, je n'ai rien contre ça mais à partir du moment ou ça commence à partir sur du langage offensif et de la nuisance là, je ne peux plus accepter de collaborer avec certaines personne.

Donc bon pour ceux qui essayent de nuire je leur dirai, je ne cesserai pas le projet pour vous, et pour ceux qui rejoignent bah je ne collaborerai avec eux que si ils sont sérieux et qui ils ne prennent pas leur idées pour des vérités absolue. (Il y a souvent plusieurs approches possible en programmation, certaines sont à éviter certes, mais pas toutes)

Voilà ceci dit,
Titre: Re : Framework
Posté par: Lolilolight le Décembre 18, 2013, 12:42:10 pm
Re, j'ai commencer à faire un petit générateur de map (pour le contour (les murs) et le sol).

Ceci me servira pour le tutoriel :

TextureManager &tm =  resourceManager<Texture>("TextureManager");
        tm.load("tilesets/herbe.png", "GRASS");
        tm.load("tilesets/murs.png", "WALLS");
        View view = getWindow().getDefaultView();
        Vec2f pos (view.getCenter().x - view.getSize().x * 0.5f, view.getCenter().y - view.getSize().y * 0.5f);
        BoundingRectangle br (pos.x, pos.y, view.getSize().x, view.getSize().y);
        theMap = new Map (100, 50, 30, "Map test");
        std::vector<Tile*> tiles;
        std::vector<Tile*> walls;
        tiles.push_back(new Tile(tm.getResourceByAlias("GRASS"), Vec2f(0, 0), Vec2f(120, 60),IntRect(0, 0, 100, 50), 0));
        walls.push_back(new Tile(tm.getResourceByAlias("WALLS"), Vec2f(0, 0), Vec2f(100, 100), IntRect(100, 0, 100, 100), 1));
        walls.push_back(new Tile(tm.getResourceByAlias("WALLS"), Vec2f(0, 0), Vec2f(100, 100), IntRect(100, 100, 100, 100), 1));
        walls.push_back(new Tile(tm.getResourceByAlias("WALLS"), Vec2f(0, 0), Vec2f(100, 100), IntRect(100, 200, 100, 100), 1));
        walls.push_back(new Tile(tm.getResourceByAlias("WALLS"), Vec2f(0, 0), Vec2f(100, 100), IntRect(100, 300, 100, 100), 1));
        walls.push_back(new Tile(tm.getResourceByAlias("WALLS"), Vec2f(0, 0), Vec2f(100, 100), IntRect(100, 400, 100, 100), 1));
        walls.push_back(new Tile(tm.getResourceByAlias("WALLS"), Vec2f(0, 0), Vec2f(100, 100), IntRect(100, 500, 100, 100), 1));
        BoundingRectangle rect(0, 0, 1000, 1000);
        theMap->generate_map(tiles, walls, rect);
        theMap->checkVisibleEntities(br);
 

Je pense que je vais donc continuer les tutoriels sur les entités de haut niveau de SFGL ainsi que les entity managers. :P

Je vais même faire un générateur de donjon plus tard pour SFGL. :P

Mais en ce moment je dois surtout finir les tutoriels et faire en sorte que le code source soit au top pour la version 1.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 19, 2013, 11:24:38 am
Salut,

J'ai améliorer le resource holder de SFGL, il offre maintenant plus de façons de gérer les ressources : (Via un alias ou via un pointeur)

http://www.jeux-libres.com/tutoriaux/tuto-679-chapitre-introduction-et-installation-de-sfgl.php (http://www.jeux-libres.com/tutoriaux/tuto-679-chapitre-introduction-et-installation-de-sfgl.php)

J'ai corriger aussi quelques erreurs dans le code source, je dois encore finir d'améliorer quelque petites chose et je remet tout ça sur git-hub ce soir. ;)

PS : Pour ceux qui utilise thor : Resource correspond à la classe Key de thor, ResourceManager à la classe cache et ResourceCache à la classe MultiCache.

Plus tard je rajouterai peut être un pointeur sur fonction dans la classe Resource pour le load et un shared_pointer à la place du pointeur classique mais je n'en vois pas trop l'intérêt. (A part allourdir le code)

Par contre je pense que je vais faire un système qui associe un sf::Event à un pointeur de fonction pour les actions, pour plus tard. :) (Dans ce cadre là, les pointeurs de fonctions me semble plus utile)

Ps 2 : je dois encore combiner la puissance des scene node à celle de l'entity manager et je pense que ça sera bon, je vais également combiner les transformations sur les entités enfants directement dans la méthode draw de la classe Entity. ^^

Donc en gros ça ressemblera à une grille qui peut contenir des hiérarchie d'entités, après, je ferai la même chose avec un quadtree et un bsp-tree mais ça, ce n'est que prévu dans la version 2.

Dans la version 2 je pense aussi ajouter des hiérarchies de volumes englobant pour améliorer mon système de collision, et je pense que se sera parfait pour la 2D.

Pour la 3D par contre, il y a encore du boulot. (Je dois faire des générateurs de sol (heightmap), un chargeur de fichier (je pense que je vais choisir le format le plus standart, le .obj, et charger plusieurs fichier .obj en faisant une interpolation linéaires entre les positions des vertex pour les animations)
Il faut aussi refaire le système d'éclairage pour la 3D....

Il y a aussi le moteur de particule que je dois encore faire..., ainsi que le système de gui IG. :/

Mais je ne pense pas que je vais pouvoir tout inclure dans la version un surtout si je n'ai personne pour faire le site web.

Donc je pense que je ferai le système de particules dans la version 2, je vais me contenter de reprendre celui du tutoriel SFML pour la version un je pense.



Titre: Re : Framework
Posté par: Lolilolight le Décembre 19, 2013, 05:24:14 pm
Re :

Dépôt git-hub remis à jour.

-Amélioration du système de gestion des ressources (Désormais on peut utiliser le nom de la ressource comme identifiant et on n'est plus obligé d'utiliser un alias) et ajout d'une classe ResourceCache pour gérer les ressources indépendamment de le classe application.
-Amélioration du système de dessin des entités, désormais, la classe entité dessine toutes les entités enfants qui lui sont ajoutée avec toutes les classes qui dérivent de Entity)
-Amélioration de la classe TileGround : celle-ci peut contenir un ensemble de tiles (un peu comme une tileMap) et plus une seule Tile.
-Amélioration de la classe map : Seuls les entités enfants des entités parents qui sont visibles à l'écran son récupérées, on peut récupérer n'importe quel type ou entités contenant un ensemble d'entités visible à présent et les afficher dans l'ordre qu'on veut. (Ceci combine la puissance des SceneNode et celle de la grille)
Et les ombres sont désormais compté comme des entités enfants et donc, ne sont plus gérée dans un conteneur à part dans la classe map.
-La classe world peut contenir n'importe quel type d'entity manager (et plus seulement des entity manager de type map si vous voulez faire un entity manager personnalisé. :P)
-Ajout d'un générateur de plateformes dans la classe map avec possibilité d'ajouter des murs sur le bords. (Mais je dois encore perfectionné ça)

(Mais je dois encore régler quelques bugs depuis que j'ai changé le système.)


Bref voilà la suite du développement du framework sera donc surtout de la correction de bugs, et de l'amélioration de code source. (Au niveau optimisation je ne pense plus qu'il y a grand chose à faire, à part, une classe qui gère un quadtree et une qui gère un BSP-Tree, et aussi un système de volume englobant hiérarchique pour la gestion de collisions, mais ce n'est que prévu pour la version 2)

Ici je vais finir de corriger les derniers bugs de la version 1, et rajouter juste une classe de base pour l'entity system avec un thread pour remettre à jour les entités en fonction du temps ou des événements utilisateurs et une variable de condition pour la synchronisation. :P

Ensuite je ferai les tutoriels et le site pour tenter de sortir la version 1.

Ce qui est prévu pour la version 2 :

-Un système de commandes qui permettra de lier une action (qui contiendra un pointeur de fonction) à un événement.
-La possibilité de créer des jeux en réseau de manière  sécurisée avec openssl.
-La prédiction de mouvement.
-La possibilité de créer des interfaces IG.
-Ajout d'un système de gestion de particules.

Et dans la version 3 :

-Ajout d'entité pour la 3D de haut niveau. (Face au lieu de Tile, Sphere à la place de Shape, etc...)
-Génération et chargement d'entité en 3D. (heightmap, .obj, etc...)
-Ajout d'un système d'éclairage et d'ombres pour la 3D.

Certains ajout de classes pour la version 2 et 3 du framework on été mises sur le dépôt mais elles ne sont pas encore tout à fait au point.











Titre: Re : Framework
Posté par: cobra.one le Décembre 19, 2013, 08:02:18 pm
Avant de penser à la version 2, 3 ou 18, tu devrais déjà clarifier pas mal ton code, parce que c'est un peu (beaucoup ?) le bazar entre les .h et .cpp... Je vois des .h contenant toute l'implémentation, d'autres avec juste la déclaration, d'autres avec un bout d'implémentation, un bout de déclaration, bref.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 19, 2013, 08:16:05 pm
Ouais je sais je n'ai pas encore eu le temps de mettre de l'ordre dans tout ça.
Même chose pour les noms ou il y a des noms en français et en Anglais.

Mais pour les petits bout de code je trouve ça inutile de mettre l'implémentation dans un .cpp alors je l'ai mise dans un .h.

Mais j'avoue que je ne devrai pas faire les 2 avec une même classe, je devrai choisir entre l'un ou l'autre.

Parfois j'ai vraiment la flemme de recréer un fichier .cpp quand dans mon fichier.h il n'y a presque rien.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 20, 2013, 09:51:43 am
Ha, j'ai enfin compris l'intérêt du pointeur de fonction pour le chargement des ressources, et je vais en rajouter un dans la sous classe Ressource pour charger une ressource, car, j'ai oublié que une ressource peut aussi être chargée autrement que par un fichier.

Il faut juste que j'apprenne à utiliser std::function.  :P

En y regardant de plus prêt, c'est vrai que on pourrait se passer des pointeurs de fonctions mais le fait que le c++ offre plus de possibilité que le java n'est pas mal du tout. ^^

(Ca me permettrait d'éviter de devoir rajouter un héritage...)

PS : j'ai découvert un bug en fait dans la classe Math, dans la fonction sqrt, il fallait rajouter std devant sqrt, sinon, il rappelait la fonction sqrt de la classe Math.





Titre: Re : Framework
Posté par: Lolilolight le Décembre 20, 2013, 02:44:58 pm
Bon, je vois que std::bind permet de générer différents pointeurs de fonctions (utile si on veut définir différents fonctions pour charger un truc)

Mais il reste un problème dans mon cas : il faut quand même passer les arguments à la fonctions, pour l'appeler, et si je veux faire différentes fonctions load pouvant avoir un nombre variable d'argument, et passer une de ses fonctions à la classe ResourceManager pour charger une ressource, ça ne va pas marcher.

Alors j'ai réfléchi et je pense que je vais faire un fichier .cpp qui va écrire dans ce même fichier .cpp la fonction avec les noms des arguments.

(Ce sera du code source qui générera du code source un peu comme le fait Qt d'ailleurs qui génère du code c++ dans les .moc)

Mais je vais essayer de faire un système ou il ne faut pas générer de fichier .moc.

Titre: Re : Framework
Posté par: Laurent le Décembre 20, 2013, 06:17:03 pm
Fais gaffe, tu parles encore tout seul.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 20, 2013, 08:08:01 pm
Bon, j'essaye de faire mon propre système de signaux et slot, l'idée est d'écrire dans un fichier source, donc j'ai essayer de faire un fichier source qui écrit dans un autre fichier source, comme ceci :
#ifndef RESOURCE_LOADER
#define RESOURCE_LOADER
#include <fstream>
namespace sfgl {
class Function {
    public :
    static void createFunction (std::string functionName, std::map<std::string, void*> args, std::string classType = "", std::string objectName = "", bool isPointer = false, std::string returnType = "void") {
        std::ifstream ifile("C:/SFGL/include/SFGL/Core/resourceLoader.h");
        std::string line;
        std::vector<std::string> fcontent;
        while (getline(ifile, line))
            fcontent.push_back(line);
        ifile.close();
        std::ostringstream content("\t");
        Function::returnType = returnType;
        if (returnType != "void" && objectName == "")
            content<<"return "<<functionName<<"(";
        else if (returnType == "void" && objectName == "")
            content<<functionName<<"(";
        else if (returnType == "void" && objectName != "")
            if (!isPointer)
                content<<objectName<<"."<<functionName<<"(";
            else
                content<<objectName<<"->"<<functionName<<"(";
        else if (returnType != "void" && objectName != "")
            if (!isPointer)
                content<<"return "<<objectName<<"."<<functionName<<"(";
            else
                content<<"return "<<objectName<<"->"<<functionName<<"(";
        std::map<std::string, void*>::iterator it;
        for (it = args.begin(); it != args.end();it++) {
            argsTypes.push_back(it->first) ;
            argsValues.push_back(it->second);
        }
        for (unsigned int i = 0; i < argsTypes.size(); i++) {
            content<<"argsValues["<<i<<"].get<argsTypes["<<i<<"]>()";
            if (i != argsTypes.size() - 1)
                content<<",";
        }
        content<<");";
        fcontent[invokeFunction] = content.str();
        content.str("\t");
        content<<"static "<<classType<<" "<<objectName<<";";
        fcontent[declareClass] = content.str();
        content.str("");
        if (!isPointer)
            content<<classType<<" Function::"<<objectName<<" = "<<classType<<"();";
        else
            content<<classType<<" Function::"<<objectName<<" = new "<<classType.substr(0, classType.size() - 1)<<"();"<<std::endl;
        fcontent[declareOtbject] = content.str();
        std::ofstream ofile ("C:/SFGL/include/SFGL/Core/resourceLoader.h", std::ios::trunc);
        for (unsigned int i = 0; i < fcontent.size(); i++) {
            ofile<<fcontent[i]<<std::endl;
        }
        ofile.close();
    }
    static void* invoke () {

    }
    private :

        static std::string returnType;
        static std::vector<std::string> argsTypes;
        static std::vector<void*> argsValues;
        static const int invokeFunction = 57;
        static const int declareClass = 60;
        static const int declareOtbject = 68;
};

std::string Function::returnType = "";
std::vector<std::string> Function::argsTypes = std::vector<std::string> ();
std::vector<void*> Function::argsValues = std::vector<void*> ();
}
#endif // RESOURCE_LOADER
 

Mais il faudrait que je trouve une solution pour passer carrément un pointeur de fonction à la fonction createFonction parce que là vous me direz surement que c'est pas le top.

Ha oui autre chose les tabulations avec \t ne marchent pas.






Titre: Re : Framework
Posté par: Lolilolight le Décembre 21, 2013, 09:02:25 am
Bon j'ai trouvé une solution à mon problème, mais je vais arrêter de poser des questions là car je parle dans le vide.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 21, 2013, 10:51:07 pm
Bah franchement avec le c++11 c'était tout simple de faire ça. :P

#ifndef FUNCTION
#define FUNCTION
#include <typeinfo>
#include <cstdarg>
namespace sfgl {

    template <typename S> class Function {
        public:

        template <typename R, typename... A> Function (typename std::result_of<R(A...)>::S func) {
            this->func = func;
            nbArgs = sizeof...(A);
        }
        //template <typename R, typename ...A> R operator() (A... args);
        template <typename R, typename... A> R operator()(A... args) {
            return func(&args ...);
        }
        private :
            unsigned int nbArgs;
            std::vector<void*> argTypes;
            S func;
            std::vector<std::string> typeNames;
    };
}
#endif // FUNCTION
 
int main () {    
    Function <void(string)> f();
    func("...");
    return 0;

}
 

Bon maintenant il ne reste plus qu'à faire la même chose mais avec des fonctions membres, et ensuite, j'attaquerai le système de signal et de slot, mais je ne suis pas sûr d'y arriver, car, il faut que je passe les paramètres de la fonction du signal à celle du slot et ensuite appeler le slot avec un foncteur...

Bref là en ce moment je m'amuse avec le c++11 ça devient tellement simple la méta-programmation.  :D

Bon ok j'ai quand même chercher longtemps..., avant de trouver le truc. (Pour déclarer n'importe quel type de pointeur de fonction puis l'appeler) parce que std::bind ne permet pas de faire ce genre de chose. (Vu qu'il déclare des pointeurs à la volée dont en plus on ne connait pas le type renvoyé par std::bind.)
Ca pue. :/
Titre: Re : Framework
Posté par: Lo-X le Décembre 22, 2013, 12:25:18 am
http://en.cppreference.com/w/cpp/utility/functional/function
Titre: Re : Framework
Posté par: Lolilolight le Décembre 22, 2013, 01:03:09 pm
std::function est bien mais c'est juste que moi j'ai besoin d'un type précis pour faire une fonction de callback (comme le fait la librairie thor), std::function ne possède pas de type, il permet juste de définir différents pointeurs de fonctions.

Bref, un truc du genre :

Function <void()> callBack();
Slot (callBack);
 

Et je voudrais faire aussi bien avec des fonctions void que avec retour ainsi par exemple pour mon système de ressource, définir n'importe quel fonction callback pour charger une ressource et récupérer le booléen.

Je suis obligé de recréer la classe vu que std::function ne me permet pas de faire ça :
std::function<void()> f;
Slot (f);
 

Ou alors j'ai loupé quelque chose ?

PS : j'ai pensé à faire un template qui accepterais n'importe quel type de st::function mais la syntaxe serait trop lourde. :/

De plus avec un template je pourrais très bien envoyer autre chose qu'une fonction..., car, pas de std::result_of. :/



Titre: Re : Framework
Posté par: Lolilolight le Décembre 22, 2013, 05:45:57 pm
En fait je voudrais faire quelque chose comme ceci :

Ex obj;    
Function<void(Ex::*)()> f = &Ex::of;  
 f(obj)();
 

J'ai essayé ceci :
#ifndef FUNCTION
#define FUNCTION
namespace sfgl {

    template <typename S> class Function {
        class FunctionMember;
        public:
        template <typename R, typename... A> Function (typename std::result_of<R(A...)>::S func) {
            this->func = func;
        }
        template <typename R, typename C, typename... A> Function (R(C::*function)(A...)) {
            this->func = function;
        }
        template <typename R, typename... A> R operator()(A... args) {
            return func(&args ...);
        }
        template <typename R, typename O, typename... A> R operator()(O object, A... args) {
            return object.func();
        }
        private :
            S func;
    };

}
#endif // FUNCTION
 

Mais ça ne fonctionne pas.

Je voudrais mettre la fonction membre dans S mais je sais pas trop comment faire donc si quelqu'un à une idée.

J'ai essayé avec un decltype mais ça ne marche pas :
template <typename R, typename C, typename... A> Function (R(C::*function)(A...)) {
            S = decltype(&C::function);
            this->func = function;
        }
 
Titre: Re : Framework
Posté par: Laurent le Décembre 22, 2013, 06:10:37 pm
Avec std::function :

// toujours appelée avec obj
std::function<void()> f = std::bind(&Ex::of, obj);
f();

// l'objet est variable et spécifié lors de l'appel
std::function<void(Ex&)> f = std::bind(&Ex::of, std::placeholders::_1);
f(obj);

Avec des lambdas :

// toujours appelée avec obj
auto f = [&](){obj.of();};
f();

// l'objet est variable et spécifié lors de l'appel
auto f = [](Ex& o){o.of();};
f(obj);

Note que tu peux aussi stocker le résultat d'une lambda dans un std::function, tout comme utiliser "auto" pour le type de retour de std::bind.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 22, 2013, 09:25:19 pm
Ha ça va j'ai trouvé l'article qu'il me faillait. (Enfin!) :)

http://stackoverflow.com/questions/3534812/how-does-the-template-parameter-of-stdfunction-work-implementation (http://stackoverflow.com/questions/3534812/how-does-the-template-parameter-of-stdfunction-work-implementation)

J'ai re-spécialisé la classe pour les fonctions normale, je crois que je vais également faire une spécialisation pour les fonctions membre statiques, ainsi que pour les foncteurs et les lambdas.

Ensuite je ferai une classe Signal qui se chargera de contenir plusieurs de ses fonctions et de les appeler en leur passant des paramètres. (des informations sur des events par exemple)
Et une classe pour connecter un signal à une fonction. ^^
Titre: Re : Framework
Posté par: Lolilolight le Décembre 23, 2013, 09:55:37 am
Re, j'ai une question au sujet du c++11, je voudrais savoir comment faire pour récupérer chaque élément d'un template pack. (Avec un boucle par exemple)

void function(A... args) {
       for (int i = 0; i < sizeof...(A); i++) {
            ????
       }
}
 

PS : en fait je voudrais faire une classe qui puisse contenir à la fois : des fonctions, des arguments de fonctions/objets ou bien des placeholders  et tout appeler avec l'operator () qui exécutera tout. (on aura le choix, soit on passera les arguemnts/objets à l'opérator() ou alors on les passera directement au constructeur de ma classe bind.

En gros se sera comme un signal auxquel on pourra connecter des slots. (fonctions, paramètres et objets)

Je connecterai ensuite ces signaux à des actions qui se déclencheront lors d'event et le binder appelera tout avec l'opérateur ().


PS : je crois que j'ai compris, il faut appeler la fonction récursivement en lui passant le paraméter pack.

Maintenant j'aimerais savoir si y'a moyen de stocker un paraméter pack dans une variable membre. (Afin de stocker un ensemble de valeurs d'arguments ou objets de fonction pour les appeler plus tards.


Titre: Re : Framework
Posté par: Lolilolight le Décembre 23, 2013, 12:36:15 pm
Bon je pense que y'a pas moyen de stocker plusieurs fonctions dans un template parameter pack, et de les appeler une à une via l'opérateur ().


Je voudrais aussi vérifier le type de chaque arguments des fonctions, et renvoyer une erreur lors de l'appel de la fonction si le nombre d'arguments ou le type d'un argument est incorrect.

Bref je voudrais faire un peu ce que fait le compilateur..., ainsi, je pourrais lier une action à un ensemble de fonctions qui seront appelée lorsque l'action sera déclenchée.

Pour l'instant j'ai juste créer une classe Function et je pense que je vais faire un std::vector de function et je voudrais lors de l'appel des fonctions ça vérifie si les arguments passé à l'opérateur() correspondent à ceux définis lors de la déclaration des fonctions, pareil si la fonction est appelée sur un objet.

Je pensais stocker la liste des types d'arguments dans un tuple, et les récupérer avec get comme ceci :

std::tuple<ArgsType>... argList;
 

Mais ça ne marche pas, ce code-ci me renvoie une erreur :

Function (Res (*func)(ArgTypes...)) {
        ptr.func = func;
        callback = &call_func;
        argList = ArgTypes; //Erreur.
}
 

PS : un bon compilateur est un compilateur qui nous permet de faire aussi ce que lui fait.  :D



Titre: Re : Framework
Posté par: Lolilolight le Décembre 23, 2013, 01:11:40 pm
O_O mais c'est que c'est génial le c++11 !

http://stackoverflow.com/questions/11279044/how-do-i-use-values-from-an-stdtuple-as-function-arguments (http://stackoverflow.com/questions/11279044/how-do-i-use-values-from-an-stdtuple-as-function-arguments)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 23, 2013, 05:45:24 pm
Mwai non j'ai parlé trop vite, ça ne marche que pour passer les arguments d'une fonction à un tuple si j'ai bien compris...

Mais pas pour passer les arguments d'un pointeur de fonction...

Donc j'en conclu que y'a pas moyen de le faire. (Car je vois aucune moyen de stocker les arguments d'un pointeurs de fonction dans un tuple...

Bref je pense que je vais faire une classe qui sera un std::vector de Function, et que je vais appeler les fonctions une par une.

Et une autre classe qui connectera les objets et les actions aux fonctions.

Je voulais faire un truc comme std::bind qui créerait automatiquement des Function en lui passant des arguments, qui stockerai les fonctions dans une liste et qui en plus appellerait automatiquement ces fonctions en vérifiant si tout est correct, mais il semblerait que ça ne soit pas possible, tout simplement parce que je ne peux pas récupérer les arguments d'un pointeur de fonction...






Titre: Re : Framework
Posté par: cobra.one le Décembre 23, 2013, 06:54:27 pm
Passionant... mais euh sans vouloir te vexer t'en es où exactement dans ton projet ? Parce que bon, au bout de 10 pages quasiment à toi tout seul (en exagérant à peine), j'ai du mal à voir exactement ce que tu souhaites obtenir pour une hypothétique première version. Vu de l'extérieur tu donnes l'impression de partir dans tous les sens.

Ne serait-ce pas plus cohérent de figer une "wishlist" de ce que ton projet doit comporter (exit les super nouvelles idées à implémenter tout de suite maintenant avant même que le reste ne soit fonctionnel), ce qui donnerait une idée de son état d'avancement ("fait", "à faire"), et te permettrait de terminer quelque chose de concret.

Fixe toi une liste d'objectifs et essaie de t'y tenir, parce que sinon tu n'auras jamais fini. Et puis celà sert-il à quelque choses de raconter tout ce que tu as fais/fais/voudrais faire pendant des pages et des pages ? Franchement, bosse, fais un truc solide, utilisable, utile et stable, présente-le et puis voilà...

L'idée pouvait paraître bonne, c'est pour ça que je suis ce topic, mais bon là c'est rapidement lassant...
Titre: Re : Framework
Posté par: Laurent le Décembre 23, 2013, 07:35:40 pm
1) Pourquoi diable veux-tu à tout prix recoder std::function et std::bind ?

2) Tu postes 5 messages par jour, juste pour raconter ce que tu fais, les 3/4 n'étant même pas des questions. Pourquoi n'ouvres-tu pas un blog ? Ca devient un peu chiant là. Surtout que le sujet initial de ce topic, qui ne t'appartient même pas, était tout autre (un framework communautaire, pas ton truc à toi pour lequel tu as déjà moultes topics ouverts).
Titre: Re : Framework
Posté par: Lolilolight le Décembre 23, 2013, 09:29:40 pm
Salut, non, je veux pas recoder std::function et std::bind, ce que je cherche à faire, c'est, un seul type pour toutes les sortes de fonctions. (Et pas 36 000 types différents comme le font std::bind et std::function)
De plus le mot clé auto ne marche pas en paramètre à une fonction, et encore moins en tant que variable membre.

Bref j'ai réussi à créer tous ces différents types de pointeurs de fonctions dans une seule classe donc ça c'est bon.

Ensuite je vais faire une autre classe qui se chargera de lier les valeurs des arguments des fonctions et un objet si c'est une fonction membre. (Un peu comme le font les signaux et les slots de QT avec une fonction connect.

Bref ça je dois encore le faire mais ça ne m'a pas l'air trop compliqué, donc à la fin ça donnera quelque chose comme ça : (Et je vais en profiter pour terminer en introduisant le système d'event de SFGL qui sera différents de certains autre systèmes.

Les slots :
Les slots de SFGL se crée à l'aide de la classe Function qui peut contenir un pointeur de fonction sur n'importe quel type de fonction, et appeler la fonction via l'opérateur ().
#include <iostream>
#include "myApplication.h"
#include "function.h"
using namespace std;
using namespace sfgl;
class Ex {
    public :

    static void sf() {
        std::cout<<"I'm a static member function!"<<std::endl;
    }
    void of () {
        std::cout<<"I'm an object member function!"<<std::endl;
    }

};
void f (std::string text) {
    std::cout<<"I'm a function "<<text<<endl;
}
int main () {
 Function<void(std::string)> func = &f;
    func("Text");
    Function<void()> staticMemberFunc = &Ex::sf;
    staticMemberFunc();
    Ex obj;
    Function<void(Ex*)> memberFunc = &Ex::of;
    memberFunc(obj);
    return 0;

}
 

J'ai passer les arguments des fonctions à l'opérateur (), mais, ceci n'est pas très pratique , surtout si lors d'une action on a besoin d'appeler la fonction directement à se déclaration.

SFGL possède une classe qui permet de lier les arguments et un objet si c'est une fonction membre à une fonction, cette classe s'appelle la classe signal :

Function<void(std::string)> func = &f;
Signal signal (func, "Text");
 

La classe signal est une sorte de classe bind améliorée qui permettra de contenir n'importe quel type de fonction et d'argument de fonctions à la fois, plus tard, je compte même faire en sorte que Signal permette de créer des "Function" de manière automatique, bref...

Enfin la méthode connect de SFGL permet de connecter une action à un signal :


connect (action, signal);

 

Quand l'action est déclenchée, le signal est appelé, il envoie les arguments au slot pour que le slot puisse appelé le pointeur de fonction.

Bref c'est complètement différent de std::bind qui ne fait que de créer un objets de n'importe quel type (pour cela qu'on doit utiliser le mot clé auto), et donc qui ne me permet pas de stocker mes fonctions pour les appelée plus tard avec une fonction de call back.





Titre: Re : Framework
Posté par: cobra.one le Décembre 23, 2013, 09:38:17 pm
Je trouve que tu te compliques bien la vie... je dis ça je dis rien...
Titre: Re : Framework
Posté par: Lolilolight le Décembre 23, 2013, 09:40:10 pm
Pourquoi y'a un moyen plus simple de faire ???
Titre: Re : Framework
Posté par: cobra.one le Décembre 23, 2013, 10:41:11 pm
J'ai écris un petit ensemble de classes pour architecturer un projet plaisir sur lequel je travaille à mes heures perdues. Au bout de quelques mois, j'obtiens, en résumant beaucoup, un "framework" proposant un coeur modulaire (insertion/retrait dynamiques de modules, système de communication par appels directs ou bus), et une couche IO, le tout réutilisable pour créer n'importe quel type de jeu.

Et je peux te dire que je suis loin d'être parti dans des trucs super complexes, à vouloir réinventer la roue, avec au final un résultat simple à mettre en oeuvre, stable, et suffisement performant, et surtout qui me permet aujourd'hui de progresser beaucoup plus rapidement dans le développement du "jeu" à proprement parler, et c'est le but.

Et au fait ? Ton système de signaux/slot, n'était-ce pas pour la version 2, comme dis 2/3 pages auparavant ? Il faudrait vraiment que tu songes à finaliser quelque chose de prévu pour la V1 avant d'aller papillonner à droite à gauche, là tu seras crédible. Et aussi, comme dis Laurent, à ouvrir un blog "Moi, Ma Vie, Mon Oeuvre" pour y déverser tes élucubrations...

J'interviens peu sur ce forum, car je trouve dans 99% des cas les réponses à mes questions dans la doc (très bien faite au passage), mais là j'avoue que c'est plus fort que moi. Tu me rappelles une vieille connaissance estudiantine, qui raflait toujours de superbes notes aux soutenances de projets en blablatant sur tout ce qu'il projetait de faire... et qui au final réalisait 1% de ses ambitions initiales...

Bon j'arrête là le hors-sujet...
Ce topic devrait être épinglé "culte", dans la série "Best Of", section "Nid de Coucou" !
Titre: Re : Framework
Posté par: Lolilolight le Décembre 24, 2013, 08:35:55 am
Re, hum..., la version 1 n'est pas super pratique..., dans le sens ou il manque pas mal de choses pour rendre le framework vraiment performant, et j'ai besoin d'un système de gui performant pour mon jeux, pour cela que je me consacre à la version 2, la version 1 est finie. (à part remettre un peu d'ordre dans le code et sur les noms de fonctions mais ça, c'est pas ce qui prend le plus de temps)

std::bind est bien mais il ne me permet pas de stocker les arguments d'un pointeur de fonction dans une liste pour l'appeler plus tard comme le font les signaux de Qt, bind sert juste à créer des pointeurs de fonctions, la librairie permettant de faire ce que je veux faire n'existant pas je dois l'implémenter moi même.

J'ai trouvé cependant une solution qui se rapproche du problème. (Le code source manipulant des template pack étant assez compliqué à aborder, car il faut appelle à la récursivité et à la spécialisation de template, j'ai chercher une solution sur internet)

http://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer
 

template<int ...>
    struct seq { };

    template<int N, int ...S>
    struct gens : gens<N-1, N-1, S...> { };

    template<int ...S>
    struct gens<0, S...> {
      typedef seq<S...> type;
    };
    template <typename R> struct Bind {

    };
    template <typename R, typename ...A> struct Bind <R(A...)>  {
        Bind (R(A...), A... args) {
            f = R(A...);
        }
        Function<R(A...)> f
    };
 

Finalement je crois que ça doit être faisable si j'adapte le code source de ce lien à ma structure bind. *-*
Y'a donc rien de bien compliqué là dedans.

Bref je vais arrêter de raconter ma vie sur ce topic. (Ha je serai tellement fier n'en pêche si j'arrive à recoder bind.  :D)
Et même le système de signaux et de slot de QT.

PS : enfin si il me permet de stocker les paramètre de la fonction, mais pas de stocker la fonction de manière permanente vu que bind, n'est pas une classe.

Et je n'aime pas utiliser la fonction connect de thor que je pense qu'elle permettrait aussi au développeur d'envoyer une simple variable à la fonction connect en call-back => crach. (Enfin, d'après ce que j'ai vu sur son tutoriel)

De plus le système de thor, ne permet pas de passer des arguments d'une fonction (un signal) à une autre fonction (un slot), il faut passer donc par un context sur la renderwindow ce qui complique les chose je trouve.
Moi je n'aurais qu'à faire ceci :

connect (action, objet, Bind<void>(&signal), renderwindow), objet, Bind<void>(&slot));
[/code]

Ou un truc du genre du moins car je n'ai pas encore créer la classe qui connecte tout.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 24, 2013, 09:57:21 am
Voilà c'est déjà plus simple comme ça :
template <typename R> struct Bind {

    };
    template <typename R , typename ...A> struct Bind <R(A...)> {
        Bind (R(*f)(A...), A... args) : f(f) {
               params = std::make_tuple(args...);
        }
        Bind (R(*f)(A...)) : f(f) {

        }
        template <int ...S> R operator ()() {

            return f(std::get<0>(params));
        }
        std::tuple<A...> params;
        Function<R(A...)> f;
    };
 

En même temps ça m’entraîne à manipuler les tuples.

Du coup ça me donne ceci (ça ressemble plus à unary function et à binary function en fait mais avec n'importe quel type de fonction et n'importe quel nombre d'arguments)

Bind <void(std::string)> b(&f, "text");
    b();
 

Etant donné que j'ai enfin trouvé la solution à mon problème, je vais arrêter de polluer ce topic qui de plus n'a même pas été créer par moi, et bon, était donné que j'ai déjà fait plusieurs topic sur sfgl je ne sais pas si je devrais en recréer un qui parle mais juste du projet. (Pas d'un proposement de framework communautaire)

PS : plus besoin de s'embêter avec les place holders maintenant. :) (Par contre pour la déclaration de la fonction entre <> ça, je peux pas faire autrement je pense que je suis obligé de la mettre entièrement (et pas juste préciser le type de retour de la fonction)

Mais si quelqu'un à une solution pour simplifier l'écriture je suis preneur.

Genre comme ça :
Bind <void> b(&f, "text");
    b();
 

Ou alors sans template mais je pense pas que ça soit faisable j'ai essayer ça :


template <> Bind<> {
};
 

Mais mon compilateur ne l'accepte pas.
Titre: Re : Re : Framework
Posté par: Lo-X le Décembre 24, 2013, 11:48:53 am
std::bind est bien mais il ne me permet pas de stocker les arguments d'un pointeur de fonction dans une liste pour l'appeler plus tard comme le font les signaux de Qt, bind sert juste à créer des pointeurs de fonctions, la librairie permettant de faire ce que je veux faire n'existant pas je dois l'implémenter moi même.

[...]

Bref je vais arrêter de raconter ma vie sur ce topic. (Ha je serai tellement fier n'en pêche si j'arrive à recoder bind.  :D)
Et même le système de signaux et de slot de QT.

Les signauxde Qt ne sont pas "programmés" en C++, c'est ajouté à la méta-compilation (c'est pour ça que Qt a une étape en plus  @see moc )

Tu devrais vraiment ouvrir un blog
Titre: Re : Framework
Posté par: Lolilolight le Décembre 24, 2013, 12:16:52 pm
Les signaux et slots sont un peu lourd à faire avec mon éditeur de map, je dois retaper des commandes à chaque fois que je recrée des signaux et des slots.

Bref avec sfgl les signaux et les slots pourront se créer facilement, sans avoir besoin de faire recours à la méta-compilation, d'ailleurs, les nouveautés du c++11 permettent de faire de la méta-compilation avec les template variadique mais la syntaxe reste compliquée, d'après ce que j'ai pu lire là dessus, cela se réserve à des programmeurs expérimentes.

Bref je vais ouvrir un blog là dessus je pense, en tout cas là j'ai déjà fait 2 classes : une qui stocke des pointeurs de fonctions et une autre qui stocke des pointeurs de fonction  (Function et Bind) et les arguments de fonctions, je dois encore faire 2 classes :

une qui crée des objets de type bind (Classe avec méthodes statiques (la classe Binder)) et une autre qui connecte les actions aux slots crées avec le binder.

Ensuite je fini le deuxième tutoriel de SFGL. :D (Et je pourrai m'amuser à créer n'importe quel type de gui, et de passer les paramètres des events que je veux aux slots.)

Titre: Re : Re : Framework
Posté par: cobra.one le Décembre 24, 2013, 07:32:24 pm
Ce topic est une perle !  ;D
Titre: Re : Framework
Posté par: Lolilolight le Décembre 26, 2013, 08:33:06 pm
Voilà, je vais inclure bientôt des nouveautés inédites!
Qui permettront de gérer des évènements graphique très rapidement avec sfgl::function et sfgl::bind. (L'un permet de stocker une fonction quelconque (en spécifiant juste sont type de retour), l'autre permet de stocker une fonction et des arguments :

Function<void> ptrf (&f);
ptrf(args1, arg2, ....);
Bind<void>  b (&f, arg1, arg2, ....);
b();
 

Certains pointeurs de fonction seront à définir dans certaines classes comme par exemple la classe ResourceManager pour lui passer la fonction qui se chargera de charger les ressources.

D'autres devront être utilisé pour le système d'évènements avec les interfaces graphiques.

Je compte prévoir aussi un système de placeholders qui pemettra de ne pas devoir spécifier tout les arguments à bind dès la déclaration du pointeur de fonction.



 
Titre: Re : Framework
Posté par: Lolilolight le Décembre 27, 2013, 12:03:40 pm
Bon, j'ai rien dis, je vais en revenir à std::function et à std::bind.  :P

Je pensais que ce code-ci s'exécuterait :

#ifndef FUNCTION
#define FUNCTION
namespace sfgl {
template<typename R> class Function {
    public :
    template <typename ...A>  Function (R(*f)(A...)) : function(&f) {

    }
    template <typename ...A> R operator()(A... args) {
        R(*func)(A...) = *reinterpret_cast<R**>(&function);

        return func(args...);
    }
    private :
    R* function;
};
 
Mais en fait non de plus j'ai du rajouté l'option -fpermissive pour que ça compile donc je sais pas si c'est une bonne idée de caster un void* en pointeur de fonction.

Voici ce que me donne le débugueur :
#0 0028FEBD ?? () (??:??)
#1 004010FD __mingw_CRTStartup () (??:??)
#2 00401295 mainCRTStartup () (??:??)

PS : de plus il me semble qu'on ne peut pas faire ça avec des fonctions membres.
Titre: Re : Framework
Posté par: Lolilolight le Décembre 27, 2013, 12:41:27 pm
Avec std::function et std::bind y'a pas moyen non plus :

function<void()> func = std::bind(&f, placeholders::_1);
Signal s(func);
s.emit("text");
 

Ce code ne compile pas.

Le mien compile par contre avec -fpermissive mais provoque un crash.

Bref je pense que je vais devoir abandonner mon idée, et passer à un type de fonction bien précis.

Mais avant de faire ça, je vais finir la version 1.
Titre: Re : Framework
Posté par: Canadadry le Décembre 27, 2013, 04:01:12 pm
Si tu veux faire des signaux slots en C++ t'as deux solutions :

Pour ce qui est de stocker les arguments regarde l'exemple. C'est faisable avec un tuple et des variadic template.

Et s'il te plais arrête tes monologues.   :)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 27, 2013, 08:50:50 pm
Ok, oui je sais que c'est faisable pour stocker les arguments je l'ai même fait, c'est pour stocker un pointeur sur une fonction quelconque que apparemment ce n'est pas faisable. (Ce que je trouve dommage)
Titre: Re : Framework
Posté par: Nexus le Décembre 28, 2013, 12:23:22 am
Comme je t'ai déjà dit, il faut apprendre les concepts de std::function avant de l'utiliser. Ca sert à rien si nous repondons toutes tes questions et expliquons chaque détail, juste parce que tu n'as pas envie de lire la documentation...
Titre: Re : Framework
Posté par: Lolilolight le Décembre 28, 2013, 01:25:02 pm
Je l'ai lue le peu de doc que j'ai trouvé sur ce sujet mais c'est bon je vais m'en sortir..., il faut juste que je fasse une classe qui lie un id à un signal, afin de faire un contenaire de signaux.
Et comme je te dis j'ai essayer de faire un pointeur sur une fonction quelconque afin de stocker et std::function<void()> et l'appeler plus tard en lui passant des arguments, mais, y'a pas moyen std::function<void()> en fait c'est juste un foncteur et pas une fonction.

Mais je ne sais pas ou tu l'a trouvé la doc sur std::function parce que moi j'en ai pas trouvé beaucoup.
Titre: Re : Re : Framework
Posté par: Nexus le Décembre 28, 2013, 03:54:42 pm
Mais je ne sais pas ou tu l'a trouvé la doc sur std::function parce que moi j'en ai pas trouvé beaucoup.
Vraiment?

http://en.cppreference.com/w/cpp/utility/functional
http://www.cplusplus.com/reference/functional/function
http://msdn.microsoft.com/en-us/library/bb982519.aspx
http://www.boost.org/doc/libs/1_55_0/doc/html/function.html
...
Titre: Re : Framework
Posté par: Lolilolight le Décembre 29, 2013, 10:00:41 am
J'ai réussi!  :D

Par contre le code source n'est pas simple à comprendre.

#ifndef FUNCTION
#define FUNCTION

namespace sfgl {
namespace helper {
    template<int ...> struct seq {};

    template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};

    template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };
}
template<typename R> class Function {
    public :
    template <typename ...A>  Function (R(*f)(A...)) : function(&f) {

    }
    template <typename ...A> R operator()(A... args) {
        R(*func)(A...) = *reinterpret_cast<R**>(function);
        std::tuple<A...> params = std::make_tuple(args...);
        return  callFunc(typename helper::gens<sizeof...(A)>::type(), params);
    }
    template<int ...S,typename ...A>
    R callFunc(helper::seq<S...>, std::tuple<A...> params)    {
         R(*func)(A...) = *reinterpret_cast<R**>(function);
        return f(std::get<S>(params) ...);
    }
    private :
    R** function;
};
 

Ce que je voulais faire c'est wrapper n'importe quel type de pointeur sur fonction pour l'appeler plus tard.

Afin de wrapper ensuite ces pointeurs de fonctions dans un conteneur avec un id ainsi j'appelle le bon pointeur de fonction en passant l'id du pointeur de fonction au conteneur.

void f (std::string text, std::string text2) {
    std::cout<<"I'm a function "<<text<<" "<<text2<<endl;
}
int main () {
    std::map<std::string, Function<void>> ptrfunc;
    Function<void> f1 = &f;
    ptrfunc.insert(std::pair<std::string, Function<void>>("Fonction test", f1));
    std::map<std::string, Function<void>>::iterator it = ptrfunc.find("Fonction test");
    it->second("text1", "text2");
    return 0;
}
 

Ainsi je stocke tout mes signaux dans un conteneur en les liant à une action, et lors du déclenchement d'un event, j'appelle la bonne fonction suivant son id en lui passant les paramètres que je veux.

Je ne sais pas si cette technique peut marcher avec les fonctions membres par contre. (Faut que je continue mes tests)

Et d'après ce que j'ai pu lire, std::function et std::bind ne permettent pas de faire ça. :/ (Voilà de quoi je parlais quand je disais "faire mieux que std::function".)
Titre: Re : Framework
Posté par: Lolilolight le Décembre 29, 2013, 01:55:54 pm
Lol, juste lol, j'ai du remplacer les std::string par des char* pour les arguments de ma fonction f pour que ça marche. (Sinon ça crash)

Le temps est venu de revenir au C les amis.  :D



Titre: Re : Framework
Posté par: cobra.one le Décembre 29, 2013, 05:09:13 pm
Passionant...