All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.integratedmodelling.collections.Ticker Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (C) 2007, 2014:
 * 
 * - Ferdinando Villa  - integratedmodelling.org - any
 * other authors listed in @author annotations
 *
 * All rights reserved. This file is part of the k.LAB software suite, meant to enable
 * modular, collaborative, integrated development of interoperable data and model
 * components. For details, see http://integratedmodelling.org.
 * 
 * This program is free software; you can redistribute it and/or modify it under the terms
 * of the Affero General Public License Version 3 or any later version.
 *
 * This program is distributed in the hope that it will be useful, but without any
 * warranty; without even the implied warranty of merchantability or fitness for a
 * particular purpose. See the Affero General Public License for more details.
 * 
 * You should have received a copy of the Affero General Public License along with this
 * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite
 * 330, Boston, MA 02111-1307, USA. The license is also available at:
 * https://www.gnu.org/licenses/agpl.html
 *******************************************************************************/
package org.integratedmodelling.collections;

import java.util.ArrayList;

/**
 * A simple object that can be incremented along a number of dimensions. Mimicks one of
 * those clickable counters with wheels, except each wheel can have different number of
 * states. It knows what dimension indexes have been changed by the latest increment.
 * 
 * @author Ferdinando Villa
 *
 */
public class Ticker {

    /** total number of states (product of dimension sizes) */
    int states;

    /** total number of dimensions */
    int dims;

    ArrayList sizes   = new ArrayList();
    int[]              current = null;
    boolean[]          changed = null;

    private int currentIndex = 0;

    public Ticker() {
        states = 1;
        dims = 0;
    }

    /**
     * add all dimensions one by one in order, before doing anything. The last dimension
     * added changes the fastest.
     * 
     * @param size
     */
    public void addDimension(int size) {

        sizes.add(size);
        current = new int[sizes.size()];
        changed = new boolean[sizes.size()];
        dims++;
        reset();
    }

    /**
     * reset ticker to 0
     * 
     * @return index
     */
    public int reset() {
        states = 1;
        currentIndex = 0;

        /*
         * create 'current' vector, set all initial states as changed and calculate total
         * number of states
         */
        for (int i = 0; i < dims; i++) {
            current[i] = 0;
            changed[i] = true;
            states *= sizes.get(i);
        }

        /* return it */
        return states;
    }

    /**
     * Total number of possible states
     * 
     * @return total states
     */
    public int size() {
        return states;
    }

    /**
     * the current index along the passed dimension
     * 
     * @param i
     * @return current
     */
    public int current(int i) {
        return current[i];
    }

    /**
     * return the current states
     * 
     * @return state
     */
    public int[] retrieveState() {
        return current;
    }

    /** increment, recording changes along dimensions */
    public void increment() {

        currentIndex++;

        for (int i = dims - 1; i >= 0; i--) {
            if (current[i] == sizes.get(i) - 1) {
                current[i] = 0;
                changed[i] = true;
            } else {
                current[i]++;
                changed[i] = true;
                break;
            }
        }
    }

    /**
     * Returns whether the last increment changed the specified dimension. It resets the
     * status to false after that, so call it only once and save the value if required
     * more than once.
     * @param dim 
     * @return true if dim has changed
     */
    public boolean hasChanged(int dim) {
        boolean ret = changed[dim];
        changed[dim] = false;
        return ret;
    }

    /** prints the current values for the dimension */
    @Override
    public String toString() {

        String ret = "";

        for (int i = 0; i < dims; i++)
            ret += current[i] + (i < dims - 1 ? " " : "");

        return ret;
    }

    public static void main(String[] args) {

        Ticker ticker = new Ticker();

        ticker.addDimension(4);
        ticker.addDimension(3);
        ticker.addDimension(2);

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

            System.out.println(ticker.toString());
            ticker.increment();
        }

    }

    /**
     * Current overall state;
     * 
     * @return current state
     */
    public int current() {
        return currentIndex;
    }

    /**
     * Index of last overall state
     * 
     * @return last state
     */
    public int last() {
        return states - 1;
    }

    public boolean[] changedStates() {
        return changed;
    }

    /*
     * return whethere there are more states to cover.
     */
    public boolean expired() {
        return !(currentIndex < (states - 1));
    }

};




© 2015 - 2025 Weber Informatics LLC | Privacy Policy