LCOV - code coverage report
Current view: top level - PTN_Engine - Place.cpp (source / functions) Hit Total Coverage
Test: filtered_coverage.info Lines: 80 87 92.0 %
Date: 2024-05-26 15:41:39 Functions: 15 16 93.8 %

          Line data    Source code
       1             : /*
       2             :  * This file is part of PTN Engine
       3             :  *
       4             :  * Copyright (c) 2017-2024 Eduardo ValgĂ´de
       5             :  *
       6             :  * Licensed under the Apache License, Version 2.0 (the "License");
       7             :  * you may not use this file except in compliance with the License.
       8             :  * You may obtain a copy of the License at
       9             :  *
      10             :  * http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  * Unless required by applicable law or agreed to in writing, software
      13             :  * distributed under the License is distributed on an "AS IS" BASIS,
      14             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  * See the License for the specific language governing permissions and
      16             :  * limitations under the License.
      17             :  */
      18             : 
      19             : #include "PTN_Engine/Place.h"
      20             : #include "PTN_Engine/Executor/IActionsExecutor.h"
      21             : #include "PTN_Engine/PTN_EngineImp.h"
      22             : #include "PTN_Engine/PTN_Exception.h"
      23             : #include "PTN_Engine/Utilities/LockWeakPtr.h"
      24             : #include <mutex>
      25             : #include <string>
      26             : #include <thread>
      27             : 
      28             : 
      29             : namespace ptne
      30             : {
      31             : using namespace std;
      32             : 
      33         282 : Place::~Place() = default;
      34             : 
      35         284 : Place::Place(const PlaceProperties &placeProperties, const shared_ptr<IActionsExecutor> &executor)
      36         284 : : m_name(placeProperties.name)
      37         284 : , m_onEnterActionName(placeProperties.onEnterActionFunctionName)
      38         286 : , m_onEnterAction(placeProperties.onEnterAction)
      39         284 : , m_onExitActionName(placeProperties.onExitActionFunctionName)
      40         284 : , m_onExitAction(placeProperties.onExitAction)
      41         284 : , m_numberOfTokens(placeProperties.initialNumberOfTokens)
      42         284 : , m_isInputPlace(placeProperties.input)
      43         852 : , m_actionsExecutor(executor)
      44             : {
      45         284 :         if (!m_onEnterActionName.empty() && m_onEnterAction == nullptr)
      46             :         {
      47           1 :                 throw PTN_Exception("On enter action function must be specified.");
      48             :         }
      49             : 
      50         283 :         if (!m_onExitActionName.empty() && m_onExitAction == nullptr)
      51             :         {
      52           1 :                 throw PTN_Exception("On exit action function must be specified.");
      53             :         }
      54         294 : }
      55             : 
      56         252 : string Place::getName() const
      57             : {
      58         252 :         return m_name;
      59             : }
      60             : 
      61      811363 : void Place::enterPlace(const size_t tokens)
      62             : {
      63      811363 :         unique_lock guard(m_mutex);
      64      811363 :         increaseNumberOfTokens(tokens);
      65      811361 :         if (m_onEnterAction == nullptr)
      66             :         {
      67        6842 :                 return;
      68             :         }
      69      804519 :         while (m_blockStartingOnEnterActions)
      70             :         {
      71             :                 // TO DO make this wait period configurable
      72             :                 // add a max wait time after which an exception
      73             :                 // is thrown.
      74           0 :                 this_thread::sleep_for(100ms);
      75             :         }
      76      804519 :         lockWeakPtr(m_actionsExecutor)->executeAction(m_onEnterAction, m_onEnterActionsInExecution);
      77      811363 : }
      78             : 
      79     1206711 : void Place::exitPlace(const size_t tokens)
      80             : {
      81     1206711 :         unique_lock guard(m_mutex);
      82     1206711 :         decreaseNumberOfTokens(tokens);
      83     1206710 :         if (m_onExitAction == nullptr)
      84             :         {
      85     1202282 :                 return;
      86             :         }
      87        4428 :         lockWeakPtr(m_actionsExecutor)->executeAction(m_onExitAction, m_onExitActionsInExecution);
      88     1206711 : }
      89             : 
      90      811363 : void Place::increaseNumberOfTokens(const size_t tokens)
      91             : {
      92      811363 :         if (tokens == 0)
      93             :         {
      94           1 :                 throw NullTokensException();
      95             :         }
      96             : 
      97      811362 :         if (tokens > ULLONG_MAX - m_numberOfTokens)
      98             :         {
      99           1 :                 throw OverflowException(tokens);
     100             :         }
     101             : 
     102      811361 :         m_numberOfTokens += tokens;
     103      811361 : }
     104             : 
     105     1206711 : void Place::decreaseNumberOfTokens(const size_t tokens)
     106             : {
     107     1206711 :         if (m_numberOfTokens < tokens)
     108             :         {
     109           1 :                 throw NotEnoughTokensException();
     110             :         }
     111     1206710 :         if (tokens == 0) // reset
     112             :         {
     113           0 :                 m_numberOfTokens = 0;
     114             :         }
     115             :         else
     116             :         {
     117     1206710 :                 m_numberOfTokens -= tokens;
     118             :         }
     119     1206710 : }
     120             : 
     121          13 : void Place::setNumberOfTokens(const size_t tokens)
     122             : {
     123          13 :         unique_lock guard(m_mutex);
     124          13 :         m_numberOfTokens = tokens;
     125          13 : }
     126             : 
     127     3882132 : size_t Place::getNumberOfTokens() const
     128             : {
     129     3882132 :         shared_lock guard(m_mutex);
     130     3882132 :         return m_numberOfTokens;
     131     3882132 : }
     132             : 
     133        2678 : bool Place::isInputPlace() const
     134             : {
     135        2678 :         shared_lock guard(m_mutex);
     136        2678 :         return m_isInputPlace;
     137        2678 : }
     138             : 
     139           1 : string Place::getOnEnterActionName() const
     140             : {
     141           1 :         shared_lock guard(m_mutex);
     142           2 :         return m_onEnterActionName;
     143           1 : }
     144             : 
     145           1 : string Place::getOnExitActionName() const
     146             : {
     147           1 :         shared_lock guard(m_mutex);
     148           2 :         return m_onExitActionName;
     149           1 : }
     150             : 
     151          10 : bool Place::isOnEnterActionInExecution() const
     152             : {
     153          10 :         return m_onEnterActionsInExecution > 0;
     154             : }
     155             : 
     156           8 : void Place::blockStartingOnEnterActions(const bool value)
     157             : {
     158           8 :         m_blockStartingOnEnterActions = value;
     159           8 : }
     160             : 
     161          32 : PlaceProperties Place::placeProperties() const
     162             : {
     163          32 :         PlaceProperties placeProperties;
     164          32 :         placeProperties.name = m_name;
     165          32 :         placeProperties.onEnterActionFunctionName = m_onEnterActionName;
     166          32 :         placeProperties.onExitActionFunctionName = m_onExitActionName;
     167          32 :         placeProperties.initialNumberOfTokens = m_numberOfTokens;
     168          32 :         placeProperties.onEnterAction = m_onEnterAction;
     169          32 :         placeProperties.onExitAction = m_onExitAction;
     170          32 :         placeProperties.input = m_isInputPlace;
     171          32 :         return placeProperties;
     172           0 : }
     173             : 
     174           0 : void Place::setActionsExecutor(shared_ptr<IActionsExecutor> &actionsExecutor)
     175             : {
     176           0 :         unique_lock guard(m_mutex);
     177           0 :         m_actionsExecutor = actionsExecutor;
     178           0 : }
     179             : 
     180             : } // namespace ptne

Generated by: LCOV version 1.14