Advertisement
agmike

Lse.Init [Revised 24.07.2011]

Jul 24th, 2011
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.43 KB | None | 0 0
  1. // LOCOMOTIVE SCRIPT EXTENDER LIBRARY
  2. // Version: 0.0.7, date: 24.07.2011
  3. // Author: agentmike, e-mail: agentmike@rambler.ru
  4. // For license information see config.txt file.
  5. //
  6. // LSE is extensible framework for creating prototypically working locomotives.
  7. // LSE.Init is standalone part of LSE providing support of unified initialization
  8. // system for locomotives with custom scripts.
  9.  
  10. include "train.gs"
  11.  
  12.  
  13. //                                                                            +
  14. // Initialization messages (all major strings are prefixed with 'Lse.Init.'):
  15. //
  16. // #  |    source      |  destination   |     major      |     minor      |
  17. //    
  18. // 1       train            Broadcast      TrainPhysics        state
  19. // 2      vehicle           Broadcast        PreState       preState time
  20. // 3      vehicle           Broadcast       SetRunlevel       runlevel
  21. // 4      vehicle           Broadcast     RunlevelChanged     runlevel
  22. // 5      vehicle           Broadcast        Runlevel         runlevel
  23. // 6      vehicle           Broadcast      RunlevelChange   runlevel proc
  24. //
  25. // Note:
  26. // Every message is broadcasted from concrete vehicle. This is because
  27. // they could be used by other systems to monitor init/run activities.
  28. // I. e. Lse.Pneumatics rely on this messages to set initial pressures in
  29. // reservoirs and starting brake systems simulation.
  30. // If message is a directive command, only vehicle referenced as message
  31. // source will respond to it. Such messages should be sent using
  32. // Router.PostMessage by InitV or other custom initialization controller.
  33. //
  34. // Description:
  35. // 1. This message is directive command that has to be sent by an
  36. //    InitV/other init controller to properly handle the Train.EnablePhysics
  37. //    call and state.
  38. //    Message must be broadcasted with concrete train as source.
  39. // 2. This is optional message to handle preinitialization
  40. //    state of a vehicle. It allows to init state of vehicle with
  41. //    consideration of how it was used (or not used) before the initialization
  42. //    process. PreState has 4 defined values: Cold, Warm, Hot, HotRunning and
  43. //    number representing how long in minutes vehicle was in that state.
  44. //    Supporting of this feature is optional; default value is 'Warm 1140',
  45. //    meaning last crew left it in loco yard one day ago. Unsupported levels
  46. //    should be handled by falling to the closest preferring lower (i.e. Cold
  47. //    instead of Hot if Warm if not supported).
  48. //    Message must be broadcasted with concrete vehicle as source.
  49. // 3. This message used to control current runlevel of a vehicle.
  50. //    Message must be broadcasted with concrete vehicle as source.
  51. // 4. This message is used to notify world about finished runlevel transition.
  52. //    Not sent for Halt runlevel.
  53. //    Message is broadcasted by LseInit instance.
  54. // 5. This message is used to notify world current runlevel.
  55. //    Not sent for Halt runlevel.
  56. //    Message is broadcasted by LseInit instance in regular intervals
  57. //    (currently every minute).
  58. // 6. This message is used to notify world about beginning runlevel transition.
  59. //    Message is broadcasted by LseInit instance.
  60. //
  61. // Message parameters:
  62. // train: Train object containing some vehicle
  63. // vehicle: Vehicle object we want to monitor/init
  64. // Any: means src/dst is not relevant
  65. // Broadcast: means message is sent to every object in the world
  66. // state: Enabled or Disabled
  67. // preState: Cold or Warm or Hot or HotRunning
  68. // time: integer value, minutes since vehicle was left in this preState
  69. // runlevel: Halt or Wait or User or Auto
  70. // proc: Init or Term
  71. //
  72.  
  73. class LseInit
  74. {
  75.     Vehicle _vehicle;
  76.    
  77.     final Vehicle _getVehicle() { return _vehicle; }
  78.    
  79.     define public int RunlevelHalt = 0;
  80.     define public int RunlevelWait = 1;
  81.     define public int RunlevelAuto = 2;
  82.     define public int RunlevelUser = 3;
  83.    
  84.     int _runlevel       = RunlevelHalt;
  85.     int _runlevelTo     = RunlevelHalt;
  86.     int _runlevelNext   = RunlevelHalt;
  87.    
  88.     bool _runlevelChange = false;
  89.    
  90.     bool _runlevelWaitThread = false;
  91.    
  92.     bool _trainPhysicsState = true;
  93.    
  94.     final public bool GetPhysicsState() { return _trainPhysicsState; }
  95.    
  96.     define public int PreStateCold = 0;       // После ТР/КР
  97.     define public int PreStateWarm = 1;       // После отстоя в депо
  98.     define public int PreStateHot = 2;        // После смены бригад
  99.     define public int PreStateHotRunning = 3; // После смены бригад, локомотив запущен
  100.    
  101.     define public int PreStateIdleForHour = 60;
  102.     define public int PreStateIdleForDay = 24 * PreStateIdleForHour;
  103.     define public int PreStateIdleForMonth = 30 * PreStateIdleForDay;
  104.    
  105.     int _preState = PreStateWarm;
  106.     int _preStateIdleMinutes = PreStateIdleForDay;
  107.    
  108.     final public int GetPreState() { return _preState; }
  109.     final public int GetPreStateIdleMinutes() { return _preStateIdleMinutes; }
  110.    
  111.     final public int GetPreStateTime(int months, int days, int hours, int minutes)
  112.     {
  113.         return minutes
  114.              + hours  * PreStateIdleForHour
  115.              + days   * PreStateIdleForDay
  116.              + months * PreStateIdleForMonth;
  117.     }
  118.    
  119.     // Call this to change loco runlevel
  120.     final void RcSet(int runlevel)
  121.     {
  122.         if (   RunlevelHalt == runlevel
  123.             or RunlevelWait == runlevel
  124.             or RunlevelUser == runlevel
  125.             or RunlevelAuto == runlevel)
  126.         {
  127.             if (_trainPhysicsState or runlevel == RunlevelHalt)
  128.             {
  129.                 _runlevelTo = runlevel;
  130.             }
  131.         }
  132.        
  133.     }
  134.    
  135.     // Call this to terminate script in case of fatal error (i.e. derailment)
  136.     final public void RcHalt()
  137.     {
  138.         RcSet(RunlevelHalt);
  139.     }
  140.    
  141.     void RcUserInit(); // Override this methods with your custom loco logic
  142.     void RcUserTerm(); // Call RcFin() when initiation/termination is complete.
  143.     void RcAutoInit(); // CALL inherited() AT THE FIRST LINE OF YOUR CODE!!!
  144.     void RcAutoTerm(); //
  145.     void RcWaitInit(); //
  146.     void RcWaitTerm(); //
  147.    
  148.    
  149.     final thread void _rcInvoke(int rl, bool status)
  150.     {
  151.         _runlevelChange = true;
  152.         switch (rl)
  153.         {
  154.             case RunlevelWait:
  155.                 if (status)
  156.                     RcWaitInit();
  157.                 else
  158.                     RcWaitTerm();
  159.             break;
  160.            
  161.             case RunlevelUser:
  162.                 if (status)
  163.                     RcUserInit();
  164.                 else
  165.                     RcUserTerm();
  166.             break;
  167.            
  168.             case RunlevelAuto:
  169.                 if (status)
  170.                     RcAutoInit();
  171.                 else
  172.                     RcAutoTerm();
  173.             break;
  174.            
  175.             case RunlevelHalt:
  176.             default:
  177.             break;
  178.         }
  179.        
  180.         switch (_runlevelNext)
  181.         {
  182.             case RunlevelWait:
  183.                 _getVehicle().PostMessage(null, "Lse.Init.RunlevelChanged", "Wait", 0.0);
  184.             break;
  185.            
  186.             case RunlevelUser:
  187.                 _getVehicle().PostMessage(null, "Lse.Init.RunlevelChanged", "User", 0.0);
  188.             break;
  189.            
  190.             case RunlevelAuto:
  191.                 _getVehicle().PostMessage(null, "Lse.Init.RunlevelChanged", "Auto", 0.0);
  192.             break;
  193.            
  194.             case RunlevelHalt:
  195.             default:
  196.                 _getVehicle().PostMessage(null, "Lse.Init.RunlevelChanged", "Halt", 0.0);
  197.             break;
  198.         }
  199.        
  200.         _runlevel = _runlevelNext;
  201.         _runlevelChange = false;
  202.     }
  203.    
  204.     final void _rcDispatch()
  205.     {
  206.         if (_runlevelChange)
  207.             return;
  208.        
  209.         switch (_runlevel)
  210.         {
  211.             case RunlevelWait:
  212.                 switch (_runlevelTo)
  213.                 {
  214.                     case RunlevelHalt:
  215.                         _runlevelNext = RunlevelHalt;
  216.                         _rcInvoke(RunlevelWait, false);
  217.                     break;
  218.                    
  219.                     case RunlevelUser:
  220.                         _runlevelNext = RunlevelUser;
  221.                         _rcInvoke(RunlevelUser, true);
  222.                     break;
  223.                    
  224.                     case RunlevelAuto:
  225.                         _runlevelNext = RunlevelAuto;
  226.                         _rcInvoke(RunlevelAuto, true);
  227.                     break;
  228.                    
  229.                     case RunlevelWait:
  230.                     default:
  231.                     break;
  232.                 }
  233.             break;
  234.            
  235.             case RunlevelUser:
  236.                 switch (_runlevelTo)
  237.                 {
  238.                     case RunlevelHalt:
  239.                     case RunlevelWait:
  240.                     case RunlevelAuto:
  241.                         _runlevelNext = RunlevelWait;
  242.                         _rcInvoke(RunlevelUser, false);
  243.                     break;
  244.                    
  245.                     case RunlevelUser:
  246.                     default:
  247.                     break;
  248.                 }
  249.             break;
  250.            
  251.             case RunlevelAuto:
  252.                 switch (_runlevelTo)
  253.                 {
  254.                     case RunlevelHalt:
  255.                     case RunlevelWait:
  256.                     case RunlevelUser:
  257.                         _runlevelNext = RunlevelWait;
  258.                         _rcInvoke(RunlevelAuto, false);
  259.                     break;
  260.                    
  261.                     case RunlevelAuto:
  262.                     default:
  263.                     break;
  264.                 }
  265.             break;
  266.            
  267.             case RunlevelHalt:
  268.             default:
  269.                 switch (_runlevelTo)
  270.                 {
  271.                     case RunlevelWait:
  272.                     case RunlevelUser:
  273.                     case RunlevelAuto:
  274.                         _runlevelNext = RunlevelWait;
  275.                         _rcInvoke(RunlevelWait, true);
  276.                     break;
  277.                    
  278.                     case RunlevelHalt:
  279.                     default:
  280.                     break;
  281.                 }
  282.             break;
  283.         }
  284.     }
  285.    
  286.     final thread void _initWait()
  287.     {
  288.         float sleepTime = 1.0;
  289.        
  290.         float runlevelMessageTime = 60.0;
  291.         float runlevelMessageTimeLeft = 0.0;
  292.        
  293.         while (_runlevelWaitThread)
  294.         {
  295.             if (!_trainPhysicsState)
  296.                 RcSet(RunlevelWait);
  297.        
  298.             if (_runlevel != _runlevelTo)
  299.                 _rcDispatch();
  300.                
  301.             if (_runlevelChange)
  302.                 runlevelMessageTimeLeft = 0.0;
  303.             else
  304.             {
  305.                 if (runlevelMessageTimeLeft <= 0.0)
  306.                 {
  307.                     switch (_runlevel)
  308.                     {
  309.                         case RunlevelWait: _getVehicle().PostMessage(null, "Lse.Init.Runlevel", "Wait", 0.0); break;
  310.                         case RunlevelAuto: _getVehicle().PostMessage(null, "Lse.Init.Runlevel", "Auto", 0.0); break;
  311.                         case RunlevelUser: _getVehicle().PostMessage(null, "Lse.Init.Runlevel", "User", 0.0); break;
  312.                         case RunlevelHalt: break;
  313.                         default: break;
  314.                     }
  315.                     runlevelMessageTimeLeft = runlevelMessageTime;
  316.                 }
  317.                 else
  318.                     runlevelMessageTimeLeft = runlevelMessageTimeLeft - sleepTime;
  319.             }
  320.            
  321.             _getVehicle().Sleep(sleepTime);
  322.         }
  323.     }
  324.    
  325.     void RcUserInit()
  326.     {
  327.         _getVehicle().PostMessage(null, "Lse.Init.RunlevelChange", "User Init", 0.0);
  328.     }
  329.    
  330.     void RcUserTerm()
  331.     {
  332.         _getVehicle().PostMessage(null, "Lse.Init.RunlevelChange", "User Term", 0.0);
  333.     }
  334.    
  335.     void RcAutoInit()
  336.     {
  337.         _getVehicle().PostMessage(null, "Lse.Init.RunlevelChange", "Auto Init", 0.0);
  338.     }
  339.    
  340.     void RcAutoTerm()
  341.     {
  342.         _getVehicle().PostMessage(null, "Lse.Init.RunlevelChange", "Auto Term", 0.0);
  343.     }
  344.    
  345.     void RcWaitInit()
  346.     {
  347.         _getVehicle().PostMessage(null, "Lse.Init.RunlevelChange", "Wait Init", 0.0);
  348.         if (!_runlevelWaitThread)
  349.         {
  350.             _runlevelWaitThread = true;
  351.             _initWait();
  352.         }
  353.        
  354.         _getVehicle().Sleep(0.1);
  355.     }
  356.    
  357.     void RcWaitTerm()
  358.     {
  359.         _getVehicle().PostMessage(null, "Lse.Init.RunlevelChange", "Wait Term", 0.0);
  360.         _runlevelWaitThread = false;
  361.        
  362.         _getVehicle().Sleep(1.0);
  363.     }
  364.    
  365.    
  366.     final void _onLseTrainPhysics(Message msg)
  367.     {
  368.         Train msgTrain = cast<Train> msg.src;
  369.         if (msgTrain and msgTrain == _getVehicle().GetMyTrain())
  370.         {
  371.             string stateStr = Str.CloneString(msg.minor);
  372.             Str.ToLower(stateStr);
  373.            
  374.             if (stateStr == "disabled" or stateStr == "false" or stateStr == "0")
  375.                 _trainPhysicsState = false;
  376.             else
  377.                 _trainPhysicsState = true;
  378.         }
  379.     }
  380.    
  381.     final void _onLsePreState(Message msg)
  382.     {
  383.         if (msg.src != me)
  384.             return;
  385.        
  386.         string[] msgParams = Str.Tokens(msg.minor, "");
  387.         if (msgParams.size() != 2)
  388.             return;
  389.            
  390.         string preState = msgParams[0];
  391.         Str.ToLower(preState);
  392.         string preStateIdleTime = msgParams[1];
  393.        
  394.         if (preState == "cold")
  395.             _preState = PreStateCold;
  396.         else if (preState == "warm")
  397.             _preState = PreStateWarm;
  398.         else if (preState == "hot")
  399.             _preState = PreStateHot;
  400.         else if (preState == "hotrunning")
  401.             _preState = PreStateHotRunning;
  402.        
  403.         int preStateIdleTimeInt = Str.ToInt(preStateIdleTime);
  404.         if (preStateIdleTimeInt > 0)
  405.             _preStateIdleMinutes = preStateIdleTimeInt;
  406.     }
  407.    
  408.     final void _onLseSetRunlevel(Message msg)
  409.     {
  410.         if (msg.src != me)
  411.             return;
  412.            
  413.         string runlevel = Str.CloneString(msg.minor);
  414.         Str.ToLower(runlevel);
  415.        
  416.         if (runlevel == "halt")
  417.             RcSet(RunlevelHalt);
  418.         else if (runlevel == "wait")
  419.             RcSet(RunlevelWait);
  420.         else if (runlevel == "user")
  421.             RcSet(RunlevelUser);
  422.         else if (runlevel == "auto")
  423.             RcSet(RunlevelAuto);
  424.     }
  425.    
  426.     public void LseInit()
  427.     {
  428.         _vehicle = cast<Vehicle> (object) me;
  429.         if (_vehicle == null)
  430.             Interface.Exception("LseInit should be inherited by Vehicle or descendants! (line 430)");
  431.        
  432.         _getVehicle().AddHandler(_getVehicle(), "Lse.Init.TrainPhysics", "", "_onLseTrainPhysics");
  433.         _getVehicle().AddHandler(_getVehicle(), "Lse.Init.PreState",     "", "_onLsePreState"    );
  434.         _getVehicle().AddHandler(_getVehicle(), "Lse.Init.SetRunlevel",  "", "_onLseSetRunlevel" );
  435.        
  436.         // _getVehicle().AddHandler(_getVehicle(), "Lse.Init.TrainPhysics.Direct", "", "_onLseTrainPhysics");
  437.         // _getVehicle().AddHandler(_getVehicle(), "Lse.Init.PreState.Direct",     "", "_onLsePreState"    );
  438.         // _getVehicle().AddHandler(_getVehicle(), "Lse.Init.SetRunlevel.Direct",  "", "_onLseSetRunlevel" );
  439.        
  440.         RcSet(RunlevelWait);
  441.         _rcDispatch();
  442.     }
  443. };
  444.  
  445. // Dummy class for script and class tags in config.txt
  446. class LseInitLibrary isclass Library
  447. {
  448. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement