All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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