clientobjectsholder.java

来自「Java mulitplayer strategy game. Adaptati」· Java 代码 · 共 161 行

JAVA
161
字号
package net.sf.jawp.client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import net.sf.jawp.gf.api.Entity;

/**
 * Tracks game data at client side.
 * @author jarek
 * @version $Revision$
 * @param <ENTITY> object type  to be traced
 */
public abstract class ClientObjectsHolder<ENTITY extends Entity>
{
	/**
	 * all known objects
	 */
	private final HashMap<Long , ENTITY> knownObjects;
	
	/**
	 * recently updated objects
	 */
	private final HashSet<Long> updated;
	
	/**
	 * recently added
	 */
	private final HashSet<Long> added;
	
	/**
	 * recently removed objects
	 */
	private final HashSet<Long> removed;
	
	
	public ClientObjectsHolder()
	{
		this.knownObjects = new HashMap<Long, ENTITY>();
		this.updated = new HashSet<Long>();
		this.added = new HashSet<Long>();
		this.removed = new HashSet<Long>();
	}
	
	public final void bulkRefresh( final Collection<ENTITY> newObjects)
	{
		//this variable finally should hold all objects that are not updated (possibly removed)
		final Set<Long> notMentioned = new HashSet<Long>( this.knownObjects.keySet());
		for ( final ENTITY newObject : newObjects)
		{
			notMentioned.remove( newObject.getKey());
			refreshObject( newObject);
		}
		//process not mentioned objects
		for ( final Long key : notMentioned)
		{
			this.removed.add( key);
		}
	}
	
	public final ENTITY find( final long key)
	{
		return this.knownObjects.get( key );
	}

	private void refreshObject(final ENTITY newObject)
	{
		//check if object is already known
		final ENTITY old = find( newObject.getKey());
		if ( old != null)
		{
			updateObject( old, newObject);
		}
		else
		{
			addNewObject( newObject);
		}
		
	}

	private void addNewObject(final ENTITY newObject)
	{
		this.knownObjects.put( newObject.getKey(), newObject);
		this.added.add( newObject.getKey());
	}

	private void updateObject(final ENTITY oldObject, final ENTITY newObject)
	{
		
		final boolean changed = hasChanged( oldObject, newObject);
		update( oldObject, newObject, changed);
		if ( changed )
		{
			this.updated.add( oldObject.getKey());
		}
	}
	
	/**
	 * should return true if object has changed important data and must be added to updated objects sets
	 * (if object has changed unimportant data should return false)
	 * method update will be called later anyhow (th
	 * 
	 * @param old
	 * @param newObject
	 * @return
	 */
	protected abstract boolean hasChanged( final ENTITY old, final ENTITY newObject);
	
	/**
	 * update old object using new data
	 * @param changed - result of hasChanged function - usefull in case when object has to be updated even though
	 * 		it wont appear in updated objects set (small change)  
	 */
	protected abstract void  update(final ENTITY old, final ENTITY newObject, final boolean changed );
	
	private Collection<ENTITY> keysToObjects( final Collection<Long> keys)
	{
		final ArrayList<ENTITY> result = new ArrayList<ENTITY>( keys.size());
		for ( final Long key : keys)
		{
			result.add( find( key));
		}
		return result;
	}
	
	private Collection<ENTITY> getCollectionAndClear(final Set<Long> keys)
	{
		final Collection<ENTITY> result = keysToObjects( keys );
		keys.clear();
		return result;
	} 
	
	public final Collection<ENTITY> getUpdated()
	{
		return getCollectionAndClear(this.updated);
	}
	
	public final Collection<ENTITY> getRemoved()
	{
		final Collection<ENTITY> result = getCollectionAndClear(this.removed);
		for ( final ENTITY e : result)
		{
			this.knownObjects.remove( e.getKey());
		}
		return result;
	}
	
	public final Collection<ENTITY> getAdded()
	{
		return getCollectionAndClear(this.added);
	}
	
	public final Collection<ENTITY> getAll()
	{
		return new ArrayList<ENTITY>( this.knownObjects.values());
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?