001 package com.croftsoft.core.util.state; 002 003 import java.util.*; 004 005 import com.croftsoft.core.util.queue.*; 006 import com.croftsoft.core.util.queue.ListQueue; 007 008 /********************************************************************* 009 * 010 * Broadcasts the latest object state changes to StateListeners 011 * using Queues and QueuePullers for buffering. 012 * 013 * @author 014 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 015 * @version 016 * 2000-04-30 017 *********************************************************************/ 018 019 public class QueuedStateMulticaster implements StateMulticaster 020 ////////////////////////////////////////////////////////////////////// 021 ////////////////////////////////////////////////////////////////////// 022 { 023 024 /** QueuePullers keyed by StateListeners. */ 025 private Map queuePullerMap; 026 027 ////////////////////////////////////////////////////////////////////// 028 ////////////////////////////////////////////////////////////////////// 029 030 public QueuedStateMulticaster ( Map queuePullerMap ) 031 ////////////////////////////////////////////////////////////////////// 032 { 033 this.queuePullerMap = queuePullerMap; 034 } 035 036 /********************************************************************* 037 * this ( new HashMap ( ) ); 038 *********************************************************************/ 039 public QueuedStateMulticaster ( ) 040 ////////////////////////////////////////////////////////////////////// 041 { 042 this ( new HashMap ( ) ); 043 } 044 045 ////////////////////////////////////////////////////////////////////// 046 ////////////////////////////////////////////////////////////////////// 047 048 public void update ( State state ) 049 ////////////////////////////////////////////////////////////////////// 050 { 051 QueuePuller [ ] queuePullers = null; 052 053 synchronized ( queuePullerMap ) 054 { 055 queuePullers = ( QueuePuller [ ] ) 056 queuePullerMap.values ( ).toArray ( new QueuePuller [ 0 ] ); 057 } 058 059 for ( int i = 0; i < queuePullers.length; i++ ) 060 { 061 queuePullers [ i ].replace ( state ); 062 } 063 } 064 065 public synchronized boolean addStateListener ( 066 StateListener stateListener ) 067 ////////////////////////////////////////////////////////////////////// 068 { 069 QueuePuller queuePuller = new QueuePuller ( 070 new ListQueue ( new LinkedList ( ) ), 071 new StateListenerConsumer ( stateListener ) ); 072 073 if ( !queuePullerMap.containsKey ( stateListener ) ) 074 { 075 queuePullerMap.put ( stateListener, queuePuller ); 076 queuePuller.start ( ); 077 return true; 078 } 079 else 080 { 081 return false; 082 } 083 } 084 085 public synchronized boolean removeStateListener ( 086 StateListener stateListener ) 087 ////////////////////////////////////////////////////////////////////// 088 { 089 QueuePuller queuePuller 090 = ( QueuePuller ) queuePullerMap.remove ( stateListener ); 091 if ( queuePuller == null ) return false; 092 queuePuller.stop ( ); 093 return true; 094 } 095 096 ////////////////////////////////////////////////////////////////////// 097 ////////////////////////////////////////////////////////////////////// 098 }