/******************************************************************************* * TurtleKit 3 - Agent Based and Artificial Life Simulation Platform * Copyright (C) 2011-2014 Fabien Michel * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package turtlekit.kernel; import static turtlekit.agr.TKOrganization.ENGINE_GROUP; import static turtlekit.agr.TKOrganization.MODEL_GROUP; import static turtlekit.agr.TKOrganization.MODEL_ROLE; import static turtlekit.agr.TKOrganization.SCHEDULER_ROLE; import static turtlekit.agr.TKOrganization.TURTLES_GROUP; import static turtlekit.agr.TKOrganization.TURTLE_ROLE; import static turtlekit.kernel.TurtleKit.Option.cuda; import static turtlekit.kernel.TurtleKit.Option.endTime; import static turtlekit.kernel.TurtleKit.Option.envDimension; import static turtlekit.kernel.TurtleKit.Option.envHeight; import static turtlekit.kernel.TurtleKit.Option.envWidth; import static turtlekit.kernel.TurtleKit.Option.environment; import static turtlekit.kernel.TurtleKit.Option.launcher; import static turtlekit.kernel.TurtleKit.Option.model; import static turtlekit.kernel.TurtleKit.Option.scheduler; import static turtlekit.kernel.TurtleKit.Option.startSimu; import static turtlekit.kernel.TurtleKit.Option.turtles; import static turtlekit.kernel.TurtleKit.Option.viewers; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import madkit.action.SchedulingAction; import madkit.i18n.ErrorMessages; import madkit.kernel.Agent; import madkit.kernel.Madkit; import madkit.kernel.Madkit.Option; import madkit.message.SchedulingMessage; import madkit.util.XMLUtilities; import turtlekit.agr.TKOrganization; import turtlekit.cuda.CudaEngine; import turtlekit.kernel.TurtleKit.LevelOption; public class TKLauncher extends Agent { private int width = 200; private int height = 200; // private TKScheduler sch; private String community; private Document dom; public TKLauncher() { } @Override protected void activate() { // setLogLevel(Level.ALL); initProperties(); createGroup(TKOrganization.TK_COMMUNITY, TKOrganization.LAUNCHING); createGroup(community, ENGINE_GROUP); createGroup(community, MODEL_GROUP); createGroup(community, TURTLES_GROUP); requestRole(community, ENGINE_GROUP, MODEL_ROLE); if (isMadkitPropertyTrue(TurtleKit.Option.cuda) && ! CudaEngine.init(getMadkitProperty(LevelOption.turtleKitLogLevel))){ setMadkitProperty(TurtleKit.Option.cuda, "false"); } createSimulationInstance(); if(isMadkitPropertyTrue(startSimu)){ sendMessage(community, ENGINE_GROUP, SCHEDULER_ROLE, new SchedulingMessage(SchedulingAction.RUN)); } } protected void live() { }//avoid the Agent's default live message protected void createSimulationInstance(){ if (! launchXMLAgents("Environment")) { launchAgent(getMadkitProperty(environment)); } if (! launchXMLAgents("Scheduler")) { // System.err.println(getMadkitProperty(turtlekit.kernel.TurtleKit.Option.community)); launchScheduler(); } launchConfigTurtles(); if (! launchXMLAgents("Viewer")) { launchViewers(); } launchXMLAgents("Agent"); } protected void launchScheduler(){ final TKScheduler sch = (TKScheduler) launchAgent(getMadkitProperty(scheduler)); try { sch.setSimulationDuration(Integer.parseInt(getMadkitProperty(endTime))); } catch (NumberFormatException | NullPointerException e) { } } protected void launchViewers() { final String viewerClasses = getMadkitProperty(viewers); if (viewerClasses != null && ! viewerClasses.equals("null")) { for (final String v : viewerClasses.split(";")) { launchAgent(v, true); } } } private NodeList getDomNodes(String nodeName){ return dom.getElementsByTagName(nodeName); } private boolean launchXMLAgents(String type){ boolean done = false; if (dom != null) { NodeList nodes = getDomNodes(type); for (int i = 0; i < nodes.getLength(); i++) { final Node item = nodes.item(i); if (launchNode(item) == ReturnCode.SUCCESS) { done = true; } } } return done; } private void launchXmlTurtles(){ if (dom != null) { NodeList nodes = getDomNodes("Turtle"); for (int i = 0; i < nodes.getLength(); i++) { final Node turtleNode = nodes.item(i); final NamedNodeMap namesMap = turtleNode.getAttributes(); String[] roles = null; try { roles = namesMap.getNamedItem("roles").getNodeValue().split(";"); } catch (NullPointerException e) { } appendBucketModeNode(turtleNode,TURTLE_ROLE); if (roles != null) { for (String role : roles) { appendBucketModeNode(turtleNode, role); } } launchNode(turtleNode); } } } /** * @param turtleNode * @param turtleRole */ private void appendBucketModeNode(final Node turtleNode, String role) { Element turtleRole = dom.createElement(XMLUtilities.BUCKET_MODE_ROLE); turtleRole.setAttribute("community",community); turtleRole.setAttribute("group",TURTLES_GROUP); turtleRole.setAttribute("role", role); turtleNode.appendChild(turtleRole); } /** * */ protected void initProperties(){ String modelFile = getMadkitProperty(model); if (modelFile != null) { try { getMadkitConfig().loadPropertiesFromFile(modelFile); if (modelFile.endsWith(".xml")) { dom = XMLUtilities.getDOM(modelFile); } } catch (SAXException | IOException | ParserConfigurationException e) { e.printStackTrace(); } } community = getMadkitProperty(model); if (community == null) { community = getMadkitProperty(turtlekit.kernel.TurtleKit.Option.community); } else{ setMadkitProperty(turtlekit.kernel.TurtleKit.Option.community,community); } // if (community == null) { // community = TLKOrganization.TK_COMMUNITY; // setMadkitProperty(communityName.name(), community); // } try { String widthParam = getMadkitProperty(envWidth); String heightParam = getMadkitProperty(envHeight); if (heightParam != null || widthParam != null) { setMadkitProperty(envDimension, (widthParam != null ? widthParam : "200") + "," + (heightParam != null ? heightParam : "200")); } String[] dimension = getMadkitProperty(envDimension).split(","); setMadkitProperty(envWidth, dimension[0]); if (dimension.length > 1) { setMadkitProperty(envHeight, dimension[1]); } else{ setMadkitProperty(envHeight, dimension[0]); } width = Integer.parseInt(getMadkitProperty(envWidth)); height = Integer.parseInt(getMadkitProperty(envHeight)); } catch (NumberFormatException e) { e.printStackTrace(); setMadkitProperty(envWidth, "200"); setMadkitProperty(envHeight, "200"); } } /** * */ public static void main(String[] args) { executeThisAgent(1,false,Option.configFile.toString(),"turtlekit/kernel/turtlekit.properties",cuda.toString(), turtles.toString(),Turtle.class.getName()); } /** * This offers a convenient way to create a main method * that launches a simulation using the environment * class under development. * This call only works in the main method of the environment. * * @param args * MaDKit or TurtleKit options * @see #executeThisAgent(int, boolean, String...) * @since TurtleKit 3.0.0.1 */ protected static void executeThisLauncher(String... args) { StackTraceElement element = null; for (StackTraceElement stackTraceElement : new Throwable().getStackTrace()) { if(stackTraceElement.getMethodName().equals("main")){ element = stackTraceElement; break; } } final ArrayList<String> arguments = new ArrayList<>(Arrays.asList( Madkit.BooleanOption.desktop.toString(),"false", Madkit.Option.configFile.toString(), "turtlekit/kernel/turtlekit.properties", launcher.toString(), element.getClassName())); if (args != null) { arguments.addAll(Arrays.asList(args)); } new Madkit(arguments.toArray(new String[0])); } protected void launchConfigTurtles(){ // Timer.startTimer(this); // if (logger != null) // logger.info("** LAUNCHING CONFIG TURTLES **"); launchXmlTurtles(); final String agentsTolaunch = getMadkitProperty(turtles); if (!agentsTolaunch.equals("null")) { final String[] agentsClasses = agentsTolaunch.split(";"); for (final String classNameAndOption : agentsClasses) { final String[] classAndOptions = classNameAndOption.split(","); final String className = classAndOptions[0].trim();// TODO should test if these classes exist int number = 1; if (classAndOptions.length > 1) { try { number = Integer.parseInt(classAndOptions[1].trim()); } catch (NumberFormatException e) { getLogger().severeLog(ErrorMessages.OPTION_MISUSED.toString() +Option.launchAgents.toString()+" "+ agentsTolaunch +" "+e.getClass().getName()+" !!!\n" , null); } } if (logger != null) logger.info("Launching " + number + " instance(s) of " + className); launchAgentBucket(className,number,Runtime.getRuntime().availableProcessors()+1,community+","+TKOrganization.TURTLES_GROUP+","+TKOrganization.TURTLE_ROLE); } } // Timer.stopTimer(this); } /** * @return the width */ public int getWidth() { return width; } /** * @param width the width to set */ public void setWidth(int width) { this.width = width; } /** * @return the height */ public int getHeight() { return height; } /** * @param height the height to set */ public void setHeight(int height) { this.height = height; } }