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

net.onedaybeard.ecs.model.scan.ConfigurationResolver Maven / Gradle / Ivy

There is a newer version: 0.2.0
Show newest version
package net.onedaybeard.ecs.model.scan;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;

import net.onedaybeard.ecs.util.ClassFinder;

/**
 * Finds all ECS types by inspecting the class hierarchy
 * while matching against known parent classes.
 */
public final class ConfigurationResolver {
	public final String[] aspectRequire;
	public final String[] aspectRequireOne;
	public final String[] aspectExclude;

	public Set managers;
	public Set systems;
	public Set components;
	public Set factories;
	public Type componentMapper;
	private TypeConfiguration typeConfiguration;
	private final Map> parentChildrenMap;

	private final String resourcePrefix;
	
	public ConfigurationResolver(File rootFolder, String ecsResourcePrefix) {
		this.resourcePrefix = ecsResourcePrefix;
		if (!rootFolder.isDirectory())
			throw new RuntimeException("Expected folder - " + rootFolder);
		
		managers = new HashSet();
		systems = new HashSet();
		components = new HashSet();
		factories = new HashSet();
		
		typeConfiguration = new TypeConfiguration(resourcePrefix);
		systems.addAll(typeConfiguration.systems);
		managers.addAll(typeConfiguration.managers);
		components.addAll(typeConfiguration.components);
		factories.addAll(typeConfiguration.factories);
		componentMapper = typeConfiguration.componentMapper;
		aspectRequire = typeConfiguration.aspectRequire;
		aspectRequireOne = typeConfiguration.aspectRequireOne;
		aspectExclude = typeConfiguration.aspectExclude;

		parentChildrenMap = new HashMap>();
		
		List classes = ClassFinder.find(rootFolder);
		for (File f : classes) {
			findExtendedArtemisTypes(f); // for resolving children of children
		}
		
		resolveExtendedTypes(typeConfiguration, parentChildrenMap);
		
		for (File f : classes) {
			findArtemisTypes(f);
		}
	}

	private static void resolveExtendedTypes(TypeConfiguration main, Map> found) {
		main.systems = recursiveResolution(main.systems, found);
		main.managers = recursiveResolution(main.managers, found);
		main.components = recursiveResolution(main.components, found);
		main.factories = recursiveResolution(main.factories, found);
	}

	private static Set recursiveResolution(Set types, Map> found) {
		Set destination = new HashSet();
		for (Type t : types) {
			recursiveResolution(t, found, destination);
		}
		
		return destination;
	}

	private static void recursiveResolution(Type t, Map> found, Set destination) {
		if (found.containsKey(t)) {
			destination.add(t);
			for (Type foundType : found.get(t)) {
				recursiveResolution(foundType, found, destination);
			}
		}
	}

	public EcsTypeData scan(ClassReader source) {
		EcsTypeData info = new EcsTypeData();
		
		EcsScanner typeScanner = new EcsScanner(info, this);
		source.accept(typeScanner, 0);
		return info;
	}
	
	public void clearDefaultTypes() {
		TypeConfiguration tc = new TypeConfiguration(resourcePrefix);
		systems.removeAll(tc.systems);
		managers.removeAll(tc.managers);
		components.removeAll(tc.components);
		factories.removeAll(tc.factories);
	}
	
	// TODO: merge with findArtemisType
	private void findExtendedArtemisTypes(FileInputStream stream) {
		ClassReader cr;
		try {
			cr = new ClassReader(stream);
			ParentChainFinder artemisTypeFinder = new ParentChainFinder(parentChildrenMap);
			cr.accept(artemisTypeFinder, 0);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (stream != null) try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private void findExtendedArtemisTypes(File file) {
		try {
			findExtendedArtemisTypes(new FileInputStream(file));
		} catch (FileNotFoundException e) {
			System.err.println("not found: " + file);
		}
	}

	private void findEcsTypes(FileInputStream stream) {
		ClassReader cr;
		try {
			cr = new ClassReader(stream);
			SurfaceTypeCollector typeCollector = new SurfaceTypeCollector(this, typeConfiguration);
			cr.accept(typeCollector, 0);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (stream != null) try {
				stream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private void findArtemisTypes(File file) {
		try {
			findEcsTypes(new FileInputStream(file));
		} catch (FileNotFoundException e) {
			System.err.println("not found: " + file);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy