Bienvenue, Invité. Merci de vous connecter ou de vous inscrire. Avez-vous oublié d'activer ?

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - Lolilolight

Pages: « Précédente 1 [2] 3 4 ... 53 Suivante »
16
Bon, ce n'est que le début parce que là j'ai juste de quoi avoir maison et voiture à 26 ans avec quelques loisirs en plus quand même.

Bon, je vise plus haut après bien sûr, car il me faut un garde du corps, une limousine, une maison de luxe comme celle du développeur de mine craft et tant que je suis dans mon délire et que je me lâche, pourquoi pas ma 1ère petite copine!!! é_é  :D (Après 5 ans de pur développement à développez pendant 11 heures par jour derrière un fichu PC)

Haaaa si seulement la vie était si belle!!!

Laurent Gomilla sera tellement jaloux qu'il va encore plus me troll avec ses messages du genre : "Met un code minimal" ou bien fermera encore mes topiques parce que ça part en sucette. :o

Non mais plus sérieusement, ça coûte la peau des fesses en Belgique, parfois je me demande, pourquoi je ne me retrouve pas à la rue ? :o

Le seul avantage c'est que les soins sont remboursé mais maintenant c'est devenu partout pareil surtout avec OBAMA.

Voici quelque vidéos  pour les rendus :

Ici

Ici

Et ici en 3D.

A venir, les 1er jeux (enfin), mais je suis encore un petit peu loin de la version commerciale pour parler de richesse, car, il me faut encore faire un site de vente en ligne dans un 1er temps ensuite bien sûr, terminer d'ajouter les dernières fonctionnalités du moteur en priant pour qu'il se vende, et pour avoir ainsi assez pour héberger les futurs projets commerciaux. :o

Et comme je dois me charger de tout ça tout seul, c'est pas pour demain.

Mais a 30 ans j'espère!








17
Sortie de la release 1.0 et optimisations pour la version pro.

Quelques nouvelles :

Le moteur va devenir payant, cependant le code source de la version 1.0 restera disponible sur la plateforme git mais risque de ne pas bien fonctionné pour les rendus plus complexe et ne sera plus maintenu.

Objectif de la version payante ?

L'optimisation, et l'amélioration des rendus, en effet :

La version actuelle utilise beaucoup de shaders, le FPS est bas, et les shaders dépendent de la compatibilité avec la carte graphique. :/

Lors de la version pro je compte faire tout les calculs ainsi que toutes les textures de rendus avec le CPU.
Mais on pourra bien sûr encore utiliser le GPU, pour afficher le framebuffer dans une fenêtre SFML par exemple ou bien SDL.

La version pro vise un rendu complexe en peu de temps, donc, le moteur utilisera son propre système de rasterisation, ainsi, plus besoin de récupérer le pixel dans un shader avec une texture de rendu et de faire pleins de if.

En effet, le moteur positionnera la vue à la position des lumières pour générer les ombres pour les fragments qui sont dans le champs de vision de la caméra et convertira les coordonnées des fragments de la vue de la lumière à la vue de la caméra pour les ombres. (Chose qu'il est plus difficile de faire avec les textures de rendu)

Le moteur gérera aussi la réfraction (effet de miroir) et la disfraction de la lumière.

PS : par contre je ne sais pas si il est possible d'afficher une image directement sur la fenêtre avec SFML, au pire, j'afficherai la framebuffer avec un sprite dans la fenêtre.

L'avantage de se système : aucune connaissance de openg, de la SFML ou bien de la SDL sera requise, juste une connaissance du langage c++.
Le moteur sera compatible peu importe la plateforme utilisée.
Le moteur permettra de faire de beau rendu en peu de temps (aussi possible avec opengl mais plus compliqué car nécessite d'avoir une très bonne connaissance d'opengl et un driver qui supporte les versions modernes de opengl (je n'ai pas cette version))

Le framework va aussi bien sûr changer de nom.

Voici un aperçu de ce que le framework sera capable d'afficher :

http://www.massal.net/article/raytrace/page5.html

18
Je voudrais réagir suite à une remarque qui a été faîtes sur le forum Anglais au sujet d'une ombre. (celle d'un mur)

Je viens juste d'ajouter la possibilité de pouvoir changer le type d'ombre pour les murs, pour les murs qui se suivent donc j'utilise des shapes pour afficher les ombres, pour les murs qui ne se suivent pas, (comme l'unique mur près du feu de bois qui paraissait étrange), j'utilise un sf::Sprite ce qui rend beaucoup mieux!

On a donc maintenant le choix pour les modèles lors la génération d'une sf::Shape pour l'ombre ou bien d'un sf::Sprite.
Wall* w = new odfaeg::g2d::Wall(3, 80, t,odfaeg::g2d::AmbientLight::getAmbientLight(), odfaeg::g2d::Shadow::SHADOW_TYPE::SHADOW_TILE);
 
Je vais update le git-hub dès que possible, ici je suis entrain de mettre des commentaires partout pour générer la doc et ensuite je séparerai le code du mieux que je peux et je dois aussi rendre le linkage dynamique fonctionnel, et enfin je pourrai poster plus de vidéos!
J'essaye d'utiliser RAII et std::function le plus possible, et j'ai changé complètement ma classe FastDelegate. (Suite aux remarques qui ont été faîtes sur le forum Anglais à se sujet)

19
Finalement je pense que tu aurais pu utiliser des template, en fait, le principe est très simple :

-Tu enregistres chaque fonction et chaque classe de tes fonctions membres dans une factory en associant à chaque classe et à chaque fonction, un id unique que l'utilisateur (ou bien toi même) utilisera pour appeler la fonction à l'exécution.
Et tu fait une genre de méthode init() comme le fait SDL qui enregistre les fonctions appelée par ta librairie pour dessiner par exemple, bref tu enregistres ce que tu veux quoi. (Il faut passer le nom de la classe en paramètre template à la factory)
Le principe est fort similaire à celui des dll.
Bref moi c'est ce que j'utilise pour faire, un système de réflexion portable.

Ceci à l'avantage que peut importe le nom de la classe de base utilisée pour dessiner, l'utilisateur pourra choisir n'importe quelle type pour la classe de base à condition qu'il l'enregistre dans la factory à l'initialisation de SFML sinon il faudra renvoyer une exception.

Pour le bien tu devrais aussi utiliser std::function pour enregistrer les pointeurs sur tes fonctions de callback, ce qui donnerait quelque chose comme ceci :

#ifndef ODFAEG_FAST_DELEGATE_HPP
#define ODFAEG_FAST_DELEGATE_HPP
#include <functional>
#include <iostream>
#include "export.hpp"
#include "erreur.h"
#include <tuple>
#include <utility>
#include <memory>
/**
  *\namespace odfaeg
  * the namespace of the Opensource Development Framework Adapted for Every Games.
  */

namespace odfaeg {
/**
*  \file  fastDelegate.h
*  \class IRefVal
*  \brief Interface for the warppers to references, values and pointers.
*  This class is used store references, pointers and values to pass to the callack's functions.
*  \param T : the type of the value to wrap.
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

template<class T>
struct IRefVal {
    /**\fn
    *  \brief default constructor
    */

        IRefVal()=default;
        /**\fn T& get()
        *  \brief get the reference of the wrapped type.
        *  \return the reference of the wrapped type.
        */

        virtual T& get() =0;
        /**\fn std::unique_ptr<IRefVal<T>> clone() const = 0;
        *  \brief copy the wrapper.
        *  \return the copied wrapper.*/

        virtual std::unique_ptr<IRefVal<T>> clone() const = 0;
        /**\fn destructor*/
        virtual ~IRefVal(){}

protected:
    /**\fn IRefVal(const IRefVal&)
    *  \brief constructor, pass the reference to wrap.
    *  \param const IRefVal& : the reference to wrap.
    */

        IRefVal(const IRefVal&){}
        /** \fn IRefVal& operator=(const IRefVal&)
        *   \brief affector.
        *   \param const IRefVal& : the wrapper to affect.
        *   \return the affected wrapper.*/

        IRefVal& operator=(const IRefVal&)
        { return *this; }
};
/**
*  \file  fastDelegate.h
*  \class Ref
*  \brief Warp a reference. (Use std::reference_wrapper so we can pass a reference with std::ref)
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

template<class T>
struct Ref : IRefVal<T> {
    /**
    *\fn Ref(const std::reference_wrapper<T>& r)
    *\brief Constructor : pass an std::reference_wrapper to the wrapper.
    *\param std::reference_wrapper<T>& r : the reference_wrapper.
    */

        Ref(const std::reference_wrapper<T>& r)
                : ref(r)
        {}
        /**
        * \fn T& get()
        * \brief return a reference to an object.
        * \return T& the reference to the object.
        */

        T& get()
        { return ref.get(); }
        /**
        * \fn std::unique_ptr<IRefVal<T>> clone() const
        * \brief copy the reference wrapper.
        * \return std::unique_ptr<IRefVal<T>> : the cloned wrapper.
        */

        std::unique_ptr<IRefVal<T>> clone() const
        { return std::make_unique<Ref>(*this); }
private:
        std::reference_wrapper<T> ref; /**> the std::reference_wrapper which warp the reference.*/
};
/**
*  \file  fastDelegate.h
*  \class Val
*  \brief Warp a value.
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

template<class T>
struct Val : IRefVal<T> {
    /**\fn Val(const T& t)
    *  \brief pass a value to the wrapper.
    *  \param const T& t : the value to pass.
    */

        Val(const T& t)
                : val(t)
        {}
        /** \fn
        *   \brief return the value
        *   \return T& : return the value.
        */

        T& get()
        { return val; }
        /**
        * \fn std::unique_ptr<IRefVal<T>> clone() const
        * \brief copy the value wrapper.
        * \return std::unique_ptr<IRefVal<T>> : the cloned wrapper.
        */

        std::unique_ptr<IRefVal<T>> clone() const
        { return std::make_unique<Val>(*this); }
private:
        T val; /**> T val : keep the value of the wrapper.*/
};
/**
*  \file  fastDelegate.h
*  \class Ref
*  \brief Warp a pointer.
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

template<class T>
struct Pointer : IRefVal<T> {
    /**\fn Pointer(const T* t)
    *  \brief pass a pointer to the wrapper.
    *  \param const T* t : the pointer to pass.
    */

        Pointer(const T* t)
                : pointer(t)
        {}
        /** \fn
        *   \brief return the pointer of the wrapper.
        *   \return T& : return the pointer.
        */

        T& get()
        { return pointer; }
        /**
        * \fn std::unique_ptr<IRefVal<T>> clone() const
        * \brief copy the pointer wrapper.
        * \return std::unique_ptr<IRefVal<T>> : the cloned wrapper.
        */

        std::unique_ptr<IRefVal<T>> clone() const
        { return std::make_unique<Pointer<T>>(*this); }

private:
        T pointer; /**> T pointer : keep the pointer of the wrapper.*/
};
/**
*  \file  fastDelegate.h
*  \class RefVal
*  \brief Wrap a pointer, a value or a reference an keep a pointer to the generic wrapper.
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

template<class T>
struct RefVal {
    /**
    * \fn RefVal (const T& t)
    * \brief constructor : construct a wrapper to a value
    * \param const T& t : the value to
    */

        RefVal(const T& t)
        : rv(std::make_unique<Val<T>>(t))
        {}
        RefVal(const std::reference_wrapper<T>& r)
        : rv(std::make_unique<Ref<T>>(r))
        {}
        RefVal(const T*& p)
        : rv(std::make_unique<Pointer<T>>(p))
        {}
        RefVal(const RefVal& rhs)
    {
        rv = rhs.rv->clone();
    }
        RefVal& operator=(const RefVal& rhs)
        { rv=rhs.rv->clone(); return *this; }
        T& get() const
        { return rv->get(); }

private:
        std::unique_ptr<IRefVal<T>> rv;
};
//Classe de trait pour déterminer le type à stocker

//(Interne) Cas général
template<class T>
struct ToStoreImpl
{ using type = T; };

template<class T>
struct ToStoreImpl<std::reference_wrapper<T>>
{ using type = T; };

template<class T>
struct ToStore
        : ToStoreImpl<std::remove_reference_t<T>>
{};

template<class T>
using ToStore_t = typename
        ToStore<T>::type;
template<class R, class C, class... ArgT>
struct DynamicWrapper {
        DynamicWrapper(R(C::*pf)(ArgT...)) : pfunc(pf){}
        template<class O, class... ArgU>
        R operator()(O* o, ArgU&&... arg) const
        {
                if(dynamic_cast<C*>(o))
                        return (dynamic_cast<C*>(o)->*pfunc)(std::forward<ArgU>(arg)...);
        throw Erreur(0, "Invalid cast : types are nor polymorphic!", 1);
        }
private:
        R (C::*pfunc)(ArgT...);
};
template<class F>
class DynamicFunction;

template<class R, class... ArgT>
class DynamicFunction<R(ArgT...)>
        : std::function<R(ArgT...)>
{
        using Base = std::function<R(ArgT...)>;

public:
        template<class F>
        DynamicFunction(F&& f) : Base(std::forward<F>(f))
        {}
        template<class C, class... ArgU>
        DynamicFunction(R (C::*pf)(ArgU...))
                : Base(DynamicWrapper<R,C,ArgU...>(pf))
        {}
    using Base::operator();
};
template<class R>
struct Delegate {
        Delegate() =default;
        virtual std::unique_ptr<Delegate> clone() const = 0;
        virtual R operator()() = 0;
        virtual ~Delegate(){}

protected:
        Delegate(const Delegate&){}
        Delegate& operator=(const Delegate&)
        { return *this; }
};

template<class R, class... ArgT>
struct FastDelegateImpl : Delegate<R> {
    template<class F, class... ArgU>
        FastDelegateImpl(F&& f, ArgU&&... arg)
                : func(std::forward<F>(f))
                , param(std::forward<ArgU>(arg)...)
        {}
        std::unique_ptr<Delegate<R>> clone() const
        { return std::make_unique<FastDelegateImpl>(*this); }
        R operator()()
        { return call(std::make_index_sequence<sizeof...(ArgT)>()); }
        template<class... ArgU>
        void setParams(ArgU&&... arg)
        { param=std::make_tuple(std::forward<ArgU>(arg)...); }

private:
        template<std::size_t... I>
        R call(std::index_sequence<I...>)
        { return func(std::get<I>(param).get()...); }

        std::function<R(ArgT&...)> func;
        std::tuple<RefVal<ArgT>...> param;
};
template<class R>
struct FastDelegate {
    FastDelegate() = default;
    template<class F, class... Arg>
        FastDelegate(F&& f, Arg&&... arg) :
                delegate(std::make_unique
                        <FastDelegateImpl<R,ToStore_t<Arg>...>>
                        (std::forward<F>(f),std::forward<Arg>(arg)...)
                )
        {}
        FastDelegate(FastDelegate& rhs)
                : delegate(rhs.delegate->clone())
        {}
        FastDelegate(const FastDelegate& rhs)
                : delegate(rhs.delegate->clone())
        {}
        FastDelegate(FastDelegate&& rhs) =default;
        FastDelegate& operator=(const FastDelegate& rhs)
        { return operator=(FastDelegate(rhs)); }
        FastDelegate& operator=(FastDelegate&&) =default;
        R operator()() const
        { return (*delegate)(); }
        template<class... Arg>
        void setParams(Arg&&... arg)
        {
                using StaticType =
                        FastDelegateImpl<R,ToStore_t<Arg>...>*;
                static_cast<StaticType>(delegate.get())->setParams(std::forward<Arg>(arg)...);
        }
private:
        std::unique_ptr<Delegate<R>> delegate;
};
}
#endif
 

//fichier fabrique.h
#ifndef ODFAEG_FACTORY_HPP
#define ODFAEG_FACTORY_HPP
#include <map>
#include <string>
#include "export.hpp"
#include "fastDelegate.h"
/**\file factory.h
*  \brief This file register types of derived objects
*  and instanciate the polymorphic objects of the right type with the given type id.
*  There are two factories
*  The static factory (The class Factory) which evaluate objects and functions at compile time.
*  The dynamic factory (The class BaseFactory) which evaluate objects and functions at runtime.
*  The dynamic factory avoids to have a reflexion system which is impossible to make in c++ without a lot of macros.
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

/********************************************************************************************************************/
/**\fn
* \brief This is an helper function like macro which register a derived type in the dynamic factory.
* \param ID : an ID which is associate to a derived type.
* \param BASE : the base type of the derived class.
* \param DERIVED : the derived type of the derived class.
*/

#define REGISTER_TYPE(ID, BASE, DERIVED) \
{ \
DERIVED *derived##ID = nullptr; \
odfaeg::Allocator<BASE> allocator##ID; \
BASE*(odfaeg::Allocator<BASE>::*f##ID)(DERIVED*) = &odfaeg::Allocator<BASE>::allocate<DERIVED>; \
odfaeg::FastDelegate<BASE*> allocatorDelegate##ID(f##ID, &allocator##ID, derived##ID); \
odfaeg::BaseFact<BASE>::register_type(typeid(DERIVED).name(), allocatorDelegate##ID); \
}

/**fn
* \brief This is an helper function like macro which register a function in the dynamic factory.
* \param ID : an ID which is associate to a derived type.
* \param funcName : the name of the derived class member's function to register.
* \param SID : an ID associated to the argument list of the member's function to register.
* \param BASE : the base type of the derived class.
* \param DERIVED : the derived type of the derived class.
* \param SIGNATURE : the signature of the function to register.
*/

#define REGISTER_FUNC(ID, funcName, SID, BASE, DERIVED, SIGNATURE, args...) \
{ \
REGISTER_TYPE(ID, BASE, DERIVED) \
void(DERIVED::*f##ID##funcName##SID)SIGNATURE = &DERIVED::vt##funcName; \
odfaeg::FastDelegate<void> delegate##ID##funcName##SID (f##ID##funcName##SID, args); \
odfaeg::BaseFact<BASE>::register_function(typeid(DERIVED).name(), #funcName, #SID, delegate##ID##funcName##SID); \
}

/**
  *\namespace odfaeg
  * the namespace of the Opensource Development Framework Adapted for Every Games.
  */

namespace odfaeg {
/**\class Factory
*  \brief This class register types of derived objects
*  and instanciate the polymorphic objects of the right type with the given type id.
*  This is a static factory, it means that the id is defined at compile time.
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

template <class O, class K = std::string>
class Factory {
private :
     static std::map<K, O*> m_map;
public:
     static void Register (K key, O* object);
     O* Create (const K& key);
};
/**\class Allocator
*  \brief this struct allocate an object of a derived type and return a pointer of the base type.
*  \param B : the base type.
*/

template <typename B>
struct Allocator {
   /**\fn allocate(D*)
   *  \brief this function allocates an object of a derived type and return a pointer of the base type.
   *  \param D : the derived type.
   *  \return B* : a pointer to the base type.
   */

   template <typename D>
   B* allocate(D*) {
        return new D();
   }
};
/**\class BaseFactory
*  \brief This class register types of derived objects
*  and instanciate the polymorphic objects of the right type with the given type id.
*  This is a dynamic factory, it means that the id is defined at runtime time with RTTI infos.
*  So you must provide the id with typeid(object).name().
*  \author Duroisin.L
*  \version 1.0
*  \date 1/02/2014
*/

template <typename B>
class BaseFactory {
    public :
    /**
    * \fn void register_type (std::string typeName, FastDelegate<B*> allocatorDelegate)
    * \brief register a type into a factory, if the type isn't already registered.
    * \param std::string typeName : the name of the type to register.
    * \param a callback function to an allocator, to return a pointer of the base class which point
    * to the derived object.
    */

    static void register_type(std::string typeName, FastDelegate<B*> allocatorDelegate) {
        typename std::map<std::string, FastDelegate<B*>>::iterator it = types.find(typeName);
        if (it == types.end()) {
            types[typeName] = allocatorDelegate;
        }
    }
    /** \fn void register_function(std::string typeName, std::string funcName, std::string funcArgs, FastDelegate<void> delegate)
    *   \brief register a member function of a class type into the factory.
    *   \param std::string typeName : the type name of the class containing the member function to register.
    *   \param std::string funcName : the name of the function to register.
    *   \param std::string funcArgs : the name of the types of the member function's argument list to register.
    *   \param FastDelegate<void> delegate : a callback function of the registered member function. (only funcions returing void can be registered!)
    */

    static void register_function(std::string typeName, std::string funcName, std::string funcArgs, FastDelegate<void> delegate) {
        typename std::map<std::string, FastDelegate<void>>::iterator it = functions.find(typeName+funcName+funcArgs);
        if (it == functions.end())
            functions[typeName+funcName+funcArgs] = delegate;
    }
    /** \fn void callFunction(std::string typeName, std::string funcName, std:string fincArgs, A&&... args)
    *   \brief call a registered function of the factory, throw an error if the function isn't registered.
    *   \param std::string typeName : the type name of the class containing the member function.
    *   \param std::string funcName : the name of the member function.
    *   \param std::string funcArgs : the name of the types of the member function's argument list to call.
    *   \param A&& args.... : the value of the arguments to pass to the callback's member function. (object + arguments)
    */

    template <typename... A>
    static void callFunction(std::string typeName, std::string funcName, std::string funcArgs, A&&... args) {
        typename std::map<std::string, FastDelegate<void>>::iterator it = functions.find(typeName+funcName+funcArgs);
        if (it != functions.end()) {
            it->second.setParams(std::forward<A>(args)...);
            (it->second)();
        } else {
            throw Erreur(0, "Unregistred function exception!", 1);
        }
    }
    /** \fn B* create (std::string typeName)
    *   \brief return a pointer of the base class of an object which point to an object of a derived type.
    * this function call a callback function to an allocator function to allocate the object.
    *   \param the typeName of the type to allocate.
    *   \return B* a pointer of a base class which'll point to the allocated object.
    */

    static B* create (std::string typeName) {
        typename std::map<std::string, FastDelegate<B*>>::iterator it = types.find(typeName);
        if (it != types.end()) {
            return (it->second)();
        }
        throw Erreur(0, "Unregistred type exception!", 1);
    }
    /** \fn std::string getTypeName (B* type)
    *   \brief return the type name of a base object.
    *   \param B* type : a pointer to the type to check the dynamic type name.
    *   \return the dynamic type name of the passed object*/

    static std::string getTypeName (B* type) {
        typename std::map<std::string, FastDelegate<B*>>::iterator it = types.find(typeid(*type).name());
        if (it != types.end())
            return it->first;
    }
    private :
    static std::map<std::string, FastDelegate<B*>> types; /**> An std::map which store the typeName and a callback's function to an allocator of the registered types*/
    static std::map<std::string, FastDelegate<void>> functions; /**> An std::map which store the signature and a callback's function to the registered member's functions.*/
};
template <typename B>
std::map<std::string, FastDelegate<B*>> BaseFactory<B>::types = std::map<std::string, FastDelegate<B*>>();
template <typename B>
std::map<std::string, FastDelegate<void>> BaseFactory<B>::functions = std::map<std::string, FastDelegate<void>>();
}
#endif
 

Ensuite tu n'as plus qu'à faire une fonction SFML_Init() pour enregistrer toutes les classes et fonctions template utiliser par SFML.

Donc je pense que tu pourrais améliorer SFML à l'avenir, et utiliser le c++14. ;) (Ne t'inquiète pas pour la compatibilité, normalement tout les PC supportent gcc4.9 et d'aileurs c'est la version de gcc qu'on devrait tous utiliser pour des raisons de sécurité, et éviter les nombreux memory leaks et problème d'UB présent encore dans certaines libs écrite en C utilisant SFML mais aussi parfois dans SFML.

20
Je n'en met pas maintenant, j'ai des choses plus urgentes à faire pour la bibliothèque : réorganisation des fichiers, génération de la docs et finir de commenter le code source, et le site web afin de faire une librairie digne de son nom tout comme SFML. (Et réorganisation du répertoire git-hub pour un meilleur usage)

J'en ai aussi profiter pour utiliser std::function les outils pour la gestion automatique de la mémoire.

Je mettrai à jour le git-hub quand j'aurai fini. (juste avant de commencer le site web)

De plus je dois m'arranger aussi pour le nom de domaine avec une connaissance du web.

Donc vous comprenez bien que j'ai trop de boulot pour encore faire des vidéos ou bien des images.

21
Ha oui c'est vrai, j'ai update les liens, merci de me l'avoir signalé!

J'ai changé mon système pour la sérialisation, car, mon précédent système causait trop de problème à cause des forward déclarations.

J'en ai profiter pour faire "un genre" de système de réflexion, et je dis bien un "genre" car n'ayant pas de système de réflexion intégré dans le language comme en java, je dois enregistrer les types et les fonctions à la main.

Il y a peut être moyen de le faire automatiquement mais je ne connais pas la technique.

22
Ok, je me demandais si c'était possible de faire ça dans ta librairie. (ou pas.)


23
I can see one advantage by using a template :

Your library'll be more customizable, by example, if you want that the user can change a part of your library. (With a variadic template class, a wrapper and a macro by example)
He'll be able to change a part of the source code of your library automatically.

I use this mecasim to serialize a lot of different variables type onto different kind of archives in my library.
So I don't need to have to overload the functions for each object type to serialize, it's very paintfull when they are a lot of them.

If the user want to change the library. (by example by creating a class which derive from a class of the library and serialize it)  He can do it with a macro before including your library. (This'll change the class definition thanks to the variadic template and the variadic macro)

But there's also an inconvenient, so this mecanism should be used only if you have no other choices :

-The code'll take more time to compile. (maybe you'll need to use short and inlined functions)
-You'll have to recompile your library automatically if the source code of your library change. (But normally it shoudn't change a lot if the user have a well analized it)

I hope that c++'ll still increase the powerfullness of his meta-programmation system to be able to modify libraries at compile time! (But I don't think that SFML need it, in Laurent Gomila's case, inheritence is normally sufficient)

But anyway I look forward to the futur of the c++ future, this looks so promising, I would like to define some code in my library that the user can modify and some other source code that the user can't modify and change the name of my library to ODCFAEG (Opensource Developement Customizable Framework Adapted For Every Game)


-

24
Projets SFML / Passage de la librairie en "header only" prochainement.
« le: Août 19, 2014, 07:02:19 pm »
Re, hum..., j'ai quelques soucis actuellement avec les objets polymorphique qui en utilise d'autres, si je change la définition d'une classe de la librairie en compilation à l'aide d'une macro, je dois forcément recompiler la librairie sinon ça crash. (Car lé définition de la classe ne correspond plus avec ce qu'il y a dans le fichier .a.

Mais je veux garder le côté "méta-programmation" qu'offre le c++11 et que je trouve très pratique (ça m'évite de devoir passé par un système de réflexion et c'est plus rapide à l'exécution)

Par exemple lors de la sérialisation, si je décide de rajouter une classe dérivée à une classe de base je change la définition du wrapper du fichier .h de la librairie en redéfinissant une macro de la librairie dans mon projet utilisant la librairie. (Exactement comme le fait boost)

Je pense que la seule solution pour éviter d'avoir un crash est de rendre ma librairie "header only". (Ainsi si je modifie la définition de la classe, pas besoin de recompiler toute la librairie! (Ou bien de modifier le header de la librairie à la main)

25
Projets SFML / Re : SimpleGui
« le: Août 19, 2014, 06:49:38 pm »
Ok, je comprend mieux maintenant.

26
Projets SFML / Re : SimpleGui
« le: Août 18, 2014, 10:09:54 am »
Ha oké on peut transféré le contenu d'un shared pointer dans un autre, je ne savais pas que l'on pouvait faire ça, comme je te l'ai dis je pensais que un shared pointer ne faisait que compter les occurrences et détruire automatiquement le pointeur lorsqu'il ne pointait plus sur rien.

Bref, ça me sera utile. :)

Les std::unique_ptr c'est donc quand le contenu du pointeur ne peut pas être copié.

Merci pour ses infos.


27
Projets SFML / Re : SimpleGui
« le: Août 16, 2014, 02:05:45 pm »
Tu arrives à faire des callback avec des lambdas , même avec des fonctions callback qui prennent des arguments et rappeler plusieurs fois la fonction callback avec des arguments différents ?
Bref moi j'ai fais un système qui permet de faire ça, c'est un genre à std::bind à part que tu peux stocker le wrapper sur le pointeur de fonction dans un contenaire et le connecter à un identifiant afin de changer la valeur des arguments avant chaque appel de la fonction callback. (Utile pour passer des informations sur les événements à la fonction de callback)
Mais mon système gère aussi les fonctions anonyme. (Et donc les lambdas)

Je pense même que je vais faire une interface comme en java du style ActionListener en lui passant le bouton qui a été cliqué en paramètre à une fonction que l'on pourra redéfinir.

Pour copier un objet il te faut en réallouer un nom ? (Et pas juste copier l'adresse du bouton)
Ou alors, j'ai loupé quelque chose ???

PS : à moins que tu utilises std::move ???
Dans ce cas là, les std::unique_ptr et les std::shared_ptr me semblent en effet plus appropriés. (D'ailleurs je me demande si je ne vais pas essayer de les utiliser aussi mais je les comprends pas encore assez bien pour ça)


Non j'ai dis une connerie std::move fais juste un transfert de donnée, pas une copie.

J'ai enfin trouvé un bonne article (en Anglais) qui m'a éclairé sur le sujet.
http://www.codeproject.com/Articles/570638/Ten-Cplusplus-Features-Every-Cplusplus-Developer

Je ne savais pas que avec un std::shared on pouvait copier je pensais que ça contenais juste un compteur qui comptait le nombre de fois que le pointeurs était utilisé dans le programme.

28
Projets SFML / Re : SimpleGui
« le: Août 15, 2014, 05:00:26 pm »
Il y avait une erreur dans mon algorithme désolé, voici le bon code :

class Widget {
void exampleMethod (BaseInterface& bi) {
    for (unsigned int i = 0; i < children.size(); i++) {
           children[i]->inheritedExampleMethod(*static_cast<Widget&>(bi).children[i]);
    }
}
virtual void inheritedExampleMethod(Widget &w) = 0;
};
 

Et dans la classe bouton :
class Button : public Widget, public Interface<Button> {
    Button() : Interface<Button>(*this) {}
    void exampleMethod(Widget& w) {
            inheritedExampleMethod(static_cast<Button&>(w));
    }
    void inheritedExampleMethod(Button &button) {
             //Définition de la méthode ici.
    }
};
 

Voilà.  :)

29
Projets SFML / Re : SimpleGui
« le: Août 15, 2014, 11:22:18 am »
Salut.

Les std::make_shared c'est bien mais que se passerait t'il si on a envie de cloner un bouton et si en plus la classe bouton dérive de la classe Widget ???
A tu prévus un fonction pour ???

Ne vaudrait t'il pas mieux partir sur un design de ce genre ?


class BaseInterface {
     public :
     void addChild(Widget* w) {
        children.push_back(w);
     }
     virtual
     std::vector<Widget*> getChildren() {
        return children;
     }
     std::vector<Widget*> children;
};
template <typename T>
class Interface : public BaseInterface  {
    public:        using DataType = T;
        DataType /* const */ & data() /* const*/{return t_;}

    protected:
        Interface(T & t) : t_(t){}
        const T& clone(const T& i) {
                   const T* c = new T(i);
                   return *c;
        }
        virtual  ~Interface(){}

        //~Interface(){}
    private:
        T & t_;
};
class Widget : public BaseInterface {
    //Définition de la classe.
    virtual void exampleMethod (BaseInterface& bi) {
    for (unsigned int i = 0; i < children.size(); i++) {
           children[i]->exampleMethod(bi);
    }
};
class Button : public Widget, public Interface<Button> {
    void exampleMethod(BaseInterface& bi) {
             static_cast<Interface<Button>&>(bi).data().exampleMethod().exampleMethod(*this);
    }
    void exampleMethod(Button &button) {
             //Methode definition here.
    }
};
 

En principe tu as 2 interfaces : une de base et une dérivée, ta classe de base hérite de l'interface de base et ta classe dérivée de l'interface dérivée.

Tu peux, dans ton interface de base si tu le veux, définir des widgets enfants, si une action s'applique à un widget parent tu pourra la rappliquer sur les widgets enfants de cette manière.

Dans l'interface enfants tu définis les méthodes de bases des widgets, ici je n'ai défini que la méthode clone, ça évite de devoir définir une méthode clone pour chaque type de widget.

Pour appeler une méthode et la rappliquer sur les widgets enfants, il suffit de définit une méthode dans la classe Widget qui va itérer sur tout les widget enfants, cette méthode doit être virtuelle.

Et dans chaque sous classes, tu redéfinis la méthode en "castant" ton interface, pour récupérer le widget enfant, et appeler ta méthode dessus.

Ce design parait compliqué au 1er abords mais il est puissant, lorsque tu rajouteras un nouveau type de widget, tu n'auras plus à modifier la classe widget.
Tu ne devras la modifier que si tu veux rajouté une méthode dans ta classe Widget que tu veux appliquer à tout tes widgets enfants. (Et je pense que tu pourrait même améliorer ce design avec des pointeurs de fonctions)

Bref..., juste pour te montrer à quel point le c++ est puissant, et, se serait dommage de brider ça puissance avec des shared_ptr.
Personnellement je ne les utilises que lors de la gestion des exceptions dans les bloc try/catch afin que la ressources soit libérée même si une exception est levée.

Ou bien pour les classes non copiable et non dérivée, ils peuvent servir aussi.
Mais pas ailleurs. (Et j'évite de les utiliser le plus possible afin d'éviter de devoir modifier ma classe si, un jour je décide de la rendre copiable ou bien de la faire dériver)

Je pense que SFML utilise pas mal de classe non copiable, Laurent doit sûrement avoir ses raisons car en effet il y a des choses qu'il ne vaudrait pas mieux copié par soucis de performance. (Mais à aucun endroit dans son code je le vois utiliser des shared_ptr et ce genre de chose)
Peut être parce que sa librairie n'utilise pas le c++11 ce qui est dommage mais bon..., en contre partie tu ne dépends pas du shared pointer et tu peux faire dériver ses classes comme tu l'entends et les cloner correctement.

PS : le mot clé auto je ne suis pas très fan non plus et je trouve qu'il sert un peu à rien à part à simplifier l'écriture et éviter de devoir utiliser un typedef dans une méthode. (Mais on pourrait très bien se passé de ce mot clé)

PS 2 : pour les fonctions de calleback j'utilise un delegate pour pouvoir changer la valeur des paramètres de la fonction callback avant son appel, ce qui m'implique de devoir connaître le type de la fonction lorsque je veux changer la valeur de ses paramètres. (Sauf si ce n'est pas une lambda expression ou une fonction anonyme car là le c++ peut déduire le type de la fonction automatiquement lors de la déduction de paramètres template)

Mais en général j'évite d'utiliser les lambda expression qui posent pas mal de problèmes aussi lorsqu'on veut modifier la valeur des paramètres de l'expression.

30
J'ai commencé à faire mon propre système de sérialisation, finalement avec le c++11 ce n'est pas si compliqué grâce aux tuples, et aux "type_traits", voici un tutoriel :
http://linor.fr/tutoriaux/tuto-723-la-serialization-et-la-compression-de-donnees-avec-odfaeg.php

J'ai mis à jour ça sur le git-hub, merci les tuples et les macros.  :D

PS : j'en ai aussi profité pour inclure un algorithme de compression que j'ai trouvé sur un site web.



Pages: « Précédente 1 [2] 3 4 ... 53 Suivante »
anything