Package org.groovymud.object.registry

Source Code of org.groovymud.object.registry.Registry

package org.groovymud.object.registry;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;

import org.apache.log4j.Logger;
import org.codehaus.groovy.control.CompilationFailedException;
import org.groovymud.engine.event.EventScope;
import org.groovymud.engine.event.MudEventListener;
import org.groovymud.engine.event.ScopedEvent;
import org.groovymud.engine.event.action.SaveEvent;
import org.groovymud.engine.event.messages.MessageEvent;
import org.groovymud.engine.event.observer.Observable;
import org.groovymud.engine.event.observer.Observer;
import org.groovymud.engine.event.system.MovementEvent;
import org.groovymud.object.Container;
import org.groovymud.object.MudObject;
import org.groovymud.object.ObjectLocation;
import org.groovymud.object.alive.Alive;
import org.groovymud.object.alive.Player;
import org.groovymud.object.room.Room;
import org.groovymud.shell.command.CommandInterpreter;
import org.groovymud.shell.telnetd.LoggingExtendedTerminalIO;
import org.groovymud.shell.telnetd.LoginShell;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/* Copyright 2008 Matthew Corby-Eaglen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* The registry is the "root" container for all mud objects all global scoped
* events pass through this object, and in turn are (if necessary) passed down
* to the child rooms and objects.
*
* spring injects mudEngine, mudObjectAttendant, commandIterpreter
*
* this object is spring applicationcontextaware and this will get injected by
* spring automatically.
*/
public class Registry implements Container, Observer, ApplicationContextAware {

  private final static Logger logger = Logger.getLogger(Registry.class);

  private Map<LoginShell, Player> activePlayerHandles;

  protected InventoryHandler inventoryHandler;

  private MudObjectAttendant mudObjectAttendant;

  private ApplicationContext applicationContext;

  private CommandInterpreter commandInterpreter;

  public Registry(InventoryHandler handler) {
    this.inventoryHandler = handler;
  }

  /**
   * registers a parameter with the registry, and re-links all the contents of
   * any containers.
   *
   * This method has to set the registry param of the registered object
   * because persistence removes it
   *
   * @param obj
   */
  public void register(MudObject obj) {
    obj.setRegistry(this);
    obj.setInterpreter(getCommandInterpreter());
    if (isContainerInstance(obj)) {
      Container con = castToContainer(obj);
      con.getInventoryHandler().setRegistry(this);
      con.getInventoryHandler().relinkContent(con);
    }

    if (obj.getId() != null) {
      MudObject old = getMudObject(obj.getId());
      if (old != null) {
        old.dest(false);
      }
    }
    if (isAliveInstance(obj)) {
      Alive alive = castToAlive(obj);
      if (alive.getTerminalOutput() == null) {
        alive.setTerminalOutput(new LoggingExtendedTerminalIO(null));
        LoggingExtendedTerminalIO io = (LoggingExtendedTerminalIO) alive.getTerminalOutput();
        if (io != null) {
          io.setObject(alive);
        }
      }
    }
    addMudObject(obj.getId() == null ? obj.getName() : obj.getId(), obj);
    addMudObject(obj);

  }

  public void update(MudObject object) {
    if (getMudObjects().contains(object)) {
      removeMudObject(object);
      addMudObject(object);
    } else {
      throw new IllegalArgumentException("cannot update registry for " + object);
    }
  }

  protected Alive castToAlive(MudObject obj) {
    return (Alive) obj;
  }

  protected boolean isAliveInstance(MudObject obj) {
    return obj instanceof Alive;
  }

  protected boolean isContainerInstance(MudObject obj) {
    return obj instanceof Container;
  }

  public void addMudObject(String key, MudObject object) {
    getInventoryHandler().addMudObject(key, object);
    addMudObject(object);
    if (object instanceof Room) {
      object.setCurrentContainer(this);
      castToObservable(object).addObserver(this);
    }
  }

  protected Observable castToObservable(MudObject object) {
    return ((Observable) object);
  }

  public void addActivePlayer(LoginShell shell, Player player) {
    addActivePlayerHandle(shell, player);
    if (logger.isDebugEnabled()) {
      logger.debug("There are " + getActivePlayerHandles().size() + " connections active and " + (Runtime.getRuntime().freeMemory() / 1000) + " kBytes free");
    }
  }

  public void removeaActivePlayer(Player player) {
    getActivePlayerHandlesMap().values().remove(player);
  }

  public MudObject removeMudObject(MudObject object) {
    if (object instanceof Player) {
      removeaActivePlayer((Player) object);
    }
    return getInventoryHandler().removeMudObject(object);
  }

  public void addActivePlayerHandle(LoginShell shell, Player player) {
    getActivePlayerHandlesMap().put(shell, player);
  }

  public Player getPlayerByHandle(LoginShell handle) {
    return getActivePlayerHandlesMap().get(handle);
  }

  protected Map<LoginShell, Player> getActivePlayerHandlesMap() {
    if (activePlayerHandles == null) {
      Map<LoginShell, Player> synchronizedMap = Collections.synchronizedMap(new WeakHashMap<LoginShell, Player>());
      activePlayerHandles = synchronizedMap;
    }
    return activePlayerHandles;
  }

  protected Observer castToObserver(Object o) {
    return ((Observer) o);
  }

  public void update(Observable object, ScopedEvent arg) {
    for (Object objs : getMudObjects()) {
      if (objs instanceof MudEventListener) {
        castToMudEventListener(objs).onBeforeMudEvent(arg);
      }
    }
    if (!arg.isConsumed()) {
      if (arg instanceof MovementEvent) {
        findNewContainer(arg);
      }
      if (arg instanceof SaveEvent) {
        doSaveEvent(arg);
      }

      for (Object objs : getMudObjects()) {
        if (objs instanceof MudEventListener) {
          castToMudEventListener(objs).onMudEvent(arg);
        }
      }
    }
    if (!arg.isConsumed()) {
      for (Object objs : getMudObjects()) {
        if (objs instanceof MudEventListener) {
          castToMudEventListener(objs).onAfterMudEvent(arg);
        }
      }
    }
  }

  public MudEventListener castToMudEventListener(Object objs) {
    return ((MudEventListener) objs);
  }

  protected void doSaveEvent(ScopedEvent arg) {
    SaveEvent ev = (SaveEvent) arg;
    getMudObjectAttendant().savePlayerData((Player) ev.getSource());
  }

  public void dest(MudObject object) {
    if (object instanceof Player) {
      fireLeavingMessage((Player) object);
    }
    if (object instanceof Container) {
      unregisterContents(((Container) object));
    }
    removeMudObject(object);
    if (object.getCurrentContainer() != null) {
      object.getCurrentContainer().removeMudObject(object);
    }
    if (object instanceof Player) {
      try {
        ((Player) object).getTerminalOutput().close();
      } catch (IOException e) {
        logger.error(e, e);
      }
    }
  }

  /**
   * removes all objects from any container and sub containers
   *
   * eg. "dest" them
   *
   * @param container
   */
  public void unregisterContents(Container container) {
    for (MudObject obj : container.getInventoryHandler().getMudObjects()) {
      // remove objects from the game, but not from the container
      if (obj instanceof Container) {
        unregisterContents(castToContainer(obj));
      }
      removeMudObject(obj);
    }
  }

  private Container castToContainer(MudObject obj) {
    return ((Container) obj);
  }

  protected void fireLeavingMessage(Player player) {
    MessageEvent leaves = new MessageEvent(EventScope.GLOBAL_SCOPE);
    leaves.setScopeMessage("[" + player.getName() + " leaves GroovyMud]");
    leaves.setSource(player);
    leaves.setSourceMessage("Thanks for visiting!!");
    ((Observable) player).fireEvent(leaves);
  }

  protected synchronized void findNewContainer(ScopedEvent arg) {
    MovementEvent event = (MovementEvent) arg;
    Alive movingObject = event.getMovingObject();
    Container foundContainer = (Container) getMudObject(event.getRoomLocation().getBeanId());
    if (foundContainer == null) {
      Exception anException = null;
      try {
        foundContainer = (Container) getMudObjectAttendant().load(event.getRoomLocation());
      } catch (CompilationFailedException e) {
        logger.error(e, e);
        anException = e;
      } finally {
        if (anException != null) {
          try {
            movingObject.getTerminalOutput().writeln(anException.getMessage());
          } catch (IOException e) {
            logger.error(e, e);
          }
        }
      }
    }
    event.setFoundRoom(foundContainer);
  }

  public void clear() {
    inventoryHandler.clear();
  }

  public boolean contains(MudObject object) {
    return inventoryHandler.contains(object);
  }

  public boolean containsAll(Collection<?> c) {
    return inventoryHandler.containsAll(c);
  }

  public MudObjectAttendant getMudObjectAttendant() {
    return mudObjectAttendant;
  }

  public void setMudObjectAttendant(MudObjectAttendant mudObjectAttendant) {
    this.mudObjectAttendant = mudObjectAttendant;
  }

  public Map<String, Set<MudObject>> getMudObjectsMap() {
    return getInventoryHandler().getMudObjectsMap();
  }

  public HashSet<LoginShell> getActivePlayerHandles() {
    return new HashSet<LoginShell>(getActivePlayerHandlesMap().keySet());
  }

  public void addMudObject(MudObject object) {
    getInventoryHandler().addMudObject(object);
  }

  public MudObject getMudObject(String name) {
    return getInventoryHandler().getMudObject(name);
  }

  public Set<MudObject> getMudObjects(String name) {
    return getInventoryHandler().getMudObjects(name);
  }

  public Set<MudObject> getMudObjects() {
    return getInventoryHandler().getMudObjects();
  }

  public void setInventoryHandler(InventoryHandler inventoryHandler) {
    this.inventoryHandler = inventoryHandler;
  }

  public InventoryHandler getInventoryHandler() {
    return inventoryHandler;
  }

  public EventScope getScope() {
    return EventScope.GLOBAL_SCOPE;
  }

  public ApplicationContext getApplicationContext() {
    return applicationContext;
  }

  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }

  public ObjectLocation getObjectLocation() {
    return null;
  }

  public void setScope(EventScope scope) {

  }

  public void setCommandInterpreter(CommandInterpreter commandInterpreter) {
    this.commandInterpreter = commandInterpreter;
  }

  public CommandInterpreter getCommandInterpreter() {
    return commandInterpreter;
  }

}
TOP

Related Classes of org.groovymud.object.registry.Registry

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.