Alternative für Funktionszeiger



  • Hallo,

    Ich habe folgende Klasse mit einem Funktionszeiger

    #include "plasma_formulas.h"
    
    using PlasmaFormula = std::size_t ( * )( int x, int y,
                                             int width, int height,
                                             int color_range, double scaler );
    
    class Plasma
    {
    
    public:
    
        Plasma( const PlasmaFormula& formula,
                const Charset& charset,
                int width, int height, double s ) : plasma_formula( formula ),
                                                    plasma_width( width ),
                                                    plasma_height( height ),
                                                    color_range( static_cast<int>( charset.getSize() / 2 ) ),
                                                    scaler( s ),
                                                    col_palette( charset.getChars() )
        {
            generatePlasma();
        }
    
        int getWidth() const;
        int getHeight() const;
        void paint( const PaintArea&,
                    int x, int y,
                    int width, int height,
                    std::size_t color_shift ) const;
    
    private:
    
        PlasmaFormula plasma_formula = 0;
        int plasma_width  = 0;
        int plasma_height = 0;
        int color_range = 0;
        double scaler = 0;
        std::vector<Char> col_palette;
    
        struct PlasmaPos
        {
            int x = 0;
            int y = 0;
            std::size_t col_index = 0;
        } plasmaPos;
        std::vector<PlasmaPos> plasma;
    
        void generatePlasma();
    };
    

    zwei sehr einfache Formeln zum Beispiel

    std::size_t formula_00( int x, int y, int width, int height, int col_range, double scaler )
    {
        int color = toInt( col_range + ( col_range * std::sin(( x + y ) / scaler )));
        return static_cast<std::size_t>( color );
    }
    
    std::size_t formula_01( int x, int y, int width, int height, int col_range, double scaler )
    {
        const double w = width  / 2.0;
        const double h = height / 2.0;
    
        int color = toInt( col_range + ( col_range * std::sin( std::sqrt(( x - w ) * ( x - w )
                                     + ( y - h ) * ( y - h )) / scaler )));
    
        return static_cast<std::size_t>( color );
    }
    

    die hier genutzt werden

    void Plasma::generatePlasma()
    {
        for ( int x = 0; x < plasma_width; ++x )
        {
            for ( int y = 0; y < plasma_height; ++y )
            {
                std::size_t color = plasma_formula( x, y,
                                                    plasma_width, plasma_height,
                                                    color_range,
                                                    scaler );
                if ( color == col_palette.size() )
                {
                    color --;
                }
                plasmaPos.x = x;
                plasmaPos.y = y;
                plasmaPos.col_index = color;
                plasma.push_back( plasmaPos );
            }
        }
    }
    

    Nun mache ich mir über 2 Punkte Gedanken. In der ersten Formel von den beiden obigen, bleibt width und height ungenutzt. Dies kann passieren und wenn ich für eine andere Formel einen weiteren Parameter bräuchte, würde dieser in allen anderen Funktionen ungenutzt.

    Wie man in der Funktion generatePlasma() sieht, werden außer x und y nur member-variablen genutzt.

    Was muss ich machen, das ich in den Formel-Funktionen selbst nur die member benutze und nur die Parameter übergebe, die keine solchen sind?
    Dann wäre auch Punkt 1 erledigt.
    Danke.



  • Versteh ich nicht ganz, aber könntest du nicht dein "Plasma" übergeben, und die Formeln holen sich selber raus, was sie brauchen, z.B. width/height?



  • Wieso versteht man mich denn immer nicht?

    Du meinst, ich soll ein Objekt von Plasma den Formeln übergeben?



  • Das hat vermutlich weniger mit dir zu tun 😉 Ich hatte nur keine Lust, mich genau reinzudenken.
    Ja, es sieht für mich so aus, dass man ein Plasma Objekt übergeben könnte. Oder, wenn es nicht passt und/oder weitere Parameter benötigt werden, irgendeine Art "context" Objekt, dass alle benötigten Informationen enthält.



  • Dann müssten die Formel-Funktionen aber nach der Klasse deklariert werden? Aber die Formel-Funktion wird doch im Konstruktor der Klasse übergeben. Wie drehe ich das dann?

    Und das context-Objekt konnte eine struct sein mit den member-Werten der Klasse?

    PS:edit: kein Ding, lass Dir Zeit 🙂



  • Kennst du "Forward Declarations"?

    http://www.learncpp.com/cpp-tutorial/17-forward-declarations/

    Edit: Ansonsten kannst du die using declaration auch einfach in die Klasse rein ziehen. Muss ja nicht zwingend außerhalb stehen.



  • Eigentlich müsste ich die kennen.

    Bin jetzt aber verunsichert. Wenn eine Klasse einen Haufen Funktionen inkludiert, wie sollen in den Funktionen Objekte dieser Klasse sein?



  • using PlasmaFormula = std::size_t ( * )( class Plasma& );
    

    Der Rest kann genauso aussehen, wie bisher...



  • Aha, danke.

    Sorry, dieses verdammte Spiel heute ist so spannend 🙂

    Muss mich später mit beschäftigen, danke 😉


Log in to reply