Calling a method of a abstract class inside of a linked list fails

173 views Asked by At

I wrote a Class called cube which holds a double linked list which should hold objects of a abstract class called Animation and has a method to add animations . It looks liket his:

class CubeLib
{
protected:
//some more variables 
    LinkedList<Animation*> animations; //a list of animations
public:
    inline void addAnimation(Animation* a){
        animations.add(a);
    };
}

The interface:

class Animation
{
 public:
    virtual void update(short delta) = 0; 
};

Inside of the ino of the arduino project i init the CubeLib and the Animation in global and inside of the setup i add them to the list:

CubeLib cube;
Sinus* sinus_ani =new Sinus(&cube); // if not like this it stucks at setup?!
void setup()
{
    cube.addAnimation(sinus_ani);
}

Inside of a method called render i call the current Animations update function.

inline void CubeLib::update(short delta)
{
    if (animations.size() != -1){ //if its not empty
        animations[current_Animation]->update(delta);
    }
}

But in this case it does happen nothing. The update of the Sinus does not get called. Last but not least here is my double linked list. (I tested it but maybe there is some issue with it?)

template <typename T>
class LinkedList
{
protected:
private:
    struct Node
    {
        Node* prev;
        Node* next;
        T value;
    };

    Node* last;
    Node* first;
    byte count;

public:
    LinkedList()
    {
        count = -1; //empty
    };

    ~LinkedList()
    {
        if (count > -1){
            clear();
        }
    };
    /** adds to list*/
    inline void add(T t);

    /**removes the thing at index*/
    inline T remove(int index);

    /** Returns NULL(ptr) if index is out of range or item not found somehow*/
    inline T get(int index);

    inline void clear();

    /**Returns the first obj*/
    inline T getFirst();

    /**Returns the last obj*/
    inline T getLast();

    /**Returns the current size. If -1 its empty!*/
    inline int size(){
        return count;
    };

    T operator[](const int i)
    {
        return get(i);
    };
};

template <typename T>
inline void LinkedList<T>::add(T t){
    Node* n = new Node();
    n->value = t;
    if (count > -1)
    {
        n->next = first;
        n->prev = last;
        last->next = n;
        last = n;
        count++;
    }
    else if (count == -1)//first element
    {
        first = n;
        first->next = n;
        first->prev = n;
        last = n;
        last->next = n;
        last->prev = n;
        count++;
    }
}

template <typename T>
inline T LinkedList<T>::remove(int index){
    if (index <= count)
    {
        Node* n = last;
        for (int i = 0; i <= index; i++)
        {
            n = n->next;
        }
        n->prev->next = n->next;
        n->next->prev = n->prev;
        count--;
        return n->value; //return the value of that node
    }
}

template <typename T>
inline T LinkedList<T>::get(int index){
    if (index <= count && index > -1)
    {
        Node* n = first;
        int i = 0;
        while (i < index)
        {
            n = n->next;
            i++;
        }
        return n->value;
    }
    return NULL;
}

template <typename T>
inline void LinkedList<T>::clear()
{
    Node* n = first;
    while (count > 0)
    {
        Node* toBeDeleted = n;
        n = n->next;
        delete toBeDeleted;
        count--;
    }
}
/**Returns the first obj*/
template <typename T>
inline T LinkedList<T>::getFirst()
{
    return first->value;
};

/**Returns the last obj*/
template <typename T>
inline T LinkedList<T>::getLast()
{
    return last->value;
};

I am sorry for alot of code here. And I hope its not a obvious failer.


Edit:

Sinus is declared liket his:

class Sinus : public Animation
{
private:
    RGB color;
    CubeLib* cube;
    byte colorcounter;
    float time;

public:
    Sinus(CubeLib* c) : time(0.0), colorcounter(0), cube(c){
        color.r = MAX_COLOR;
        color.g = MAX_COLOR;
        color.b = MAX_COLOR;
    };
    ~Sinus(){};
    void update(short delta);
};

void Sinus::update(short delta)
{
    //do this 1000 times
    time += (((float)delta)/1000.0);
    for (int x = 0; x < 5; x++)
    {
        float value = (2.0*sin((float)(x + 1)*time*12.0)) + 2.0;
        for (int y = 0; y < 5; y++)
        {
            for (int z = 0; z < 5; z++)
            {
                if (abs(((float)z) - value) < 0.5)
                {
                    //cube.setLED(x, y, z, depth - 30/5*(int)abs(z-value), 0, 0);
                    cube->setLED(x, y, z, color);
                }
                else
                {
                    cube->setLED(x, y, z, 0, 0, 0);
                }
            }
        }
    }

    colorcounter++;
    if (colorcounter > 25)
    {
        color.r = random(MAX_COLOR);
        color.g = random(MAX_COLOR);
        color.b = random(MAX_COLOR);
        colorcounter = 0;
    }
}
1

There are 1 answers

1
bemeyer On BEST ANSWER

The error is really really really small and i noticed it just by luck.

I changed the counter of the list to byte to reduce the steps. But if my list is empty it is -1 so this would not work. Thats all! changed the count to short type and it works!

template <typename T>
class LinkedList
{
private:
    struct Node
    {
        Node* prev;
        Node* next;
        T value;
    };

    Node* last;
    Node* first;
    short count; // HERE 
/...
};