/
codebase/src/net/sourceforge/pain/admin/console/command/
codebase/src/net/sourceforge/pain/data/role/
codebase/src/net/sourceforge/pain/network/console/telnet/
codebase/src/net/sourceforge/pain/network/guitool/
codebase/src/net/sourceforge/pain/plugin/
codebase/src/net/sourceforge/pain/util/
db/src/net/sourceforge/pain/util/
gui/
gui/lib/
gui/src/net/sourceforge/pain/tools/guitool/dbbrowse/
gui/src/net/sourceforge/pain/tools/guitool/dialog/
gui/src/net/sourceforge/pain/tools/guitool/menu/
gui/src/net/sourceforge/pain/tools/guitool/resources/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/explorer/
mudlibs/tinylib/
mudlibs/tinylib/area/
mudlibs/tinylib/etc/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/prototype/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/deploy/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/fn/util/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/impl/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/command/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/reset/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/shutdown/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/social/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/util/
tests/
tests/src/
tests/src/net/sourceforge/pain/db/data/
package net.sourceforge.pain;

import net.sourceforge.pain.data.*;
import net.sourceforge.pain.db.*;
import net.sourceforge.pain.logic.*;
import net.sourceforge.pain.util.*;

import java.lang.reflect.*;
import java.util.*;

/**
 * User: fmike  Date: Mar 7, 2004  Time: 1:58:28 AM
 */
final class AffectProcessor extends PulsePeriodListener implements LogicReloadListener {
    private final TimedAffectsQueue tq;
    private HashMap cache = new HashMap();
    private Class[] affectArgsTypes = new Class[]{AffectData.class};
    private Object[] affectArgsValues = new Object[1];

    public AffectProcessor(TimedAffectsQueue tq) {
        super(1, PERIOD_IN_SECONDS);
        this.tq = tq;
        Codebase.getLogicLoader().addLogicReloadListener(this);
    }

    protected void onPeriod(int time) {
        TimedAffectData aff = tq.getFirstOff();
        if (aff != null) {
            final int affectOffTime = aff.getAffectOffTime();
            Log.debug("Off time:" + affectOffTime + " time:" + time);
            if (affectOffTime <= time) {
                processExpired(aff);
            }
        }
    }


    private void processExpired(TimedAffectData aff) {
        try {
            final TimedAffect affLogic = getAffectInstance(aff);
            DbTransaction t = new DbTransaction() {
                public Object execute(Object[] params) throws Exception {
                    affLogic.onAffectTimeExpired();
                    return null;
                }
            };
            Codebase.getDB().execute(t);
        } catch (Exception e) {
            Log.error(e);
        } finally {
            //this is upper level, no active transaction here
            if (!aff.isDetached() && aff.getAffectOffTime() <= Codebase.getPulse().currentTime()) {
                aff.delete();//deletes affect and detaches object from db
            }
        }
    }

    private TimedAffect getAffectInstance(TimedAffectData aff) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        String classSuffix = aff.getAffectClassName();
        TimedAffect affLogic = (TimedAffect) cache.get(classSuffix);
        if (affLogic == null) {
            affectArgsValues[0] = aff;
            Class c = Codebase.getLogicLoader().provideClass(Codebase.AFFECTS_LOGIC_PACKAGE_PREFIX  + aff.getAffectClassName());
            affLogic = (TimedAffect) c.getDeclaredConstructor(affectArgsTypes).newInstance(affectArgsValues);
            cache.put(classSuffix, affLogic);
            affectArgsValues[0] = null;
        }
        return (TimedAffect) affLogic.newInstance(aff);
    }

    public void onLogicReloading() {
        cache.clear();
    }
}