/*
* This file is part of Mixin, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.asm.launch.platform;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.launch.Blackboard;
import net.minecraft.launchwrapper.ITweaker;
import net.minecraft.launchwrapper.LaunchClassLoader;
/**
* A collection of {@link IMixinPlatformAgent} platform agents)
*/
public class MixinContainer {
private static final List<String> agentClasses = new ArrayList<String>();
static {
Blackboard.put(Blackboard.Keys.AGENTS, MixinContainer.agentClasses);
MixinContainer.agentClasses.add("org.spongepowered.asm.launch.platform.MixinPlatformAgentFML");
MixinContainer.agentClasses.add("org.spongepowered.asm.launch.platform.MixinPlatformAgentDefault");
}
private final Logger logger = LogManager.getLogger("mixin");
private final URI uri;
private final List<IMixinPlatformAgent> agents = new ArrayList<IMixinPlatformAgent>();
public MixinContainer(MixinPlatformManager manager, URI uri) {
this.uri = uri;
for (String agentClass : MixinContainer.agentClasses) {
try {
@SuppressWarnings("unchecked")
Class<IMixinPlatformAgent> clazz = (Class<IMixinPlatformAgent>)Class.forName(agentClass);
Constructor<IMixinPlatformAgent> ctor = clazz.getDeclaredConstructor(MixinPlatformManager.class, URI.class);
this.logger.debug("Instancing new {} for {}", clazz.getSimpleName(), this.uri);
IMixinPlatformAgent agent = ctor.newInstance(manager, uri);
this.agents.add(agent);
} catch (Exception ex) {
this.logger.catching(ex);
}
}
}
/**
*
*/
public URI getURI() {
return this.uri;
}
/**
* Get phase provider names from all agents in this container
*/
public Collection<String> getPhaseProviders() {
List<String> phaseProviders = new ArrayList<String>();
for (IMixinPlatformAgent agent : this.agents) {
String phaseProvider = agent.getPhaseProvider();
if (phaseProvider != null) {
phaseProviders.add(phaseProvider);
}
}
return phaseProviders;
}
/**
* Prepare agents in this container
*/
public void prepare() {
for (IMixinPlatformAgent agent : this.agents) {
this.logger.debug("Processing prepare() for {}", agent);
agent.prepare();
}
}
/**
* If this container is the primary container, initialise agents in this
* container as primary
*/
public void initPrimaryContainer() {
for (IMixinPlatformAgent agent : this.agents) {
this.logger.debug("Processing launch tasks for {}", agent);
agent.initPrimaryContainer();
}
}
/**
* Notify all agents to inject into classLoader
*
* @param classLoader classLoader to injec
*/
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
for (IMixinPlatformAgent agent : this.agents) {
this.logger.debug("Processing injectIntoClassLoader() for {}", agent);
agent.injectIntoClassLoader(classLoader);
}
}
/**
* Analogue of {@link ITweaker#getLaunchTarget}, queries all agents and
* returns first valid launch target. Returns null if no agents have launch
* target.
*
* @return launch target from agent or null
*/
public String getLaunchTarget() {
for (IMixinPlatformAgent agent : this.agents) {
String launchTarget = agent.getLaunchTarget();
if (launchTarget != null) {
return launchTarget;
}
}
return null;
}
}