001/* 002 * *********************************************************************** * 003 * project: org.matsim.* 004 * *********************************************************************** * 005 * * 006 * copyright : (C) 2019 by the members listed in the COPYING, * 007 * LICENSE and WARRANTY file. * 008 * email : info at matsim dot org * 009 * * 010 * *********************************************************************** * 011 * * 012 * This program is free software; you can redistribute it and/or modify * 013 * it under the terms of the GNU General Public License as published by * 014 * the Free Software Foundation; either version 2 of the License, or * 015 * (at your option) any later version. * 016 * See also COPYING, LICENSE and WARRANTY file * 017 * * 018 * *********************************************************************** * 019 */ 020 021package org.matsim.contrib.dvrp.run; 022 023import java.util.function.Function; 024 025import org.matsim.core.controler.listener.ControlerListener; 026import org.matsim.core.mobsim.framework.listeners.MobsimInitializedListener; 027import org.matsim.core.mobsim.framework.listeners.MobsimListener; 028 029import com.google.inject.Provider; 030 031/** 032 * Typical usecase: binding multi-iteration object stats calculators to overcome the limitation of the QSim scope of Fleet. 033 * Notifies objectListener to that the object has been created. 034 * <p> 035 * If objectListener is also ControllerListener and/or MobsimListener, which is quite typical, 036 * addControlerListenerBinding() and/or addModalComponent() will be called, respectively. 037 * 038 * @author Michal Maciejewski (michalm) 039 */ 040public final class QSimScopeObjectListenerModule<T, L extends QSimScopeObjectListener<T> & ControlerListener & MobsimListener> 041 extends AbstractDvrpModeModule { 042 //without requiring listenerClass to implement ControlerListener & MobsimListener 043 public static <T> AbstractDvrpModeQSimModule createSimplifiedModule(String mode, Class<T> objectClass, 044 Class<? extends QSimScopeObjectListener<T>> listenerClass) { 045 return new AbstractDvrpModeQSimModule(mode) { 046 @Override 047 protected void configureQSim() { 048 addModalQSimComponentBinding().toProvider(modalProvider( 049 getter -> mobsimInitializedListener(getter.getModal(listenerClass), 050 getter.getModal(objectClass)))); 051 } 052 }; 053 } 054 055 private final Class<T> objectClass; 056 private final Class<L> listenerClass; 057 private final Provider<L> listenerProvider; 058 059 private QSimScopeObjectListenerModule(Builder<T, L> builder) { 060 super(builder.mode); 061 objectClass = builder.objectClass; 062 listenerClass = builder.listenerClass; 063 listenerProvider = builder.listenerProvider; 064 } 065 066 @Override 067 public void install() { 068 bindModal(listenerClass).toProvider(listenerProvider).asEagerSingleton(); 069 addControlerListenerBinding().to(modalKey(listenerClass)); 070 071 installQSimModule(new AbstractDvrpModeQSimModule(getMode()) { 072 @Override 073 protected void configureQSim() { 074 addModalQSimComponentBinding().to(modalKey(listenerClass)); 075 addModalQSimComponentBinding().toProvider(modalProvider( 076 getter -> mobsimInitializedListener(getter.getModal(listenerClass), 077 getter.getModal(objectClass)))); 078 } 079 }); 080 } 081 082 private static <T> MobsimInitializedListener mobsimInitializedListener(QSimScopeObjectListener<T> objectListener, 083 T object) { 084 return e -> objectListener.objectCreated(object); 085 } 086 087 public static <T, L extends QSimScopeObjectListener<T> & ControlerListener & MobsimListener> Builder<T, L> builder( 088 Class<L> listenerClass) { 089 return new Builder<>(listenerClass); 090 } 091 092 public static final class Builder<T, L extends QSimScopeObjectListener<T> & ControlerListener & MobsimListener> { 093 private final Class<L> listenerClass; 094 private String mode; 095 private Class<T> objectClass; 096 private Provider<L> listenerProvider; 097 098 private Builder(Class<L> listenerClass) { 099 this.listenerClass = listenerClass; 100 } 101 102 public Builder<T, L> mode(String val) { 103 mode = val; 104 return this; 105 } 106 107 public Builder<T, L> objectClass(Class<T> val) { 108 objectClass = val; 109 return this; 110 } 111 112 public Builder<T, L> listenerCreator(Function<ModalProviders.InstanceGetter, L> val) { 113 listenerProvider = ModalProviders.createProvider(mode, val); 114 return this; 115 } 116 117 public Builder<T, L> listenerProvider(Provider<L> val) { 118 listenerProvider = val; 119 return this; 120 } 121 122 public QSimScopeObjectListenerModule<T, L> build() { 123 return new QSimScopeObjectListenerModule<>(this); 124 } 125 } 126}