4343/**
4444 * Base class for all Plot implementations.
4545 */
46- public abstract class Plot <SeriesType extends Series , FormatterType extends Formatter , RendererType extends SeriesRenderer >
46+ public abstract class Plot <SeriesType extends Series , FormatterType extends Formatter ,
47+ RendererType extends SeriesRenderer , BundleType extends SeriesBundle <SeriesType , FormatterType >,
48+ RegistryType extends SeriesRegistry <BundleType , SeriesType , FormatterType >>
4749 extends View implements Resizable {
4850 private static final String TAG = Plot .class .getName ();
4951 private static final String XML_ATTR_PREFIX = "androidplot" ;
@@ -66,10 +68,23 @@ public HashMap<Class<? extends RendererType>, RendererType> getRenderers() {
6668 /**
6769 * Associates lists series and getFormatter pairs with the class of the Renderer used to render them.
6870 */
69- public SeriesRegistry < SeriesType , FormatterType > getSeriesRegistry () {
70- return seriesRegistry ;
71+ public RegistryType getRegistry () {
72+ return registry ;
7173 }
7274
75+ public void setRegistry (RegistryType registry ) {
76+ this .registry = registry ;
77+ for (BundleType bundle : registry .getSeriesAndFormatterList ()) {
78+ attachSeries (bundle .getSeries (), bundle .getFormatter ());
79+ }
80+ }
81+
82+ /**
83+ *
84+ * @return A new instance of RegistryType
85+ */
86+ protected abstract RegistryType getRegistryInstance ();
87+
7388 public TextLabelWidget getTitle () {
7489 return title ;
7590 }
@@ -152,7 +167,8 @@ public enum RenderMode {
152167 private final Object renderSynch = new Object ();
153168
154169 private HashMap <Class <? extends RendererType >, RendererType > renderers ;
155- private SeriesRegistry <SeriesType , FormatterType > seriesRegistry ;
170+
171+ private RegistryType registry ;
156172 private final ArrayList <PlotListener > listeners ;
157173
158174 private Thread renderThread ;
@@ -161,7 +177,7 @@ public enum RenderMode {
161177
162178 {
163179 listeners = new ArrayList <>();
164- seriesRegistry = new SeriesRegistry <> ();
180+ registry = getRegistryInstance ();
165181 renderers = new HashMap <>();
166182
167183 borderPaint = new Paint ();
@@ -459,8 +475,8 @@ private void loadAttrs(AttributeSet attrs, int defStyle) {
459475 styleableName = styleableName .replace ('.' , '_' );
460476 try {
461477 /**
462- * Use reflection to safely check for the existence of styleable defs for Plot
463- * and it's derivatives. This safety check is necessary to avoid runtime exceptions
478+ * Use reflection to safely run for the existence of styleable defs for Plot
479+ * and it's derivatives. This safety run is necessary to avoid runtime exceptions
464480 * in apps that don't include Androidplot as a .aar and won't have access to
465481 * the resources defined in the core library.
466482 */
@@ -507,7 +523,7 @@ private void loadAttrs(AttributeSet attrs, int defStyle) {
507523 for (int i = 0 ; i < attrs .getAttributeCount (); i ++) {
508524 String attrName = attrs .getAttributeName (i );
509525
510- // case insensitive check to see if this attr begins with our prefix:
526+ // case insensitive run to see if this attr begins with our prefix:
511527 if (attrName != null && attrName .toUpperCase ().startsWith (XML_ATTR_PREFIX .toUpperCase ())) {
512528 attrHash .put (attrName .substring (XML_ATTR_PREFIX .length () + 1 ), attrs .getAttributeValue (i ));
513529 }
@@ -569,11 +585,14 @@ public synchronized boolean addSeries(FormatterType formatter, SeriesType... ser
569585 * @return True if the series was added or false if the series / formatter pair already exists in the registry.
570586 */
571587 public synchronized boolean addSeries (SeriesType series , FormatterType formatter ) {
572- Class rendererClass = formatter .getRendererClass ();
588+ final boolean result = getRegistry ().add (series , formatter );
589+ attachSeries (series , formatter );
590+ return result ;
591+ }
573592
574- // if(getSeries( series, rendererClass) != null ) {
575- // return false;
576- // }
593+ protected void attachSeries ( SeriesType series , FormatterType formatter ) {
594+
595+ Class rendererClass = formatter . getRendererClass ();
577596
578597 // initialize the Renderer if necessary:
579598 if (!getRenderers ().containsKey (rendererClass )) {
@@ -584,20 +603,17 @@ public synchronized boolean addSeries(SeriesType series, FormatterType formatter
584603 if (series instanceof PlotListener ) {
585604 addListener ((PlotListener )series );
586605 }
587-
588- getSeriesRegistry ().add (new SeriesAndFormatter <>(series , formatter ));
589- return true ;
590606 }
591607
592608 /**
593609 *
594610 * @param series
595611 * @param rendererClass
596- * @return The {@link SeriesAndFormatter } that matches the series and rendererClass params, or null if one is not found.
612+ * @return The {@link SeriesBundle } that matches the series and rendererClass params, or null if one is not found.
597613 */
598- protected SeriesAndFormatter <SeriesType , FormatterType > getSeries (SeriesType series , Class <? extends RendererType > rendererClass ) {
599- for (SeriesAndFormatter <SeriesType , FormatterType > thisPair : seriesRegistry ) {
600- if (thisPair .getSeries () == series && thisPair . getFormatter ().getRendererClass () == rendererClass ) {
614+ protected SeriesBundle <SeriesType , FormatterType > getSeries (SeriesType series , Class <? extends RendererType > rendererClass ) {
615+ for (SeriesBundle <SeriesType , FormatterType > thisPair : getSeries ( series ) ) {
616+ if (thisPair .getFormatter ().getRendererClass () == rendererClass ) {
601617 return thisPair ;
602618 }
603619 }
@@ -607,17 +623,10 @@ protected SeriesAndFormatter<SeriesType, FormatterType> getSeries(SeriesType ser
607623 /**
608624 *
609625 * @param series
610- * @return A List of {@link SeriesAndFormatter} instances that reference series.
611- */
612- protected List <SeriesAndFormatter <SeriesType , FormatterType >> getSeries (SeriesType series ) {
613- List <SeriesAndFormatter <SeriesType , FormatterType >> results =
614- new ArrayList <>();
615- for (SeriesAndFormatter <SeriesType , FormatterType > thisPair : seriesRegistry ) {
616- if (thisPair .getSeries () == series ) {
617- results .add (thisPair );
618- }
619- }
620- return results ;
626+ * @return A List of {@link SeriesBundle} instances that reference series.
627+ */
628+ protected List <SeriesBundle <SeriesType , FormatterType >> getSeries (SeriesType series ) {
629+ return getRegistry ().get (series );
621630 }
622631
623632 /**
@@ -626,58 +635,47 @@ protected List<SeriesAndFormatter<SeriesType, FormatterType>> getSeries(SeriesTy
626635 * from the plot completely.
627636 * @param series
628637 * @param rendererClass
629- * @return The SeriesAndFormatterPair that was removed or null if nothing was removed.
638+ * @return True if anything was removed, false otherwise
630639 */
631- public synchronized SeriesAndFormatter < SeriesType , FormatterType > removeSeries (SeriesType series , Class <? extends RendererType > rendererClass ) {
640+ public synchronized boolean removeSeries (SeriesType series , Class <? extends RendererType > rendererClass ) {
632641
633- List <SeriesAndFormatter <SeriesType , FormatterType >> results = getSeries (series );
634- SeriesAndFormatter <SeriesType , FormatterType > result = null ;
635- for (SeriesAndFormatter <SeriesType , FormatterType > thisPair : results ) {
636- if (thisPair .getFormatter ().getRendererClass () == rendererClass ) {
637- result = thisPair ;
638- getSeriesRegistry ().remove (result );
639- break ;
640- }
641- }
642+ List removedItems = getRegistry ().remove (series , rendererClass );
642643
643644 // if series implements PlotListener and is not assigned to any other renderers remove it as a listener:
644- if ( series instanceof PlotListener && results .size () == 1 ) {
645+ if ( removedItems .size () == 1 && series instanceof PlotListener ) {
645646 removeListener ((PlotListener ) series );
647+ return true ;
646648 }
647-
648- return result ;
649+ return false ;
649650 }
650651
651652 /**
652653 * Remove all occurrences of series regardless of the associated Renderer.
653654 * @param series
654655 */
655656 public synchronized void removeSeries (SeriesType series ) {
656-
657- for (Iterator <SeriesAndFormatter <SeriesType , FormatterType >> it = getSeriesRegistry ().iterator (); it .hasNext ();) {
658- if (it .next ().getSeries () == series ) {
659- it .remove ();
660- }
661- }
662-
663657 // if series implements PlotListener, remove it from listeners:
664658 if (series instanceof PlotListener ) {
665659 removeListener ((PlotListener ) series );
666660 }
661+
662+ getRegistry ().remove (series );
667663 }
668664
669665 /**
670666 * Remove all series from the plot.
671667 */
672668 public void clear () {
673- for (Iterator <SeriesAndFormatter <SeriesType , FormatterType >> it = getSeriesRegistry ().iterator (); it .hasNext ();) {
674- it .next ();
675- it .remove ();
669+ for (SeriesType series : getRegistry ().getSeriesList ()) {
670+ if (series instanceof PlotListener ) {
671+ removeListener ((PlotListener ) series );
672+ }
676673 }
674+ getRegistry ().clear ();
677675 }
678676
679677 public boolean isEmpty () {
680- return getSeriesRegistry ().isEmpty ();
678+ return getRegistry ().isEmpty ();
681679 }
682680
683681 /**
@@ -754,7 +752,7 @@ protected synchronized void onSizeChanged (int w, int h, int oldw, int oldh) {
754752 PixelUtils .init (getContext ());
755753
756754 // disable hardware acceleration if it's not explicitly supported
757- // by the current Plot implementation. this check only applies to
755+ // by the current Plot implementation. this run only applies to
758756 // honeycomb and later environments.
759757 if (Build .VERSION .SDK_INT >= 11 ) {
760758 if (!isHwAccelerationSupported () && isHardwareAccelerated ()) {
@@ -831,12 +829,13 @@ protected synchronized void renderOnCanvas(Canvas canvas) {
831829 } catch (Exception e ) {
832830 Log .e (TAG , "Exception while rendering Plot." , e );
833831 }
834- } finally {
832+
835833 isIdle = true ;
836834 // any series interested in synchronizing with plot should
837835 // implement PlotListener.onAfterDraw(...) and do a read unlock from within that
838836 // invocation. This is the entry point for that invocation.
839837 notifyListenersAfterDraw (canvas );
838+ } finally {
840839 }
841840 }
842841
0 commit comments