Package org.gephi.graph.dhns.core

Source Code of org.gephi.graph.dhns.core.EventManager

/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org

This file is part of Gephi.

Gephi is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Gephi 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
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Gephi.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.gephi.graph.dhns.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.GraphEvent;
import org.gephi.graph.api.GraphListener;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.api.Node;
import org.gephi.graph.dhns.event.AbstractEvent;
import org.gephi.graph.dhns.event.EdgeEvent;
import org.gephi.graph.dhns.event.GeneralEvent;
import org.gephi.graph.dhns.event.GraphEventDataImpl;
import org.gephi.graph.dhns.event.GraphEventImpl;
import org.gephi.graph.dhns.event.NodeEvent;
import org.gephi.graph.dhns.event.ViewEvent;

/**
*
* @author Mathieu Bastian
*/
public class EventManager implements Runnable {

    //Const
    private final static long DELAY = 1;
    //Architecture
    private final Dhns dhns;
    private final List<GraphListener> listeners;
    private final AtomicReference<Thread> thread = new AtomicReference<Thread>();
    private final LinkedBlockingQueue<AbstractEvent> eventQueue;
    private final Object lock = new Object();
    private int eventRate = 1;
    //Flag
    private boolean stop;

    public EventManager(Dhns dhns) {
        this.dhns = dhns;
        this.eventQueue = new LinkedBlockingQueue<AbstractEvent>();
        this.listeners = Collections.synchronizedList(new ArrayList<GraphListener>());
    }

    @Override
    public void run() {
        int rate = 0;
        while (!stop) {
            if (rate == eventRate) {
                try {
                    Thread.sleep(DELAY);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                eventRate = (int) (eventQueue.size() * 0.1f);
                eventRate = Math.max(1, eventRate);
                rate++;
            }
            List<Object> eventCompress = null;

            AbstractEvent precEvt = null;
            AbstractEvent evt = null;
            while ((evt = eventQueue.peek()) != null) {
                if (precEvt != null) {
                    if ((evt instanceof NodeEvent || evt instanceof EdgeEvent) && precEvt.getEventType().equals(evt.getEventType()) && precEvt.getView() == evt.getView()) {     //Same type
                        if (eventCompress == null) {
                            eventCompress = new ArrayList<Object>();
                            eventCompress.add(precEvt.getData());
                        }
                        eventCompress.add(evt.getData());
                    } else {
                        break;
                    }
                }
                eventQueue.poll();
                precEvt = evt;
            }

            if (precEvt != null) {
                GraphEvent event = createEvent(precEvt, eventCompress);
                for (GraphListener l : listeners.toArray(new GraphListener[0])) {
                    l.graphChanged(event);
                }
            }
            rate++;

            while (eventQueue.isEmpty()) {
                rate = 0;
                eventRate = 1;
                try {
                    synchronized (lock) {
                        lock.wait();
                    }
                } catch (InterruptedException e) {
                }
            }
        }
    }

    private GraphEvent createEvent(AbstractEvent event, List<Object> compress) {
        final GraphEventDataImpl eventData = (event instanceof GeneralEvent) ? null : new GraphEventDataImpl();
        final GraphEventImpl graphEventImpl = new GraphEventImpl(event.getView(), event.getEventType(), eventData);
        if (event instanceof NodeEvent) {
            Node[] nodes;
            if (compress != null) {
                nodes = compress.toArray(new Node[0]);
            } else {
                nodes = new Node[]{(Node) event.getData()};
            }
            switch (event.getEventType()) {
                case ADD_NODES:
                    eventData.setAddedNodes(nodes);
                    break;
                case REMOVE_NODES:
                    eventData.setRemovedNodes(nodes);
                    break;
                case EXPAND:
                    eventData.setExpandedNodes(nodes);
                    break;
                case RETRACT:
                    eventData.setRetractedNodes(nodes);
                    break;
                case MOVE_NODES:
                    eventData.setMovedNodes(nodes);
                    break;
            }
        } else if (event instanceof EdgeEvent) {
            Edge[] edges;
            if (compress != null) {
                edges = compress.toArray(new Edge[0]);
            } else {
                edges = new Edge[]{(Edge) event.getData()};
            }
            switch (event.getEventType()) {
                case ADD_EDGES:
                    eventData.setAddedEdges(edges);
                    break;
                case REMOVE_EDGES:
                    eventData.setRemovedEdges(edges);
                    break;
            }
        } else if (event instanceof ViewEvent) {
            eventData.setView((GraphView) event.getData());
        }
        return graphEventImpl;
    }

    public void stop(boolean stop) {
        this.stop = stop;
    }

    public void fireEvent(AbstractEvent event) {
        eventQueue.add(event);
        synchronized (lock) {
            lock.notifyAll();
        }
    }

    public void start() {
        Thread t = new Thread(this);
        t.setDaemon(true);
        t.setName("graph-event-bus");
        if (this.thread.compareAndSet(null, t)) {
            t.start();
        }
    }

    public boolean isRunning() {
        return thread.get() != null;
    }

    public void addGraphListener(GraphListener listener) {
        if (!listeners.contains(listener)) {
            listeners.add(listener);
        }
    }

    public void removeGraphListener(GraphListener listener) {
        listeners.remove(listener);
    }
}
TOP

Related Classes of org.gephi.graph.dhns.core.EventManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.