Package games.stendhal.client

Source Code of games.stendhal.client.RPObjectChangeDispatcher

/* $Id: RPObjectChangeDispatcher.java,v 1.26 2011/03/09 19:44:24 kiheru Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.client;


import games.stendhal.client.listener.RPObjectChangeListener;
import marauroa.common.game.RPObject;
import marauroa.common.game.RPSlot;

import org.apache.log4j.Logger;

/**
* A dispatcher for RPObjectChangeListeners. This normalizes the tree deltas
* into individual object deltas.
*
* NOTE: The order of dispatch between contained objects and when their
* container is very specific. Children objects are given a chance to perform
* creation/updates before their parent is notified it happened to that specific
* child. For cases of object removal, the parent is notified first, in case the
* child does destruction/cleanup.
*/
public class RPObjectChangeDispatcher {
  /**
   * The logger.
   */
  private static final Logger logger = Logger.getLogger(RPObjectChangeDispatcher.class);

  /**
   * The normal listener.
   */
  protected RPObjectChangeListener listener;

  /**
   * The user object listener.
   */
  protected RPObjectChangeListener userListener;

  /**
   * Create an RPObjectChange event dispatcher.
   *
   * @param listener
   *            The normal listener.
   * @param userListener
   *            The user object listener.
   */
  public RPObjectChangeDispatcher(final RPObjectChangeListener listener, final RPObjectChangeListener userListener) {
    this.listener = listener;
    this.userListener = userListener;
  }

  //
  // RPObjectChangeDispatcher
  //

  /**
   * Dispatch object added event.
   *
   * @param object
   *            The object.
   */
  public void dispatchAdded(final RPObject object) {
    try {
      logger.debug("Object(" + object.getID() + ") added to client");
      fireAdded(object);
    } catch (final Exception e) {
      logger.error("dispatchAdded failed, object is " + object, e);
    }
  }

  /**
   * Dispatch object removed event.
   *
   * @param object
   *            The object.
   */
  public void dispatchRemoved(final RPObject object) {
    try {
      logger.debug("Object(" + object.getID() + ") removed from client");
      fireRemoved(object);
    } catch (final Exception e) {
      logger.error(
          "dispatchRemovedonDeleted failed, object is " + object, e);
    }
  }

  /**
   * Dispatch object added/changed attribute(s) event.
   *
   * @param object
   *            The base object.
   * @param changes
   *            The changes.
   */
  public void dispatchModifyAdded(final RPObject object,
      final RPObject changes) {
    try {
      logger.debug("Object(" + object.getID() + ") modified in client");
      fireChangedAdded(object, changes);
      object.applyDifferences(changes, null);
    } catch (final Exception e) {
      logger.error("dispatchModifyAdded failed, object is " + object
          + ", changes is " + changes, e);
    }

  }

  /**
   * Dispatch object removed attribute(s) event.
   *
   * @param object
   *            The base object.
   * @param changes
   *            The changes.
   */
  public void dispatchModifyRemoved(final RPObject object, final RPObject changes) {
    if (object != null) {
      try {
        logger.debug("Object(" + object.getID() + ") modified in client");
        logger.debug("Original(" + object + ") modified in client");

        fireChangedRemoved(object, changes);
        object.applyDifferences(null, changes);

        logger.debug("Modified(" + object + ") modified in client");
        logger.debug("Changes(" + changes + ") modified in client");
      } catch (final Exception e) {
        logger.error("dispatchModifyRemoved failed, object is " + object + ", changes is " + changes, e);
      }
    } else {
      logger.error("dispatchModifyRemoved failed, object is null, changes is " + changes);
    }
   
  }

  protected static void buildIDPath(final StringBuilder sbuf,
      final RPObject object) {
    final RPSlot slot = object.getContainerSlot();

    if (slot != null) {
      buildIDPath(sbuf, object.getContainer());
      sbuf.append(':');
      sbuf.append(slot.getName());
      sbuf.append(':');
    }

    sbuf.append(object.getID().getObjectID());
  }

  /**
   * Notify listeners that an object was added.
   *
   * @param object
   *            The object.
   */
  protected void fireAdded(final RPObject object) {

    /*
     * Call before children have been notified
     */
    listener.onAdded(object);

   
      userListener.onAdded(object);
   

    /*
     * Walk each slot
     */
    for (final RPSlot slot : object.slots()) {
      final String slotName = slot.getName();

      for (final RPObject sobject : slot) {
        fireAdded(object, slotName, sobject);
      }
    }
  }

  /**
   * Notify listeners that a slot object was added.
   *
   * @param object
   *            The parent object.
   * @param slotName
   *            The slot name.
   * @param sobject
   *            The slot object.
   */
  protected void fireAdded(final RPObject object, final String slotName,
      final RPObject sobject) {
    /*
     * Notify child
     */
    fireAdded(sobject);

    /*
     * Call after the child has been notified
     */
    listener.onSlotAdded(object, slotName, sobject);

   
    userListener.onSlotAdded(object, slotName, sobject);
   
  }

  /**
   * Notify listeners that an object added/changed attribute(s). This will
   * cascade down slot trees.
   *
   * @param object
   *            The base object.
   * @param changes
   *            The changes.
   */
  protected void fireChangedAdded(final RPObject object, final RPObject changes) {

    /*
     * Walk each slot
     */
    for (final RPSlot cslot : changes.slots()) {
      if (cslot.size() != 0) {
        fireChangedAdded(object, cslot);
      }
    }

    /*
     * Call after children have been notified
     */
    listener.onChangedAdded(object, changes);

   
      userListener.onChangedAdded(object, changes);
   
  }

  /**
   * Notify listeners that an object slot added/changed attribute(s). This
   * will cascade down object trees.
   *
   * @param object
   *            The base object.
   * @param cslot
   *            The changes slot.
   */
  protected void fireChangedAdded(final RPObject object, final RPSlot cslot) {
    final String slotName = cslot.getName();
    RPSlot slot;

    /*
     * Find the original slot entry (if any)
     */
    if (object.hasSlot(slotName)) {
      slot = object.getSlot(slotName);
    } else {
      slot = null;
    }

    /*
     * Walk the changes
     */
    for (final RPObject schanges : cslot) {
      final RPObject.ID id = schanges.getID();

      if ((slot != null) && slot.has(id)) {
        final RPObject sobject = slot.get(id);

        listener.onSlotChangedAdded(object, slotName, sobject, schanges);

       
          userListener.onSlotChangedAdded(object, slotName, sobject,
              schanges);
       

        fireChangedAdded(sobject, schanges);
      } else {
        if (!schanges.isContained()) {
          logger.warn("!!! Not contained! - " + schanges);
        }

        fireAdded(object, slotName, schanges);
      }
    }
  }

  /**
   * Notify listeners that an object removed attribute(s). This will cascade
   * down slot trees.
   *
   * @param object
   *            The base object.
   * @param changes
   *            The changes.
   */
  protected void fireChangedRemoved(final RPObject object, final RPObject changes) {
   
    /*
     * Call before children have been notified
     */
    listener.onChangedRemoved(object, changes);

   
      userListener.onChangedRemoved(object, changes);
   

    /*
     * Walk each slot
     */
    for (final RPSlot cslot : changes.slots()) {
      if (cslot.size() != 0) {
        fireChangedRemoved(object, cslot);
      }
    }
  }

  /**
   * Notify listeners that an object slot removed attribute(s). This will
   * cascade down object trees.
   *
   * @param object
   *            The base object.
   * @param cslot
   *            The changes slot.
   */
  protected void fireChangedRemoved(final RPObject object, final RPSlot cslot) {
    final String slotName = cslot.getName();

    /*
     * Find the original slot entry
     */
    final RPSlot slot = object.getSlot(slotName);

    /*
     * Walk the changes
     */
    for (final RPObject schanges : cslot) {
      final RPObject sobject = slot.get(schanges.getID());

      if (sobject == null) {
        // This happens when a child object deleted itself
        logger.debug("Unable to find existing: " + schanges);
        continue;
      }

      /*
       * Remove attrs vs. object [see applyDifferences()]
       */
      if (schanges.size() > 1) {
        listener.onSlotChangedRemoved(object, slotName, sobject,
            schanges);

       
          userListener.onSlotChangedRemoved(object, slotName,
              sobject, schanges);
       

        fireChangedRemoved(sobject, schanges);
      } else {
        fireRemoved(object, slotName, sobject);
      }
    }
  }

  /**
   * Notify listeners that an object was removed.
   *
   * @param object
   *            The object.
   */
  protected void fireRemoved(final RPObject object) {
    /*
     * Walk each slot
     */
    for (final RPSlot slot : object.slots()) {
      final String slotName = slot.getName();

      for (final RPObject sobject : slot) {
        fireRemoved(object, slotName, sobject);
      }
    }

    /*
     * Call after children have been notified
     */
    listener.onRemoved(object);

   
      userListener.onRemoved(object);
   
  }

  /**
   * Notify listeners that a slot object was removed.
   *
   * @param object
   *            The container object.
   * @param slotName
   *            The slot name.
   * @param sobject
   *            The slot object.
   */
  protected void fireRemoved(final RPObject object, final String slotName,
      final RPObject sobject) {
    /*
     * Call before the child is notified
     */
    listener.onSlotRemoved(object, slotName, sobject);

   
      userListener.onSlotRemoved(object, slotName, sobject);
   

    /*
     * Notify child
     */
    fireRemoved(sobject);
  }


TOP

Related Classes of games.stendhal.client.RPObjectChangeDispatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.