Applied-Energistics-2-tiler.../src/main/java/appeng/me/NetworkEventBus.java
yueh c9ef1beea1 Refactored the logging
Using LogManager instead of FMLRelaunchLog to access the logger instance.
Added logging of the name of failed exports instead of exception.
Improved crafting log to include issuer including their location and the
requested item.
Removed superfluous FMLRelaunchLog instance.
Removed superfluous parameters for PlayerData constructor.

Closes #2009
Refs #2069
2015-12-26 23:14:29 +01:00

220 lines
5.6 KiB
Java

/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.me;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import appeng.api.networking.IGridNode;
import appeng.api.networking.events.MENetworkEvent;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.core.AELog;
public class NetworkEventBus
{
private static final Collection<Class> READ_CLASSES = new HashSet<Class>();
private static final Map<Class<? extends MENetworkEvent>, Map<Class, MENetworkEventInfo>> EVENTS = new HashMap<Class<? extends MENetworkEvent>, Map<Class, MENetworkEventInfo>>();
void readClass( final Class listAs, final Class c )
{
if( READ_CLASSES.contains( c ) )
{
return;
}
READ_CLASSES.add( c );
try
{
for( final Method m : c.getMethods() )
{
final MENetworkEventSubscribe s = m.getAnnotation( MENetworkEventSubscribe.class );
if( s != null )
{
final Class[] types = m.getParameterTypes();
if( types.length == 1 )
{
if( MENetworkEvent.class.isAssignableFrom( types[0] ) )
{
Map<Class, MENetworkEventInfo> classEvents = EVENTS.get( types[0] );
if( classEvents == null )
{
EVENTS.put( types[0], classEvents = new HashMap<Class, MENetworkEventInfo>() );
}
MENetworkEventInfo thisEvent = classEvents.get( listAs );
if( thisEvent == null )
{
thisEvent = new MENetworkEventInfo();
}
thisEvent.Add( types[0], c, m );
classEvents.put( listAs, thisEvent );
}
else
{
throw new IllegalStateException( "Invalid ME Network Event Subscriber, " + m.getName() + "s Parameter must extend MENetworkEvent." );
}
}
else
{
throw new IllegalStateException( "Invalid ME Network Event Subscriber, " + m.getName() + " must have exactly 1 parameter." );
}
}
}
}
catch( final Throwable t )
{
throw new IllegalStateException( "Error while adding " + c.getName() + " to event bus", t );
}
}
MENetworkEvent postEvent( final Grid g, final MENetworkEvent e )
{
final Map<Class, MENetworkEventInfo> subscribers = EVENTS.get( e.getClass() );
int x = 0;
try
{
if( subscribers != null )
{
for( final Entry<Class, MENetworkEventInfo> subscriber : subscribers.entrySet() )
{
final MENetworkEventInfo target = subscriber.getValue();
final GridCacheWrapper cache = g.getCaches().get( subscriber.getKey() );
if( cache != null )
{
x++;
target.invoke( cache.getCache(), e );
}
for( final IGridNode obj : g.getMachines( subscriber.getKey() ) )
{
x++;
target.invoke( obj.getMachine(), e );
}
}
}
}
catch( final NetworkEventDone done )
{
// Early out.
}
e.setVisitedObjects( x );
return e;
}
MENetworkEvent postEventTo( final Grid grid, final GridNode node, final MENetworkEvent e )
{
final Map<Class, MENetworkEventInfo> subscribers = EVENTS.get( e.getClass() );
int x = 0;
try
{
if( subscribers != null )
{
final MENetworkEventInfo target = subscribers.get( node.getMachineClass() );
if( target != null )
{
x++;
target.invoke( node.getMachine(), e );
}
}
}
catch( final NetworkEventDone done )
{
// Early out.
}
e.setVisitedObjects( x );
return e;
}
private static class NetworkEventDone extends Throwable
{
private static final long serialVersionUID = -3079021487019171205L;
}
private class EventMethod
{
private final Class objClass;
private final Method objMethod;
private final Class objEvent;
public EventMethod( final Class Event, final Class ObjClass, final Method ObjMethod )
{
this.objClass = ObjClass;
this.objMethod = ObjMethod;
this.objEvent = Event;
}
private void invoke( final Object obj, final MENetworkEvent e ) throws NetworkEventDone
{
try
{
this.objMethod.invoke( obj, e );
}
catch( final Throwable e1 )
{
AELog.error( "[AppEng] Network Event caused exception:" );
AELog.error( "Offending Class: " + obj.getClass().getName() );
AELog.error( "Offending Object: " + obj.toString() );
AELog.debug( e1 );
throw new IllegalStateException( e1 );
}
if( e.isCanceled() )
{
throw new NetworkEventDone();
}
}
}
private class MENetworkEventInfo
{
private final List<EventMethod> methods = new ArrayList<EventMethod>();
private void Add( final Class Event, final Class ObjClass, final Method ObjMethod )
{
this.methods.add( new EventMethod( Event, ObjClass, ObjMethod ) );
}
private void invoke( final Object obj, final MENetworkEvent e ) throws NetworkEventDone
{
for( final EventMethod em : this.methods )
{
em.invoke( obj, e );
}
}
}
}