/******************************************************************************* * Copyright (c) 2015 * * 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 jsettlers.common.buildings.loader; import java.util.Hashtable; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; import jsettlers.common.buildings.IBuilding; import jsettlers.common.buildings.jobs.EBuildingJobType; import jsettlers.common.buildings.jobs.IBuildingJob; import jsettlers.common.material.EMaterialType; import jsettlers.common.material.ESearchType; import jsettlers.common.movable.EDirection; import jsettlers.common.position.RelativePoint; import jsettlers.common.position.ShortPoint2D; public class SimpleBuildingJob extends RelativePoint implements IBuildingJob { private static final long serialVersionUID = 3817438298769294483L; private final float time; private final EMaterialType material; private final EDirection direction; private final EBuildingJobType type; private final ESearchType search; private final String name; private final boolean takeMaterialFromMap; private final EMaterialType[] foodOrder; private IBuildingJob successJob; private IBuildingJob failJob; /** * Creates a new simple building job with the given data. * * @param data * The data */ private SimpleBuildingJob(BuildingJobData data) { super(data.getDx(), data.getDy()); type = data.getType(); time = data.getTime(); material = data.getMaterial(); direction = data.getDirection(); search = data.getSearchType(); name = data.getName(); takeMaterialFromMap = data.isTakeMaterialFromMap(); foodOrder = data.getFoodOrder(); } private SimpleBuildingJob(EBuildingJobType type, int time) { super(0, 0); this.type = type; this.time = time; this.material = null; this.direction = null; this.search = null; this.name = ""; this.takeMaterialFromMap = true; this.foodOrder = null; } @Override public ShortPoint2D calculatePoint(IBuilding building) { return super.calculatePoint(building.getPos()); } @Override public EDirection getDirection() { return direction; } @Override public EMaterialType getMaterial() { return material; } @Override public IBuildingJob getNextFailJob() { return failJob; } @Override public IBuildingJob getNextSucessJob() { return successJob; } @Override public float getTime() { return time; } /** * This method creates a new graph of linked jobs, starting with a start job. * <p> * The data of the provider is not checked for the type of the job. * * @param provider * The provider that provides the job definitions. * @param startJob * The first job. * @return The start job as object and a perfectly linked list. * @throws IllegalArgumentException * if the provider does provide wrog links. */ public static IBuildingJob createLinkedJobs(BuildingJobDataProvider provider, String startJob) { if (startJob == null) { throw new IllegalArgumentException("Start job is null."); } Hashtable<String, SimpleBuildingJob> converted = new Hashtable<String, SimpleBuildingJob>(); fillHashtableWithUnlinked(provider, startJob, converted); linkJobs(provider, converted); return converted.get(startJob); } private static void linkJobs(BuildingJobDataProvider provider, Hashtable<String, SimpleBuildingJob> converted) { Set<Entry<String, SimpleBuildingJob>> items = converted.entrySet(); for (Entry<String, SimpleBuildingJob> item : items) { String name = item.getKey(); SimpleBuildingJob job = item.getValue(); BuildingJobData definition = provider.getJobData(name); job.failJob = converted.get(definition.getNextFailJob()); job.successJob = converted.get(definition.getNextSucessJob()); if (job.failJob == null || job.successJob == null) { throw new IllegalArgumentException("Next jobs were not found."); } } } private static void fillHashtableWithUnlinked(BuildingJobDataProvider provider, String startJob, Hashtable<String, SimpleBuildingJob> converted) { ConcurrentLinkedQueue<String> toBuild = new ConcurrentLinkedQueue<String>(); toBuild.offer(startJob); while (!toBuild.isEmpty()) { String currentName = toBuild.poll(); if (!converted.containsKey(currentName)) { SimpleBuildingJob job = createUnlinkedJob(provider, toBuild, currentName); converted.put(currentName, job); } } } private static SimpleBuildingJob createUnlinkedJob(BuildingJobDataProvider provider, ConcurrentLinkedQueue<String> toBuild, String currentName) { BuildingJobData data = provider.getJobData(currentName); if (data == null) { throw new IllegalArgumentException("Error on building job list conversion: job " + currentName + " not found."); } SimpleBuildingJob job = new SimpleBuildingJob(data); toBuild.add(data.getNextFailJob()); toBuild.add(data.getNextSucessJob()); return job; } @Override public EBuildingJobType getType() { return type; } /** * Creates a primitive fallback job list. * * @return */ public static IBuildingJob createFallback() { SimpleBuildingJob wait = new SimpleBuildingJob(EBuildingJobType.WAIT, 1000); SimpleBuildingJob hide = new SimpleBuildingJob(EBuildingJobType.HIDE, 0); wait.successJob = wait; wait.failJob = wait; hide.successJob = wait; hide.failJob = wait; return hide; } @Override public ESearchType getSearchType() { return search; } @Override public String getName() { return name; } @Override public boolean isTakeMaterialFromMap() { return takeMaterialFromMap; } @Override public EMaterialType[] getFoodOrder() { return foodOrder; } }