de.rpgframework.random.RandomGeneratorRegistry Maven / Gradle / Ivy
The newest version!
package de.rpgframework.random;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.ServiceLoader;
import java.util.stream.Collectors;
import org.prelle.simplepersist.Persister;
import de.rpgframework.classification.Classification;
import de.rpgframework.classification.ClassificationType;
import de.rpgframework.classification.Taxonomy;
import de.rpgframework.genericrpg.modification.ModifiedObjectType;
/**
* @author prelle
*
*/
public class RandomGeneratorRegistry {
private final static Logger logger = System.getLogger(RandomGeneratorRegistry.class.getPackageName());
private static Map> knownByType;
static {
knownByType = new HashMap<>();
new Taxonomy();
}
//-------------------------------------------------------------------
public static void initialize() {
Persister.putContext(Persister.PREFIX_KEY_INTERFACE+"."+ModifiedObjectType.class.getName(), GeneratorReference.class);
ServiceLoader.load(GeneratorInitializer.class).forEach(init -> {
logger.log(Level.DEBUG, "Initializing "+init.getClass());
init.getGeneratorsToRegister().forEach(gen -> {
RandomGeneratorRegistry.register(gen);
});
});
}
//-------------------------------------------------------------------
public static void register(RandomGenerator gen) {
logger.log(Level.WARNING, "register {0} as {1}", gen.getClass().getSimpleName(), gen.getType());
List addTo = knownByType.get(gen.getType());
if (addTo==null) {
addTo = new ArrayList<>();
knownByType.put(gen.getType(), addTo);
}
logger.log(Level.INFO, "Registered "+gen.getClass()+" as "+gen.getType()+" generator");
addTo.add(gen);
}
//-------------------------------------------------------------------
public static RandomGenerator findGenerator(GeneratorType type, List> requires, List hints) {
logger.log(Level.DEBUG, "Requires: "+requires);
logger.log(Level.DEBUG, "hints: "+hints);
List possible = findGenerators(type, requires, hints);
// Take the best generator
RandomGenerator gen = possible.get(0);
logger.log(Level.INFO, "Use generator "+gen.getClass()+" for "+type);
return gen;
}
//-------------------------------------------------------------------
public static List findGenerators(GeneratorType type, List> requires, List hints) {
logger.log(Level.WARNING, "Known generator types: "+knownByType.keySet());
List possible = knownByType.get(type);
if (possible==null) {
logger.log(Level.WARNING, "No generators for type "+type);
return null;
}
logger.log(Level.DEBUG, "We have {0} generators for {1}", possible.size(), type);
if (possible.isEmpty())
throw new NoSuchElementException("No generator support for "+type);
// Now apply filters
possible = possible.stream().filter(gen -> requires.stream().allMatch(cls -> gen.matchesFilter(cls))).collect(Collectors.toList());
logger.log(Level.DEBUG, "After following requirements {0} this is down to {1}", requires, possible.size());
if (possible.isEmpty())
throw new NoSuchElementException("With this requirements there is no generator available");
for (RandomGenerator opt : possible) {
logger.log(Level.DEBUG, "--> {0} providing {1}", opt.getClass().getSimpleName(), opt.getProvidedData());
}
// Now we have a list of generators which could do the job
// Prefer those which understand the hints best
Collections.sort(possible, new Comparator() {
public int compare(RandomGenerator gen1, RandomGenerator gen2) {
long count1 = hints.stream().filter(cls -> gen1.understandsHint(cls)).count();
long count2 = hints.stream().filter(cls -> gen2.understandsHint(cls)).count();
int cmp = -Long.compare(count1, count2);
if (cmp!=0) return cmp;
return -Integer.compare(gen1.getProvidedData().size(), gen2.getProvidedData().size());
}
});
return possible;
}
//-------------------------------------------------------------------
public static Object generate(GeneratorType type, List> requires, List> hints, Map variables) {
List optionalHints = hints.stream().map(cl -> cl.getType()).toList();
RandomGenerator gen = findGenerator(type, requires, optionalHints);
// Merge requirements and hints
List> merged = new ArrayList<>(requires);
merged.addAll(hints);
logger.log(Level.DEBUG, "Hints: "+merged);
logger.log(Level.DEBUG, "Variables: "+variables);
VariableHolderNode context = new VariableHolderNode()
.withVariables(variables)
.withHints(merged)
;
return gen.generate(context);
}
//-------------------------------------------------------------------
public static Collection getSupportedTypes() {
return knownByType.keySet();
}
//-------------------------------------------------------------------
public static List getGenerators(GeneratorType type) {
return knownByType.get(type);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy