/*
* -----------------------------------------------------------------------
* Copyright 2012 - Alistair Rutherford - www.netthreads.co.uk
* -----------------------------------------------------------------------
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.netthreads.libgdx.event;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.PriorityQueue;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.scenes.scene2d.Actor;
/**
* Event source.
*
* Broadcast events to subscribed observers.
*
*/
public class ActorEventSource
{
private final static int OBSERVERS_CAPACITY = 10;
private final static int MAX_EVENTS = 100;
private ArrayList<ActorEventObserver> observers;
private LinkedList<ActorEvent> pool;
private PriorityQueue<ActorEvent> events;
/**
* Create observer list.
*
*/
public ActorEventSource()
{
observers = new ArrayList<ActorEventObserver>(OBSERVERS_CAPACITY);
pool = new LinkedList<ActorEvent>();
events = new PriorityQueue<ActorEvent>(MAX_EVENTS);
// Initialise the event pool.
for (int index = 0; index < MAX_EVENTS; index++)
{
pool.add(new ActorEvent());
}
}
/**
* Update any observers.
*
*/
public void update()
{
if (events.size() > 0)
{
ActorEvent event = events.poll();
if (event != null)
{
boolean handled = false;
int size = observers.size();
for (int index = 0; index < size; index++)
{
handled = observers.get(index).handleEvent(event);
if (handled)
break;
}
// Place data event back onto pool.
pool.add(event);
}
}
}
/**
* Add observer.
*
* @param observer
* The target observer.
*/
public synchronized void addObserver(ActorEventObserver observer)
{
if (!observers.contains(observer))
{
observers.add(observer);
}
}
/**
* Remove observer.
*
* @param observer
* Target event observer.
*/
public synchronized void removeObserver(ActorEventObserver observer)
{
if (observers.contains(observer))
{
observers.remove(observer);
}
}
/**
* Enqueue event
*
* @param id
* The event id.
* @param actor
* The associated actor.
*/
public void sendEvent(int id, Actor actor, int priority)
{
processEvent(id, actor, priority);
}
/**
* Map event data to pooled event.
*
* Place pooled event on to broadcast queue.
*
* @param id
* The event id.
* @param actor
* The associated actor.
*/
private void processEvent(int id, Actor actor, int priority)
{
ActorEvent event = pool.poll();
if (event == null)
{
event = new ActorEvent();
Gdx.app.log("ActorEventSource", "Warning, having to create pooled event, consider making the inital pool size larger, " + pool.size());
}
event.populate(id, actor, System.currentTimeMillis(), priority);
events.add(event);
}
/**
* Clear structures.
*
*/
public void clear()
{
observers.clear();
events.clear();
}
}