view game/IDMContainer.java @ 138:9eb791e2fa17

Optimize board updating logic, so that the old placed tiles need not to be redrawn from scratch on each screen update, as they do not change usually.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 25 Nov 2011 11:04:09 +0200
parents 4c0dec72e2f0
children d6d92845d6a2
line wrap: on
line source

/*
 * Ristipolku IDM widget container
 * (C) Copyright 2011 Matti 'ccr' Hämäläinen <ccr@tnsp.org>
 */
package game;

import java.awt.*;
import java.awt.event.*;
import java.util.*;



public class IDMContainer extends IDMWidget
{
    private ArrayList<IDMWidget> children, queue;
    private IDMWidget modal;
    private int iterated;
    private boolean modified;

    public IDMContainer()
    {
        children = new ArrayList<IDMWidget>();
        iterated = 0;
        modified = false;
    }

    synchronized public void add(IDMWidget widget)
    {
        widget.setParent(this);
        if (iterated > 0)
        {
            queue.add(0, widget);
            modified = true;
        }
        else
            children.add(widget);
    }

    synchronized public void remove(IDMWidget widget)
    {
        widget.setParent(null);
        if (iterated > 0)
        {
            queue.remove(widget);
            modified = true;
        }
        else
            children.remove(widget);
    }

    synchronized private void beginIteration()
    {
        modified = false;
        if (iterated == 0)
        {
            queue = new ArrayList<IDMWidget>();
            for (IDMWidget widget : children)
                queue.add(widget);
        }
        iterated++;
    }

    synchronized private void endIteration()
    {
        if (modified && iterated == 1)
        {
            children = queue;
            queue = null;
        }
        iterated--;
    }

    synchronized public void paint(Graphics2D g)
    {
        // Paint in reverse order
        ListIterator<IDMWidget> iter = children.listIterator(children.size());

        while (iter.hasPrevious())
        {
            final IDMWidget widget = iter.previous();
            widget.paint(g);
        }
    }

    synchronized public boolean mousePressed(MouseEvent e)
    {
        try {
            beginIteration();
            for (IDMWidget widget : children)
            {
                if (widget.contains(e.getPoint()))
                {
                    if (widget.mousePressed(e))
                        return true;
                }
            }
        }
        finally { endIteration(); }
        return false;
    }

    synchronized public boolean mouseReleased(MouseEvent e)
    {
        try {
            beginIteration();
            for (IDMWidget widget : children)
            {
                if (widget.mouseReleased(e))
                    return true;
            }
        }
        finally { endIteration(); }
        return false;
    }

    synchronized public boolean mouseExited(MouseEvent e)
    {
        try {
            beginIteration();
            for (IDMWidget widget : children)
            {
                if (widget.mouseExited(e))
                    return true;
            }
        }
        finally { endIteration(); }
        return false;
    }

    synchronized public boolean mouseEntered(MouseEvent e)
    {
        try {
            beginIteration();
            for (IDMWidget widget : children)
            {
                if (widget.contains(e.getPoint()))
                {
                    if (widget.mouseEntered(e))
                        return true;
                }
            }
        }
        finally { endIteration(); }
        return false;
    }

    synchronized public boolean keyPressed(KeyEvent e)
    {
        try {
            beginIteration();
            for (IDMWidget widget : children)
            {
                 if (widget.keyPressed(e))
                    return true;
            }
        }
        finally { endIteration(); }
        return false;
    }

    synchronized public void setScale(IDMPoint scale)
    {
        beginIteration();
        for (IDMWidget widget : children)
        {
            widget.setScale(scale);
        }
        endIteration();
    }

    synchronized public boolean hasObject(Class c)
    {
        for (IDMWidget widget : children)
        {
            if (widget.getClass() == c)
                return true;
        }
        return false;
    }

    synchronized public boolean containsObject(Object o)
    {
        for (IDMWidget widget : children)
        {
            if (widget == o)
                return true;
        }
        return false;
    }
}