/** * @file IntermediateStock.hpp * @author The ARTIS Development Team * See the AUTHORS or Authors.txt file */ /* * ARTIS - the multimodeling and simulation environment * This file is a part of the ARTIS environment * * Copyright (C) 2013-2023 ULCO http://www.univ-littoral.fr * * 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 . */ #ifndef ARTIS_FACTORY_STOCK_HPP #define ARTIS_FACTORY_STOCK_HPP #include "Base.hpp" #include "ProductionOrder.hpp" namespace artis::factory { struct StockEntry { unsigned int po_id; unsigned int po_index; unsigned int product_id; unsigned int quantity; StockEntry(unsigned int po_id = 0, unsigned int po_index = 0, unsigned int product_id = 0, unsigned int quantity = 0) : po_id(po_id), po_index(po_index), product_id(product_id), quantity(quantity) {} bool operator==(const StockEntry &other) const { return po_id == other.po_id and po_index == other.po_index and product_id == other.product_id and quantity == other.quantity; } std::string to_string() const { return "StockEntry < " + std::to_string(po_id) + " | " + std::to_string(po_index) + " | " + std::to_string(product_id) + " | " + std::to_string(quantity) + " >"; } }; struct ProductDemand { unsigned int po_id; unsigned int po_index; unsigned int product_id; unsigned int quantity; ProductDemand(unsigned int po_id = 0, unsigned int po_index = 0, unsigned int product_id = 0, unsigned int quantity = 0) : po_id(po_id), po_index(po_index), product_id(product_id), quantity(quantity) {} bool operator==(const ProductDemand &other) const { return po_id == other.po_id and po_index == other.po_index and product_id == other.product_id and quantity == other.quantity; } std::string to_string() const { return "ProductDemand < " + std::to_string(po_id) + " | " + std::to_string(po_index) + " | " + std::to_string(product_id) + " | " + std::to_string(quantity) + " >"; } }; struct StockAvailableResponse { int po_id; enum values { AVAILABLE, NOT_AVAILABLE, NEW_AVAILABLE } response; StockAvailableResponse(unsigned int po_id = 0, values response = NOT_AVAILABLE) : po_id(po_id), response(response) {} bool operator==(const StockAvailableResponse &other) const { return po_id == other.po_id and response == other.response; } std::string to_string() const { return "StockAvailableResponse < " + std::to_string(po_id) + " | " + (response == AVAILABLE ? "AVAILABLE" : (response == NOT_AVAILABLE ? "NOT AVAILABLE" : "NEW AVAILABLE")) + " >"; } }; struct ProductResponse { int product_id; int po_id; ProductResponse(int product_id = -1, int po_id = -1) : product_id(product_id), po_id(po_id) {} bool operator==(const ProductResponse &other) const { return product_id == other.product_id and po_id == other.po_id; } std::string to_string() const { return "Response < " + std::to_string(product_id) + " | " + std::to_string(po_id) + " >"; } }; struct StockParameters { std::vector _in_machines; std::vector _out_machines; int _capacity; // if -1 then infinity }; class Stock : public Dynamics { public: struct inputs { enum values { IN, IN_DEMAND = 1000, IN_STOCK_AVAILABLE = 2000 }; }; struct outputs { enum values { OUT = 1000, OUT_STOCK_AVAILABLE = 2000 }; }; struct vars { enum values { ENTRY_NUMBER }; }; Stock(const std::string &name, const Context &context) : Dynamics(name, context), _parameters(context.parameters()) { input_port({inputs::IN, "in"}); for (const auto &m: _parameters._in_machines) { output_port({outputs::OUT + m, "out_" + std::to_string(m)}); input_port({inputs::IN_DEMAND + m, "in_demand_" + std::to_string(m)}); } for (const auto &m: _parameters._out_machines) { output_port({outputs::OUT_STOCK_AVAILABLE + m, "out_stock_available_" + std::to_string(m)}); input_port({inputs::IN_STOCK_AVAILABLE + m, "in_stock_available_" + std::to_string(m)}); } observables({{vars::ENTRY_NUMBER, "entry number"}}); } ~Stock() override = default; void dint(const Time &t) override; void dext(const Time &t, const Time &e, const Bag &bag) override; void start(const Time &t) override; Time ta(const Time &t) const override; Bag lambda(const Time &t) const override; artis::common::event::Value observe(const Time &t, unsigned int index) const override; private: struct Phase { enum values { WAIT, SEND, SEND_AVAILABLE }; static std::string to_string(const values &value) { switch (value) { case WAIT: return "WAIT"; case SEND: return "SEND"; case SEND_AVAILABLE: return "SEND AVAILABLE"; } return ""; } }; struct Entry { Time _t; unsigned int _po_id; unsigned int _po_index; unsigned int _product_id; unsigned int _quantity; }; struct AvailableDemand { unsigned int _machine_id; unsigned int _po_id; bool _available; }; StockParameters _parameters; Phase::values _phase; std::vector _entries; std::vector> _demands; std::vector _available_demands; std::deque> _waiting_machine_ids; // pair(machine_id,po_id) }; } // namespace artis::factory #endif