Home | History | Annotate | Download | only in base
      1 /*
      2  * Copyright (c) 2011 jMonkeyEngine
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are
      7  * met:
      8  *
      9  * * Redistributions of source code must retain the above copyright
     10  *   notice, this list of conditions and the following disclaimer.
     11  *
     12  * * Redistributions in binary form must reproduce the above copyright
     13  *   notice, this list of conditions and the following disclaimer in the
     14  *   documentation and/or other materials provided with the distribution.
     15  *
     16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
     17  *   may be used to endorse or promote products derived from this software
     18  *   without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 package com.jme3.network.base;
     34 
     35 import com.jme3.network.Message;
     36 import com.jme3.network.MessageListener;
     37 import java.util.Collections;
     38 import java.util.List;
     39 import java.util.Map;
     40 import java.util.concurrent.ConcurrentHashMap;
     41 import java.util.concurrent.CopyOnWriteArrayList;
     42 import java.util.logging.Level;
     43 import java.util.logging.Logger;
     44 
     45 /**
     46  *  Keeps track of message listeners registered to specific
     47  *  types or to any type.
     48  *
     49  *  @version   $Revision: 8843 $
     50  *  @author    Paul Speed
     51  */
     52 public class MessageListenerRegistry<S> implements MessageListener<S>
     53 {
     54     static Logger log = Logger.getLogger(MessageListenerRegistry.class.getName());
     55 
     56     private List<MessageListener<? super S>> listeners = new CopyOnWriteArrayList<MessageListener<? super S>>();
     57     private Map<Class,List<MessageListener<? super S>>> typeListeners
     58                     = new ConcurrentHashMap<Class,List<MessageListener<? super S>>>();
     59 
     60     public MessageListenerRegistry()
     61     {
     62     }
     63 
     64     public void messageReceived( S source, Message m )
     65     {
     66         boolean delivered = false;
     67 
     68         for( MessageListener<? super S> l : listeners ) {
     69             l.messageReceived( source, m );
     70             delivered = true;
     71         }
     72 
     73         for( MessageListener<? super S> l : getListeners(m.getClass(),false) ) {
     74             l.messageReceived( source, m );
     75             delivered = true;
     76         }
     77 
     78         if( !delivered ) {
     79             log.log( Level.INFO, "Received message had no registered listeners: {0}", m );
     80         }
     81     }
     82 
     83     protected List<MessageListener<? super S>> getListeners( Class c, boolean create )
     84     {
     85         List<MessageListener<? super S>> result = typeListeners.get(c);
     86         if( result == null && create ) {
     87             result = new CopyOnWriteArrayList<MessageListener<? super S>>();
     88             typeListeners.put( c, result );
     89         }
     90 
     91         if( result == null ) {
     92             result = Collections.emptyList();
     93         }
     94         return result;
     95     }
     96 
     97     public void addMessageListener( MessageListener<? super S> listener )
     98     {
     99         listeners.add(listener);
    100     }
    101 
    102     public void removeMessageListener( MessageListener<? super S> listener )
    103     {
    104         listeners.remove(listener);
    105     }
    106 
    107     public void addMessageListener( MessageListener<? super S> listener, Class... classes )
    108     {
    109         for( Class c : classes ) {
    110             getListeners(c, true).add(listener);
    111         }
    112     }
    113 
    114     public void removeMessageListener( MessageListener<? super S> listener, Class... classes )
    115     {
    116         for( Class c : classes ) {
    117             getListeners(c, false).remove(listener);
    118         }
    119     }
    120 }
    121