<commit_before>/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2013 Ausenco Engineering Canada Inc.
 * Copyright (C) 2016-2019 JaamSim Software Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jaamsim.resourceObjects;

import java.util.ArrayList;

import com.jaamsim.Graphics.DisplayEntity;
import com.jaamsim.ProbabilityDistributions.Distribution;
import com.jaamsim.Samples.SampleConstant;
import com.jaamsim.Samples.SampleInput;
import com.jaamsim.Samples.TimeSeries;
import com.jaamsim.Statistics.TimeBasedFrequency;
import com.jaamsim.Statistics.TimeBasedStatistics;
import com.jaamsim.basicsim.Entity;
import com.jaamsim.events.Conditional;
import com.jaamsim.events.EventManager;
import com.jaamsim.events.ProcessTarget;
import com.jaamsim.input.InputErrorException;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
import com.jaamsim.units.DimensionlessUnit;
import com.jaamsim.units.TimeUnit;

public class Resource extends AbstractResourceProvider {

	@Keyword(description = "The number of equivalent resource units that are available.\n"
	                     + "If the capacity changes during the simulation run, the Resource will "
	                     + "attempt to use an increase in capacity as soon as it occurs. "
	                     + "However, a decrease in capacity will have no affect on entities that "
	                     + "have already seized Resource capacity.",
	         exampleList = {"3", "TimeSeries1", "this.attrib1"})
	private final SampleInput capacity;

	private int unitsInUse;  // number of resource units that are being used at present
	private int lastCapacity; // capacity for the resource

	//	Statistics
	private final TimeBasedStatistics stats;
	private final TimeBasedFrequency freq;
	protected int unitsSeized;    // number of units that have been seized
	protected int unitsReleased;  // number of units that have been released

	{
		attributeDefinitionList.setHidden(false);

		capacity = new SampleInput("Capacity", KEY_INPUTS, new SampleConstant(1.0));
		capacity.setUnitType(DimensionlessUnit.class);
		capacity.setValidRange(0, Double.POSITIVE_INFINITY);
		this.addInput(capacity);
	}

	public Resource() {
		stats = new TimeBasedStatistics();
		freq = new TimeBasedFrequency(0, 10);
	}

	@Override
	public void validate() {

		boolean found = false;
		for (Entity ent : getJaamSimModel().getClonesOfIterator(Entity.class, ResourceUser.class)) {
			ResourceUser ru = (ResourceUser) ent;
			if (ru.requiresResource(this))
				found = true;
		}
		if (!found)
			throw new InputErrorException( "At least one object must seize this resource." );

		if( capacity.getValue() instanceof Distribution )
			throw new InputErrorException( "The Capacity keyword cannot accept a probability distribution.");
	}

	@Override
	public void earlyInit() {
		super.earlyInit();

		unitsInUse = 0;
		lastCapacity = this.getCapacity(0.0d);

		// Clear statistics
		stats.clear();
		stats.addValue(0.0d, 0);
		freq.clear();
		freq.addValue(0.0d,  0);
		unitsSeized = 0;
		unitsReleased = 0;
	}

	@Override
	public void startUp() {
		super.startUp();

		if (capacity.getValue() instanceof SampleConstant)
			return;

		// Track any changes in the Resource's capacity
		this.waitForCapacityChange();
	}

	@Override
	public boolean canSeize(int n, DisplayEntity ent) {
		double simTime = getSimTime();
		return getAvailableUnits(simTime) >= n;
	}

	@Override
	public void seize(int n, DisplayEntity ent) {
		double simTime = getSimTime();
		if (getAvailableUnits(simTime) < n)
			error(ERR_CAPACITY, getCapacity(simTime), n);

		unitsInUse += n;
		unitsSeized += n;
		stats.addValue(simTime, unitsInUse);
		freq.addValue(simTime, unitsInUse);
	}

	@Override
	public void release(int m, DisplayEntity ent) {
		int n = Math.min(m, unitsInUse);
		unitsInUse -= n;
		unitsReleased += n;
		double simTime = this.getSimTime();
		stats.addValue(simTime, unitsInUse);
		freq.addValue(simTime, unitsInUse);
	}

	/**
	 * Returns true if the saved capacity differs from the present capacity
	 * @return true if the capacity has changed
	 */
	boolean isCapacityChanged() {
		return this.getCapacity(getSimTime()) != lastCapacity;
	}

	/**
	 * Loops from one capacity change to the next.
	 */
	void waitForCapacityChange() {

		// Set the present capacity
		lastCapacity = this.getCapacity(getSimTime());<commit_msg>JS: add trace output to Resource<commit_after>/*
 * JaamSim Discrete Event Simulation
 * Copyright (C) 2013 Ausenco Engineering Canada Inc.
 * Copyright (C) 2016-2019 JaamSim Software Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jaamsim.resourceObjects;

import java.util.ArrayList;

import com.jaamsim.Graphics.DisplayEntity;
import com.jaamsim.ProbabilityDistributions.Distribution;
import com.jaamsim.Samples.SampleConstant;
import com.jaamsim.Samples.SampleInput;
import com.jaamsim.Samples.TimeSeries;
import com.jaamsim.Statistics.TimeBasedFrequency;
import com.jaamsim.Statistics.TimeBasedStatistics;
import com.jaamsim.basicsim.Entity;
import com.jaamsim.events.Conditional;
import com.jaamsim.events.EventManager;
import com.jaamsim.events.ProcessTarget;
import com.jaamsim.input.InputErrorException;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
import com.jaamsim.units.DimensionlessUnit;
import com.jaamsim.units.TimeUnit;

public class Resource extends AbstractResourceProvider {

	@Keyword(description = "The number of equivalent resource units that are available.\n"
	                     + "If the capacity changes during the simulation run, the Resource will "
	                     + "attempt to use an increase in capacity as soon as it occurs. "
	                     + "However, a decrease in capacity will have no affect on entities that "
	                     + "have already seized Resource capacity.",
	         exampleList = {"3", "TimeSeries1", "this.attrib1"})
	private final SampleInput capacity;

	private int unitsInUse;  // number of resource units that are being used at present
	private int lastCapacity; // capacity for the resource

	//	Statistics
	private final TimeBasedStatistics stats;
	private final TimeBasedFrequency freq;
	protected int unitsSeized;    // number of units that have been seized
	protected int unitsReleased;  // number of units that have been released

	{
		trace.setHidden(false);
		attributeDefinitionList.setHidden(false);

		capacity = new SampleInput("Capacity", KEY_INPUTS, new SampleConstant(1.0));
		capacity.setUnitType(DimensionlessUnit.class);
		capacity.setValidRange(0, Double.POSITIVE_INFINITY);
		this.addInput(capacity);
	}

	public Resource() {
		stats = new TimeBasedStatistics();
		freq = new TimeBasedFrequency(0, 10);
	}

	@Override
	public void validate() {

		boolean found = false;
		for (Entity ent : getJaamSimModel().getClonesOfIterator(Entity.class, ResourceUser.class)) {
			ResourceUser ru = (ResourceUser) ent;
			if (ru.requiresResource(this))
				found = true;
		}
		if (!found)
			throw new InputErrorException( "At least one object must seize this resource." );

		if( capacity.getValue() instanceof Distribution )
			throw new InputErrorException( "The Capacity keyword cannot accept a probability distribution.");
	}

	@Override
	public void earlyInit() {
		super.earlyInit();

		unitsInUse = 0;
		lastCapacity = this.getCapacity(0.0d);

		// Clear statistics
		stats.clear();
		stats.addValue(0.0d, 0);
		freq.clear();
		freq.addValue(0.0d,  0);
		unitsSeized = 0;
		unitsReleased = 0;
	}

	@Override
	public void startUp() {
		super.startUp();

		if (capacity.getValue() instanceof SampleConstant)
			return;

		// Track any changes in the Resource's capacity
		this.waitForCapacityChange();
	}

	@Override
	public boolean canSeize(int n, DisplayEntity ent) {
		double simTime = getSimTime();
		return getAvailableUnits(simTime) >= n;
	}

	@Override
	public void seize(int n, DisplayEntity ent) {
		if (isTraceFlag()) trace(1, "seize(%s, %s)", n, ent);
		double simTime = getSimTime();
		if (getAvailableUnits(simTime) < n)
			error(ERR_CAPACITY, getCapacity(simTime), n);

		unitsInUse += n;
		unitsSeized += n;
		stats.addValue(simTime, unitsInUse);
		freq.addValue(simTime, unitsInUse);
	}

	@Override
	public void release(int m, DisplayEntity ent) {
		if (isTraceFlag()) trace(1, "release(%s, %s)", m, ent);
		int n = Math.min(m, unitsInUse);
		unitsInUse -= n;
		unitsReleased += n;
		double simTime = this.getSimTime();
		stats.addValue(simTime, unitsInUse);
		freq.addValue(simTime, unitsInUse);
	}

	/**
	 * Returns true if the saved capacity differs from the present capacity
	 * @return true if the capacity has changed
	 */
	boolean isCapacityChanged() {
		return this.getCapacity(getSimTime()) != lastCapacity;
	}

	/**
	 * Loops from one capacity change to the next.
	 */
	void waitForCapacityChange() {

		// Set the present capacity
		lastCapacity = this.getCapacity(getSimTime());
{'fraction_non_alphanumeric': 0.0972543497938248, 'fraction_numerical': 0.0074424218042844215, 'mean_word_length': 4.063136456211812, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4329222', 'n_tokens_mistral': 3104, 'n_tokens_neox': 2854, 'n_words': 919}