├── Stage └── Stage │ ├── StageCore │ ├── Strings │ │ ├── Alias │ │ │ ├── Ch.TcDUT │ │ │ └── Str.TcDUT │ │ ├── Strf │ │ │ └── Strf.TcPOU │ │ └── Strb │ │ │ └── I_Strb.TcIO │ ├── Entity │ │ ├── Core │ │ │ ├── I_Entity.TcIO │ │ │ ├── I_RawComponent.TcIO │ │ │ ├── I_Component.TcIO │ │ │ ├── GetOwnerFromRaw.TcPOU │ │ │ ├── Scope │ │ │ │ ├── EntityEnd.TcPOU │ │ │ │ └── EntityExtend.TcPOU │ │ │ ├── GetNextEntity.TcPOU │ │ │ ├── GetPrevEntity.TcPOU │ │ │ └── Component.TcPOU │ │ └── Sys │ │ │ ├── _EntityState.TcDUT │ │ │ ├── _Ec.TcGVL │ │ │ ├── _Helpers │ │ │ ├── _EntityExtend.TcPOU │ │ │ ├── _EntityEnd.TcPOU │ │ │ ├── _EntityStart.TcPOU │ │ │ └── _RegisterComponent.TcPOU │ │ │ └── _Itf │ │ │ ├── I_ComponentNode.TcIO │ │ │ └── I_EntityNode.TcIO │ ├── Result │ │ ├── Result.TcDUT │ │ ├── Error │ │ │ ├── GenericResult.TcGVL │ │ │ └── Err.TcGVL │ │ ├── IsErr.TcPOU │ │ ├── IsNone.TcPOU │ │ ├── IsOk.TcPOU │ │ ├── IsEnd.TcPOU │ │ ├── IsFail.TcPOU │ │ ├── IsSome.TcPOU │ │ └── ResultToStr.TcPOU │ ├── Broadcast │ │ ├── Sys │ │ │ ├── Structs │ │ │ │ ├── _BroadcastStruct.TcDUT │ │ │ │ └── _BroadcastUnion.TcDUT │ │ │ ├── _Broadcast.TcGVL │ │ │ └── Helpers │ │ │ │ ├── _Emit.TcPOU │ │ │ │ ├── _RegSignal.TcPOU │ │ │ │ ├── _Unpair.TcPOU │ │ │ │ ├── _BroadcastGetBestFit.TcPOU │ │ │ │ ├── _BroadcastDefragment.TcPOU │ │ │ │ └── _Pair.TcPOU │ │ ├── Arg │ │ │ ├── I_Arg.TcIO │ │ │ ├── IArgToIComp.TcPOU │ │ │ ├── ICompToIArg.TcPOU │ │ │ └── Args │ │ │ │ ├── BOOL │ │ │ │ ├── IArgToIBoolArg.TcPOU │ │ │ │ ├── I_BoolArg.TcIO │ │ │ │ └── BoolArg.TcPOU │ │ │ │ ├── REAL │ │ │ │ ├── IArgToIRealtArg.TcPOU │ │ │ │ ├── I_RealArg.TcIO │ │ │ │ └── RealArg.TcPOU │ │ │ │ └── DWORD │ │ │ │ ├── IArgToIDwordArg.TcPOU │ │ │ │ ├── I_DwordArg.TcIO │ │ │ │ └── DwordArg.TcPOU │ │ ├── Receiver │ │ │ ├── I_ReceiverNode.TcIO │ │ │ ├── I_Receiver.TcIO │ │ │ ├── ICompToIRec.TcPOU │ │ │ └── Receiver.TcPOU │ │ ├── Callable │ │ │ └── I_Callable.TcIO │ │ ├── Signal │ │ │ ├── ICompToISignal.TcPOU │ │ │ ├── I_Signal.TcIO │ │ │ ├── I_SignalNode.TcIO │ │ │ └── I_SignalEmit.TcIO │ │ └── Helpers │ │ │ ├── GetSignal.TcPOU │ │ │ └── GetReceiver.TcPOU │ ├── Dbg │ │ ├── DebugMode.TcDUT │ │ ├── _DebugInfo.TcDUT │ │ ├── I_Debug.TcIO │ │ ├── _Debug.TcGVL │ │ ├── DebugInfo.TcPOU │ │ └── NewDebug.TcPOU │ ├── Runtime │ │ ├── _Runtime.TcGVL │ │ ├── Init │ │ │ ├── I_Init.TcIO │ │ │ ├── I_InitNode.TcIO │ │ │ └── Init.TcPOU │ │ ├── Execute │ │ │ ├── I_Execute.TcIO │ │ │ ├── I_ExecuteNode.TcIO │ │ │ └── Execute.TcPOU │ │ └── Runtime.TcPOU │ ├── Jobs │ │ ├── JobState.TcDUT │ │ ├── Job │ │ │ ├── I_Job.TcIO │ │ │ └── I_JobInternal.TcIO │ │ └── Worker │ │ │ ├── BlockingWorker.TcPOU │ │ │ ├── LoopWorker.TcPOU │ │ │ └── Base │ │ │ ├── I_Worker.TcIO │ │ │ └── Worker.TcPOU │ ├── Tags │ │ ├── Tag.TcPOU │ │ ├── Casts │ │ │ ├── IArgToITag.TcPOU │ │ │ └── ICompToITag.TcPOU │ │ ├── Helpers │ │ │ ├── HasTagOption.TcPOU │ │ │ ├── HasTag.TcPOU │ │ │ ├── GetTagOption.TcPOU │ │ │ ├── GetTag.TcPOU │ │ │ └── MatchPath.TcPOU │ │ ├── I_Tag.TcIO │ │ ├── I_TagCmp.TcIO │ │ └── TagBase.TcPOU │ ├── _ │ │ └── Param.TcGVL │ └── State │ │ ├── State │ │ ├── ICompToIState.TcPOU │ │ ├── I_State.TcIO │ │ └── I_StateInternal.TcIO │ │ ├── Manager │ │ ├── ICompToIStateMgr.TcPOU │ │ ├── I_StateManager.TcIO │ │ └── StateManager.TcPOU │ │ ├── Helpers │ │ ├── GetStateManager.TcPOU │ │ └── GetState.TcPOU │ │ ├── _Machine │ │ └── _StateMachine.TcPOU │ │ └── _Buffer │ │ └── _StateBuffer.TcPOU │ ├── StageUtils │ ├── Color │ │ ├── Argb.TcDUT │ │ ├── BuildArgb.TcPOU │ │ ├── Itf │ │ │ └── I_Argbb.TcIO │ │ └── Argbb.TcPOU │ ├── Time │ │ ├── GetTaskCycleTime.TcPOU │ │ └── GetUnixTime.TcPOU │ └── Math │ │ └── Math.TcPOU │ └── Stage.tsproj ├── LICENSE └── README.md /Stage/Stage/StageCore/Strings/Alias/Ch.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Strings/Alias/Str.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /Stage/Stage/StageUtils/Color/Argb.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/I_Entity.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/Result.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | = 1 - Ok/Success 6 | // | Result = 0 - None 7 | // | Result <=- 1 - Error 8 | TYPE Result : INT; END_TYPE 9 | ]]> 10 | 11 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Structs/_BroadcastStruct.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Structs/_BroadcastUnion.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Dbg/DebugMode.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Dbg/_DebugInfo.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/Error/GenericResult.TcGVL: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Dbg/I_Debug.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_EntityState.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/I_Arg.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Dbg/_Debug.TcGVL: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/I_RawComponent.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/_Runtime.TcGVL: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Jobs/JobState.TcDUT: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Receiver/I_ReceiverNode.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/_Broadcast.TcGVL: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/Init/I_Init.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/Execute/I_Execute.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/IsErr.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Stage/Stage/StageUtils/Time/GetTaskCycleTime.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/IsNone.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/IsOk.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 0; 16 | nOut := nIn;]]> 17 | 18 | 19 | -------------------------------------------------------------------------------- /Stage/Stage/StageUtils/Color/BuildArgb.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/IsEnd.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Callable/I_Callable.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/IsFail.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/IsSome.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 0; 15 | nOut := nIn;]]> 16 | 17 | 18 | -------------------------------------------------------------------------------- /Stage/Stage/StageUtils/Time/GetUnixTime.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Tag.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Receiver/I_Receiver.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Helpers/_Emit.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Dbg/DebugInfo.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/_/Param.TcGVL: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Casts/IArgToITag.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Casts/ICompToITag.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/IArgToIComp.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/ICompToIArg.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Jobs/Job/I_Job.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 18 | 19 | 20 | Idle. 23 | Returns Err.Itf0 on Worker = 0. 24 | *) 25 | METHOD Start : Result 26 | VAR_INPUT 27 | END_VAR 28 | ]]> 29 | 30 | 31 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Receiver/ICompToIRec.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Helpers/_RegSignal.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/BOOL/IArgToIBoolArg.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Signal/ICompToISignal.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/State/ICompToIState.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/REAL/IArgToIRealtArg.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/DWORD/IArgToIDwordArg.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/Manager/ICompToIStateMgr.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/State/I_State.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Helpers/HasTagOption.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/I_Component.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Helpers/HasTag.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/Error/Err.TcGVL: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Krystian-L-Lis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/Init/I_InitNode.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/Execute/I_ExecuteNode.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 12 | 13 | 14 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/Helpers/GetStateManager.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Dbg/NewDebug.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_Ec.TcGVL: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 28 | 29 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Helpers/GetTagOption.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 23 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Helpers/GetTag.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/I_Tag.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/Helpers/GetState.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Helpers/GetSignal.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Helpers/GetReceiver.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/GetOwnerFromRaw.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 22 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/Runtime.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 0 DO 15 | iInit.Init(iNext => iInit); 16 | END_WHILE 17 | 18 | IF _Ec.nConstructedScopes <> 0 THEN 19 | NewDebug(0, Param.INIT_INTERNAL_DEBUG_MODE, 'Close all Entity scopes!'); 20 | END_IF 21 | 22 | IF _Debug.nPanicNumber > 0 THEN 23 | _Runtime.iFirstCyclic := 0; 24 | Tc2_System.ADSLOGSTR(Tc2_System.ADSLOG_MSGTYPE_ERROR, Tc2_Standard.CONCAT('Runtime disabled! Debug panics: ', UDINT_TO_STRING(_Debug.nPanicNumber)), ''); 25 | END_IF 26 | 27 | IF _Debug.nNotifyNumber > 0 THEN 28 | _Runtime.iFirstCyclic := 0; 29 | Tc2_System.ADSLOGSTR(Tc2_System.ADSLOG_MSGTYPE_WARN, Tc2_Standard.CONCAT('Debug notifies: ', UDINT_TO_STRING(_Debug.nPanicNumber)), ''); 30 | END_IF 31 | 32 | _Runtime.bInit := FALSE; 33 | END_IF 34 | 35 | WHILE iExecute <> 0 DO 36 | iExecute.Exe(iNext => iExecute); 37 | END_WHILE]]> 38 | 39 | 40 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/BOOL/I_BoolArg.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/REAL/I_RealArg.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/DWORD/I_DwordArg.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_Helpers/_EntityExtend.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | _EntityState.Completed THEN 26 | // If not completed, return with incorrect argument error 27 | _EntityExtend := Err.IncArg; 28 | RETURN; 29 | END_IF 30 | 31 | // Mark the entity as 'Registered' for extension 32 | iEntity._State := _EntityState.Registered; 33 | 34 | // Set the entity as the current one under construction 35 | _Ec.iUnderConstruction := iEntity; 36 | 37 | // Increment the scope construction counter 38 | _Ec.nConstructedScopes := _Ec.nConstructedScopes + 1; 39 | _EntityExtend := Ok; 40 | ]]> 41 | 42 | 43 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Result/ResultToStr.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/Scope/EntityEnd.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 26 | 27 | _nResult) THEN 28 | NewDebug(THIS^, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT('EndEntity() failed with code: ', ResultToStr(_nResult))); 29 | END_IF]]> 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/Scope/EntityExtend.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 28 | 29 | _nResult) THEN 30 | NewDebug(THIS^, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT('ExtendEntity(I_EntityNode) failed with code: ', ResultToStr(_nResult))); 31 | END_IF]]> 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_Itf/I_ComponentNode.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Jobs/Worker/BlockingWorker.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Jobs/Worker/LoopWorker.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Signal/I_Signal.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/GetNextEntity.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 21 | 0 THEN 43 | iEntity := iEntity._Next; 44 | GetNextEntity := Ok; 45 | 46 | // If there is no next entity, end of the list is reached 47 | ELSE 48 | iEntity := 0; 49 | GetNextEntity := Err.End; 50 | END_IF 51 | ]]> 52 | 53 | 54 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/GetPrevEntity.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 21 | 0 THEN 43 | iEntity := iEntity._Prev; 44 | GetPrevEntity := Ok; 45 | 46 | // If there is no previous entity, beginning of the list is reached 47 | ELSE 48 | iEntity := 0; 49 | GetPrevEntity := Err.End; 50 | END_IF 51 | ]]> 52 | 53 | 54 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Jobs/Worker/Base/I_Worker.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | THIS^ 16 | *) 17 | METHOD Defer : Result 18 | VAR_INPUT 19 | iJob : I_Job; 20 | END_VAR]]> 21 | 22 | 23 | THIS^ 29 | - Err.IncArg - iJob.State = TaskState.Idle 30 | *) 31 | METHOD Dequeue : Result 32 | VAR_INPUT 33 | iJob: I_Job; 34 | END_VAR 35 | ]]> 36 | 37 | 38 | THIS^ 44 | - Err.IncArg - iJob.State <> TaskState.Idle 45 | *) 46 | METHOD Enqueue : Result 47 | VAR_INPUT 48 | iJob: I_Job; 49 | END_VAR 50 | ]]> 51 | 52 | 53 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_Helpers/_EntityEnd.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 0 THEN 31 | // Traverse backwards to find an entity that is registered but not yet completed 32 | iEntity := _Ec.iUnderConstruction; 33 | WHILE IsOk(GetPrevEntity(iEntity)) DO 34 | // If a registered entity is found, set the return value to OK and exit 35 | IF _Ec.iUnderConstruction._State = _EntityState.Registered THEN 36 | _EntityEnd := Ok; 37 | RETURN; 38 | END_IF 39 | END_WHILE 40 | 41 | // If all remaining entities are completed, reset under-construction pointer and return OK 42 | _Ec.iUnderConstruction := 0; 43 | _EntityEnd := Ok; 44 | ELSE 45 | // If no scopes left, reset under-construction pointer and return OK 46 | _Ec.iUnderConstruction := 0; 47 | _EntityEnd := Ok; 48 | END_IF 49 | ]]> 50 | 51 | 52 | -------------------------------------------------------------------------------- /Stage/Stage/Stage.tsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Example 8 | 9 | 10 | Test 11 | 12 | 13 | VISU_TASK 14 | 15 | 16 | 17 | 18 | 19 | 20 | StageUtils Instance 21 | {08500001-0000-0000-F000-000000000064} 22 | 23 | 24 | 25 | 26 | StageCore Instance 27 | {08500001-0000-0000-F000-000000000064} 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_Helpers/_EntityStart.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | _EntityState.Unregistered THEN 25 | // If already registered or in an unexpected state, return error 26 | _EntityStart := Err.ItfEq; 27 | RETURN; 28 | END_IF 29 | 30 | // If this is the first entity in the scope, initialize the list 31 | IF _Ec.iLast = 0 THEN 32 | _Ec.iFirst := iEntity; // Set as first entity 33 | _Ec.iLast := iEntity; // Set as last entity 34 | ELSE 35 | // Link the new entity to the end of the current list | iOther < iLast > 0 | 0 < iEntity > 0 36 | _Ec.iLast._Next := iEntity; // Set previous last's next to new entity | iOther < iLast > iEntity | 0 < iEntity > 0 37 | iEntity._Prev := _Ec.iLast; // Set new entity's previous to old last | iOther < iLast > iEntity | iLast < iEntity > 0 38 | _Ec.iLast := iEntity; // Update the last entity pointer | iLast = iEntity 39 | END_IF 40 | 41 | // Register the entity and prepare for construction 42 | iEntity._State := _EntityState.Registered; 43 | _Ec.iUnderConstruction := iEntity; 44 | 45 | // Increment the scope construction count 46 | _Ec.nConstructedScopes := _Ec.nConstructedScopes + 1; 47 | _EntityStart := Ok;]]> 48 | 49 | 50 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Signal/I_SignalNode.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Helpers/_Unpair.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 0 AND_THEN _nNewStart < _nFirstId THEN 60 | _nFirstId := _Broadcast.iSignal[i]._Start; 61 | _Broadcast.iFirst := _Broadcast.iSignal[i]; 62 | END_IF 63 | END_FOR 64 | END_IF 65 | 66 | ELSE 67 | // 6) Otherwise, swap-remove from the last receiver slot 68 | _Broadcast.entry[_nPos] := _Broadcast.entry[_nEnd]; 69 | iSignal._End := _nEnd - 1; 70 | END_IF 71 | 72 | // 7) Return success code 73 | _Unpair := Ok; 74 | ]]> 75 | 76 | 77 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Helpers/_BroadcastGetBestFit.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 1 THEN 38 | _nStartIndex := 1; 39 | ELSE 40 | _nStartIndex := _Broadcast.iFirst._End + 1; 41 | END_IF 42 | 43 | // 4) Loop from _nStartIndex to the max capacity 44 | FOR i := _nStartIndex TO Param.RECEIVER_CAP DO 45 | 46 | CASE _Broadcast.entry[i].nType OF 47 | 48 | 0: // FREE slot 49 | _nChunkSize := _nChunkSize + 1; 50 | 51 | // If we've accumulated enough contiguous slots, we're done 52 | IF _nChunkSize = nRequiredSize THEN 53 | nStart := i - _nChunkSize + 1; 54 | nEnd := i; 55 | _BroadcastGetBestFit := Ok; 56 | RETURN; 57 | END_IF 58 | 59 | 1: // OCCUPIED slot 60 | // Reset the contiguous free-space counter 61 | _nChunkSize := 0; 62 | 63 | // Jump 'i' to the last index used by this signal 64 | i := _Broadcast.entry[i].variant.iSignal._End; 65 | // The next iteration of FOR will increment 'i', continuing from (i+1) 66 | 67 | ELSE // Invalid slot type => internal error 68 | _BroadcastGetBestFit := Err.IncArg; 69 | RETURN; 70 | 71 | END_CASE 72 | 73 | END_FOR 74 | 75 | // 5) If we get here, no chunk of size nRequiredSize was found. 76 | _BroadcastGetBestFit := None;]]> 77 | 78 | 79 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_Helpers/_RegisterComponent.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | _EntityState.Registered THEN 25 | // If not registered, the entity context is invalid for component registration 26 | _RegisterComponent := Err.NotFound; 27 | RETURN; 28 | END_IF 29 | 30 | // Ensure the component is not already assigned to another entity 31 | IF iComponent._Entity <> 0 THEN 32 | // Component is already linked to an entity, return incorrect argument error 33 | _RegisterComponent := Err.IncArg; 34 | RETURN; 35 | END_IF 36 | 37 | // Add entity as parent 38 | iComponent._Entity := _Ec.iUnderConstruction; 39 | iComponent._Entity._Size := iComponent._Entity._Size + 1; 40 | 41 | // If the entity already has components, append this one to the end of the component list 42 | IF _Ec.iUnderConstruction._LastComp <> 0 THEN 43 | _Ec.iUnderConstruction._LastComp._Next := iComponent; // Link previous last to new component 44 | iComponent._Prev := _Ec.iUnderConstruction._LastComp; // Link new component back to previous last 45 | _Ec.iUnderConstruction._LastComp := iComponent; // Update the last component pointer 46 | _RegisterComponent := Ok; 47 | 48 | // If this is the first component being added, initialize the list 49 | ELSE 50 | _Ec.iUnderConstruction._FirstComp := iComponent; // Set as first component 51 | _Ec.iUnderConstruction._LastComp := iComponent; // Also set as last component 52 | _RegisterComponent := Ok; 53 | END_IF 54 | ]]> 55 | 56 | 57 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/Helpers/MatchPath.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | pttSeg)) DO 37 | bMatch := FALSE; 38 | // If the current segment is a wildcard, then peek to the next segment 39 | IF pttSeg = '*' THEN 40 | IF IsOk(pttPath.Peek(sSeg => pttPeek)) THEN 41 | IF pttPeek = '*' THEN 42 | CONTINUE; // Skip redundant wildcard if *.*. 43 | END_IF 44 | ELSE 45 | MatchPath := Ok; 46 | RETURN; // No more segments in the pattern, so it's a match as everything so far matched(.*) 47 | END_IF 48 | 49 | // If current segment is not a wildcard reset the peek. 50 | ELSIF pttSeg <> '*' THEN 51 | pttPeek := ''; 52 | END_IF 53 | 54 | // Get the next segment of the address path 55 | WHILE IsOk(addPath.Next(sSeg => addSeg)) DO 56 | IF pttPeek <> '' THEN 57 | IF pttPeek = addSeg THEN 58 | bMatch := TRUE; 59 | pttPath.Next(); // Consume get next pattern segment 60 | EXIT; 61 | ELSE 62 | CONTINUE; // Get next address 63 | END_IF 64 | ELSIF pttSeg = addSeg THEN 65 | bMatch := TRUE; 66 | EXIT; // Consume get next pattern segment 67 | ELSE 68 | MatchPath := Err.NoMatch; 69 | RETURN; // No match - return 70 | END_IF 71 | END_WHILE 72 | 73 | IF NOT bMatch THEN 74 | MatchPath := Err.NoMatch; 75 | RETURN; 76 | END_IF 77 | 78 | END_WHILE 79 | 80 | IF IsOk(addPath.Peek()) THEN 81 | MatchPath := Err.NoMatch; 82 | RETURN; 83 | END_IF 84 | 85 | MatchPath := Ok; 86 | 87 | 88 | ]]> 89 | 90 | 91 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/_Machine/_StateMachine.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 29 | 30 | 0 AND_THEN NOT _iCurrentState._CanDeactivate() THEN 46 | Change := None; 47 | RETURN; 48 | END_IF 49 | 50 | IF _iCurrentState <> 0 THEN 51 | _iCurrentState._OnExit(); 52 | END_IF 53 | 54 | iNewState._OnEntry(); 55 | iOldState := _iCurrentState; 56 | _iCurrentState := iNewState; 57 | Change := Ok;]]> 58 | 59 | 60 | 61 | 65 | 66 | 0 THEN 67 | _iCurrentState._OnExecute(); 68 | END_IF]]> 69 | 70 | 71 | 72 | 76 | 77 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /Stage/Stage/StageUtils/Math/Math.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 23 | 24 | 27 | 28 | 29 | 30 | 46 | 47 | 0 THEN 48 | LinearScale := rMinY + ((rX - rMinX)/_rDnmtr) * (rMaxY - rMinY); 49 | END_IF]]> 50 | 51 | 52 | 53 | 64 | 65 | 66 | 67 | 68 | 69 | 80 | 81 | Random); 82 | _nSeed := _nSeed + 1;]]> 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Helpers/_BroadcastDefragment.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 0 THEN 30 | _iSwappedSignal := _Broadcast.iSignal[_Broadcast.nSignalLen]; 31 | _Broadcast.iSignal[iLastSignal._Id] := _iSwappedSignal; 32 | _Broadcast.iSignal[_Broadcast.nSignalLen] := iLastSignal; 33 | END_IF 34 | 35 | // 3) Copy all chunks to the temporary table 36 | FOR i := 1 TO _Broadcast.nSignalLen DO 37 | IF _Broadcast.iSignal[i]._Start <> 0 THEN 38 | Tc2_SYSTEM.MEMCPY( 39 | ADR(_temp[_nNextCopyId]), 40 | ADR(_Broadcast.entry[_Broadcast.iSignal[i]._Start]), 41 | SIZEOF(_BroadcastStruct) * _Broadcast.iSignal[i]._Size 42 | ); 43 | _Broadcast.iSignal[i]._Start := _nNextCopyId; 44 | _nNextCopyId := _Broadcast.iSignal[i]._Size + _nNextCopyId; 45 | _Broadcast.iSignal[i]._End := _nNextCopyId - 1; 46 | END_IF 47 | END_FOR 48 | 49 | // 3) Move back the swapped entities, to preserve the Ids. 50 | IF iLastSignal <> 0 THEN 51 | _Broadcast.iSignal[_iSwappedSignal._Id] := _iSwappedSignal; 52 | _Broadcast.iSignal[iLastSignal._Id] := iLastSignal; 53 | END_IF 54 | 55 | // 4) Copy temporary table onto the _Ec.comp table 56 | Tc2_System.MEMCPY( 57 | ADR(_Broadcast.entry), 58 | ADR(_temp), 59 | SIZEOF(_BroadcastStruct) * _Broadcast.nRecLen 60 | ); 61 | 62 | // 5) Clear the remainging area 63 | Tc2_System.MEMSET( 64 | ADR(_Broadcast.entry[_Broadcast.nRecLen + 1]), 65 | 0, 66 | SIZEOF(_BroadcastStruct) * (Param.RECEIVER_CAP - _Broadcast.nRecLen) 67 | ); 68 | 69 | // 6) First entry in _Ec.comp should always be iFirst 70 | CASE _Broadcast.entry[1].nType OF 71 | 1: 72 | _BroadcastDefragment := Ok; 73 | _Broadcast.iFirst := _Broadcast.entry[1].variant.iSignal; 74 | ELSE 75 | _BroadcastDefragment := Err.Udf; 76 | END_CASE 77 | 78 | ]]> 79 | 80 | 81 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Receiver/Receiver.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | 20 | 21 | 22 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 60 | 61 | 67 | 68 | 69 | 70 | 74 | 75 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Jobs/Job/I_JobInternal.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 25 | 26 | 27 | 31 | 32 | 33 | 37 | 38 | 39 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 58 | 59 | 60 | 61 | 62 | 63 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/State/I_StateInternal.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 49 | 50 | 51 | 55 | 56 | 57 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/_Buffer/_StateBuffer.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 27 | 28 | 29 | 30 | 31 | 32 | 43 | 44 | 61 | 62 | 63 | 64 | 75 | 76 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/Manager/I_StateManager.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 40 | 41 | 42 | 43 | 44 | 45 | 50 | 51 | 52 | 53 | 54 | 55 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Signal/I_SignalEmit.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 22 | 23 | 24 | 37 | 38 | 39 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 64 | 65 | 66 | 70 | 71 | 72 | 73 | 74 | 75 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Stage/Stage/StageUtils/Color/Itf/I_Argbb.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 42 | 43 | 44 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/BOOL/BoolArg.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 73 | 74 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 91 | 92 | 94 | 95 | 96 | 97 | 108 | 109 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/REAL/RealArg.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 73 | 74 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 91 | 92 | 94 | 95 | 96 | 97 | 108 | 109 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Arg/Args/DWORD/DwordArg.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 33 | 34 | 35 | 36 | 37 | 38 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 60 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 73 | 74 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 91 | 92 | 94 | 95 | 96 | 97 | 108 | 109 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Strings/Strf/Strf.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 21 | 22 | Fmt); 23 | ]]> 24 | 25 | 26 | 27 | 43 | 44 | 0 THEN 48 | FOR i := 1 TO _nleftMiss DO 49 | sValue := Tc2_Standard.CONCAT(sFillChar, sValue); 50 | END_FOR 51 | END_IF 52 | 53 | IF _nRightMiss > 0 THEN 54 | FOR i := 1 TO _nRightMiss DO 55 | sValue := Tc2_Standard.CONCAT(sFillChar, sValue); 56 | END_FOR 57 | END_IF 58 | 59 | Padding := sValue; 60 | ]]> 61 | 62 | 63 | 64 | 82 | 83 | _nMaxUnit THEN 101 | RETURN; 102 | END_IF 103 | 104 | _stTime := Tc2_Utilities.TIME_TO_OTSTRUCT(tValue); 105 | _stTime.wDay := _stTime.wWeek * 7 + _stTime.wDay; 106 | 107 | _nValues[1] := WORD_TO_UINT(_stTime.wMilliseconds); 108 | _nValues[2] := WORD_TO_UINT(_stTime.wSecond); 109 | _nValues[3] := WORD_TO_UINT(_stTime.wMinute); 110 | _nValues[4] := WORD_TO_UINT(_stTime.wHour); 111 | _nValues[5] := WORD_TO_UINT(_stTime.wDay); 112 | 113 | _sValues[1].Set(Strf.Padding(UINT_TO_STRING(_nValues[1]), 3, 0, '0')).Append('ms'); 114 | _sValues[2].Set(Strf.Padding(UINT_TO_STRING(_nValues[2]), 2, 0, '0')).Append('s'); 115 | _sValues[3].Set(Strf.Padding(UINT_TO_STRING(_nValues[3]), 2, 0, '0')).Append('m'); 116 | _sValues[4].Set(Strf.Padding(UINT_TO_STRING(_nValues[4]), 2, 0, '0')).Append('h'); 117 | _sValues[5].Set(Strf.Padding(UINT_TO_STRING(_nValues[5]), 3, 0, '0')).Append('d'); 118 | 119 | IF _nMaxUnit < 5 THEN 120 | FOR _i := 5 TO _nMaxUnit + 1 BY -1 DO 121 | IF _nValues[_i] <> 0 THEN 122 | _strb.Append(_sValues[_i].Read()).Append(' '); 123 | END_IF 124 | END_FOR 125 | END_IF 126 | 127 | FOR _i := _nMaxUnit TO _nMinUnit BY -1 DO 128 | _strb.Append(_sValues[_i].Read()).Append(' '); 129 | END_FOR 130 | 131 | SimpleTime := _strb.Read(); 132 | ]]> 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/Init/Init.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | _Runtime.iLastInit THEN 32 | NewDebug(THIS^, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT(__POUNAME(), ': Is not the last node!')); 33 | RETURN; 34 | END_IF 35 | 36 | IF IsSome(iInit.state) THEN 37 | NewDebug(iInit, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT(__POUNAME(), ': Has already been added!')); 38 | RETURN; 39 | END_IF 40 | 41 | _Runtime.iLastInit := iInit; 42 | _iNext := iInit; 43 | 44 | ]]> 45 | 46 | 47 | 48 | 61 | 62 | 0 THEN 75 | IF IsErr(_Runtime.iLastInit.Attach(THIS^), nOut => _nState) THEN 76 | NewDebug(THIS^, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT(__POUNAME(), ': Error inside!')); 77 | END_IF 78 | ELSE 79 | _Runtime.iFirstInit := THIS^; 80 | _Runtime.iLastInit := THIS^; 81 | _nState := Ok; 82 | END_IF 83 | ]]> 84 | 85 | 86 | 87 | 92 | 93 | 95 | 96 | 97 | 98 | 99 | 100 | 103 | 104 | 105 | 106 | 107 | 108 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 122 | 123 | 124 | 125 | 126 | 127 | 130 | 131 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Runtime/Execute/Execute.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | _Runtime.iLastCyclic THEN 32 | NewDebug(THIS^, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT(__POUNAME(), ': Is not the last node!')); 33 | RETURN; 34 | END_IF 35 | 36 | IF IsSome(iExecute.state) THEN 37 | NewDebug(iExecute, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT(__POUNAME(), ': Has already been added!')); 38 | RETURN; 39 | END_IF 40 | 41 | _Runtime.iLastCyclic := iExecute; 42 | _iNext := iExecute; 43 | 44 | ]]> 45 | 46 | 47 | 48 | 54 | 55 | 57 | 58 | 59 | 60 | 73 | 74 | 0 THEN 87 | IF IsErr(_Runtime.iLastCyclic.Attach(THIS^), nOut => _nState) THEN 88 | NewDebug(THIS^, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT(__POUNAME(), ': Error Inside!')); 89 | END_IF 90 | ELSE 91 | _Runtime.iFirstCyclic := THIS^; 92 | _Runtime.iLastCyclic := THIS^; 93 | _nState := Ok; 94 | END_IF 95 | ]]> 96 | 97 | 98 | 99 | 100 | 101 | 104 | 105 | 106 | 107 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 123 | 124 | 125 | 126 | 127 | 128 | 131 | 132 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/I_TagCmp.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 21 | 22 | 23 | 32 | 33 | 34 | 43 | 44 | 45 | 53 | 54 | 55 | 63 | 64 | 65 | 73 | 74 | 75 | 83 | 84 | 85 | 94 | 95 | 96 | 105 | 106 | 107 | 116 | 117 | 118 | 127 | 128 | 129 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Sys/_Itf/I_EntityNode.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 76 | 77 | 78 | 91 | 92 | 93 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Entity/Core/Component.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 23 | 26 | 27 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 47 | 48 | 49 | 50 | 51 | 52 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | 72 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 85 | 86 | 89 | 90 | 92 | 93 | 94 | 95 | 96 | 111 | 112 | _nResult) THEN 120 | NewDebug(THIS^, Param.INIT_INTERNAL_DEBUG_MODE, Tc2_Standard.CONCAT('Failed with code: ', ResultToStr(_nResult))); 121 | END_IF]]> 122 | 123 | 124 | 125 | 129 | 130 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Jobs/Worker/Base/Worker.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | THIS^ 23 | *) 24 | METHOD Defer : Result 25 | VAR_INPUT 26 | iJob : I_Job; 27 | END_VAR 28 | VAR 29 | _iPrev : I_Job; 30 | _iNext : I_Job; 31 | _iThis : I_Worker := THIS^; 32 | END_VAR]]> 33 | 34 | _iThis THEN 40 | Defer := Err.NoMatch; 41 | RETURN; 42 | END_IF; 43 | 44 | _iPrev := iJob._Prev; 45 | _iNext := iJob._Next; 46 | 47 | IF _iPrev <> 0 THEN 48 | _iPrev._Next := _iNext; 49 | ELSE 50 | _iFirst := _iNext; 51 | END_IF; 52 | 53 | IF _iNext <> 0 THEN 54 | _iNext._Prev := _iPrev; 55 | ELSE 56 | _iLast := _iPrev; 57 | END_IF; 58 | 59 | iJob._Prev := _iLast; 60 | iJob._Next := 0; 61 | 62 | IF _iLast <> 0 THEN 63 | _iLast._Next := iJob; 64 | ELSE 65 | _iFirst := iJob; 66 | END_IF; 67 | 68 | _iLast := iJob; 69 | 70 | Defer := Ok;]]> 71 | 72 | 73 | 74 | THIS^ 80 | - Err.IncArg - iJob.State = TaskState.Idle 81 | *) 82 | METHOD Dequeue : Result 83 | VAR_INPUT 84 | iJob: I_Job; 85 | END_VAR 86 | VAR 87 | _iPrev: I_Job; 88 | _iNext: I_Job; 89 | _iThis: I_Worker := THIS^; 90 | END_VAR]]> 91 | 92 | _iThis THEN 98 | Dequeue := Err.NoMatch; 99 | RETURN; 100 | END_IF; 101 | 102 | IF iJob.State = JobState.Idle THEN 103 | Dequeue := Err.IncArg; 104 | RETURN; 105 | END_IF; 106 | 107 | _iPrev := iJob._Prev; 108 | _iNext := iJob._Next; 109 | 110 | IF _iPrev <> 0 THEN 111 | _iPrev._Next := _iNext; 112 | ELSE 113 | _iFirst := _iNext; 114 | END_IF; 115 | 116 | IF _iNext <> 0 THEN 117 | _iNext._Prev := _iPrev; 118 | ELSE 119 | _iLast := _iPrev; 120 | END_IF; 121 | 122 | IF iJob.State = JobState.Completed THEN 123 | iJob._OnDone(); 124 | ELSIF iJob.State = JobState.Aborted THEN 125 | iJob._OnAbort(); 126 | END_IF 127 | 128 | iJob._OnExit(); 129 | Dequeue := Ok;]]> 130 | 131 | 132 | 133 | THIS^ 139 | - Err.IncArg - iJob.State <> TaskState.Idle 140 | *) 141 | METHOD Enqueue : Result 142 | VAR_INPUT 143 | iJob: I_Job; 144 | END_VAR 145 | VAR 146 | _iThis: I_Worker := THIS^; 147 | END_VAR]]> 148 | 149 | _iThis THEN 155 | Enqueue := Err.NoMatch; 156 | RETURN; 157 | END_IF; 158 | 159 | IF iJob.State <> JobState.Idle THEN 160 | Enqueue := Err.IncArg; 161 | RETURN; 162 | END_IF; 163 | 164 | iJob._Prev := _iLast; 165 | iJob._Next := 0; 166 | IF _iLast <> 0 THEN 167 | _iLast._Next := iJob; 168 | ELSE 169 | _iFirst := iJob; 170 | END_IF; 171 | _iLast := iJob; 172 | 173 | iJob._OnStart(); 174 | Enqueue := Ok;]]> 175 | 176 | 177 | 178 | 183 | 184 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 201 | 202 | 0 THEN 203 | CASE iJob.State OF 204 | JobState.Aborted: 205 | Run := Ok; 206 | 207 | JobState.Completed: 208 | Run := Ok; 209 | 210 | JobState.Ready: 211 | iJob._OnRun(); 212 | Run := Ok; 213 | 214 | JobState.Error, JobState.Idle, JobState.Running: 215 | Run := Err.IncArg; 216 | 217 | END_CASE 218 | ELSE 219 | Run := Err.Itf0; 220 | END_IF]]> 221 | 222 | 223 | 224 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Tags/TagBase.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 24 | 25 | 26 | 27 | 37 | 38 | 73 | 74 | 75 | 76 | 78 | 79 | 82 | 83 | 0 THEN 84 | Id := Tc2_Standard.DELETE(_sId, _nOptionLen + 1, _nOptionPos); 85 | ELSE 86 | Id := _sId; 87 | END_IF]]> 88 | 89 | 90 | 91 | 92 | 94 | 95 | 99 | 100 | 0 THEN 101 | Option := Tc2_Standard.DELETE(_sId, _nOptionPos, 1); 102 | ELSE 103 | Option := ''; 104 | END_IF]]> 105 | 106 | 107 | 108 | 110 | 111 | '' THEN 112 | _nOptionLen := INT_TO_USINT(Tc2_Standard.LEN(Option)); 113 | IF _nOptionPos <> 0 THEN 114 | _sId := Tc2_Standard.LEFT(_sId, _nOptionPos); 115 | _sId := Tc2_Standard.CONCAT(_sId, Option); 116 | ELSE 117 | // The option does not exist, so we append it 118 | _nOptionPos := INT_TO_USINT(Tc2_Standard.LEN(_sId) + 1); 119 | _sId := Tc2_Standard.CONCAT(_sId, '.'); 120 | _sId := Tc2_Standard.CONCAT(_sId, Option); 121 | END_IF 122 | ELSIF _nOptionPos <> 0 THEN 123 | _sId := Tc2_Standard.LEFT(_sId, _nOptionPos - 1); 124 | _nOptionPos := 0; 125 | END_IF 126 | ]]> 127 | 128 | 129 | 130 | 131 | 0 137 | *) 138 | PROPERTY Proxy : REFERENCE TO I_Tag]]> 139 | 140 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 151 | 152 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/State/Manager/StateManager.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 58 | 59 | _iNewState)) THEN 60 | _iPretender := _iNewState; 61 | IF IsOk(_sm.Change(_iNewState, iOldState => _iOldState)) THEN 62 | _stateChangeEvent.Emit(_iNewState.Tag); 63 | 64 | _iCurrent := _iNewState; 65 | IF _iOldState <> 0 THEN 66 | _iPrevious := _iOldState; 67 | END_IF 68 | 69 | END_IF 70 | 71 | _iPretender := 0; 72 | END_IF 73 | 74 | ]]> 75 | 76 | 77 | 78 | 82 | 83 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 97 | 98 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 112 | 113 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 0 128 | *) 129 | PROPERTY Proxy : REFERENCE TO I_StateManager]]> 130 | 131 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 155 | 156 | _comp.Entity THEN 162 | Request := Err.NoMatch; 163 | RETURN; 164 | END_IF 165 | 166 | Request := _buffer.Push(iState);]]> 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /Stage/Stage/StageUtils/Color/Argbb.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | 18 | 19 | 23 | 24 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 45 | 46 | 49 | 50 | 51 | 52 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 71 | 72 | 80 | 81 | 82 | 83 | 94 | 95 | 100 | 101 | 102 | 103 | 107 | 108 | 111 | 112 | 113 | 114 | 115 | 116 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 130 | 131 | 134 | 135 | 139 | 140 | 141 | 142 | 145 | 146 | 150 | 151 | 152 | 153 | 154 | 158 | 159 | 162 | 163 | 164 | 165 | 166 | 167 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 187 | 188 | 192 | 193 | 194 | 195 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Strings/Strb/I_Strb.TcIO: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 15 | 16 | 17 | 29 | 30 | 31 | 43 | 44 | 45 | 56 | 57 | 58 | 69 | 70 | 71 | 79 | 80 | 81 | 86 | 87 | 88 | 93 | 94 | 95 | 102 | 103 | 104 | 109 | 110 | 111 | 118 | 119 | 120 | 126 | 127 | 128 | 138 | 139 | 140 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /Stage/Stage/StageCore/Broadcast/Sys/Helpers/_Pair.TcPOU: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | _nStart, nEnd => _nEnd)) OF 43 | Ok: 44 | // Found a free chunk of size 2 45 | None: 46 | CASE (_Pair := _BroadcastDefragment()) OF 47 | Ok: 48 | // We can safely assume that if _BroadcastGetBestFit and _BroadcastDefragment didn't failed then _Broadcast.nRecLen + 1 is the next unoccupied slot. 49 | // If _BroadcastGetBestFit failed then there is no avaliable space in the first place. 50 | // If _BroadcastDefragment failed then this wouldn't be executed. 51 | _nStart := _Broadcast.nRecLen + 1; 52 | _nEnd := _Broadcast.nRecLen + 2; 53 | ELSE 54 | RETURN; 55 | END_CASE 56 | ELSE 57 | // Any other error, just return 58 | RETURN; 59 | END_CASE 60 | 61 | IF IsOk(_Pair) THEN 62 | // Mark the first slot as signal header 63 | _Broadcast.entry[_nStart].nType := 1; 64 | _Broadcast.entry[_nStart].variant.iSignal := iSignal; 65 | 66 | // Mark the second slot as the receiver 67 | _Broadcast.entry[_nEnd].nType := 2; 68 | _Broadcast.entry[_nEnd].variant.iReceiver := iReceiver; 69 | 70 | // Update the signal's metadata 71 | iSignal._Start := _nStart; 72 | iSignal._End := _nEnd; 73 | iSignal._Size := 2; 74 | 75 | // Increase global count of used slots 76 | _Broadcast.nRecLen := _Broadcast.nRecLen + 2; 77 | 78 | // Update _Broadcast.iFirst if needed 79 | IF _Broadcast.iFirst = 0 THEN 80 | _Broadcast.iFirst := iSignal; 81 | ELSIF iSignal._Start < _Broadcast.iFirst._Start THEN 82 | _Broadcast.iFirst := iSignal; 83 | END_IF 84 | 85 | RETURN; 86 | ELSE 87 | RETURN; 88 | END_IF 89 | END_IF 90 | 91 | // 5) If the signal already has slots, try extending to the right by 1 slot. 92 | _nNextId := iSignal._End + 1; 93 | IF (_nNextId <= Param.RECEIVER_CAP) AND_THEN (_Broadcast.entry[_nNextId].nType = 0) THEN 94 | // Mark that free slot as a new receiver 95 | _Broadcast.entry[_nNextId].nType := 2; 96 | _Broadcast.entry[_nNextId].variant.iReceiver := iReceiver; 97 | 98 | // Update signal info 99 | iSignal._End := _nNextId; 100 | iSignal._Size := iSignal._Size + 1; 101 | 102 | // Increase global used-slot counter 103 | _Broadcast.nRecLen := _Broadcast.nRecLen + 1; 104 | 105 | _Pair := Ok; 106 | RETURN; 107 | END_IF 108 | 109 | // 6) Try expanding to the left by shifting the boundary marker left one slot. 110 | _nNextId := iSignal._Start - 1; 111 | IF (_nNextId > 0) AND_THEN (_Broadcast.entry[_nNextId].nType = 0) THEN 112 | // Copy old boundary marker to new index 113 | _Broadcast.entry[_nNextId] := _Broadcast.entry[iSignal._Start]; 114 | 115 | // Turn the old boundary marker slot into the new receiver 116 | _Broadcast.entry[iSignal._Start].nType := 2; 117 | _Broadcast.entry[iSignal._Start].variant.iReceiver := iReceiver; 118 | 119 | // Update signal to reflect new _Start 120 | iSignal._Start := _nNextId; 121 | iSignal._Size := iSignal._Size + 1; 122 | 123 | // Increase global used-slot counter 124 | _Broadcast.nRecLen := _Broadcast.nRecLen + 1; 125 | 126 | _Pair := Ok; 127 | RETURN; 128 | END_IF 129 | 130 | // 7) If neither immediate left nor right expansions are possible, we need a new chunk 131 | _nNewSize := iSignal._Size + 1; 132 | CASE (_Pair := _BroadcastGetBestFit(_nNewSize, nStart => _nStart, nEnd => _nEnd)) OF 133 | Ok: 134 | // Chunk found 135 | None: 136 | // No chunk found => defragment. 137 | CASE (_Pair := _BroadcastDefragment(iSignal)) OF 138 | Ok: 139 | // As above 140 | _nStart := _Broadcast.nRecLen + 1; 141 | _nEnd := _Broadcast.nRecLen + _nNewSize; 142 | ELSE 143 | RETURN; 144 | END_CASE 145 | ELSE 146 | // Other errors 147 | RETURN; 148 | END_CASE 149 | 150 | IF IsOk(_Pair) THEN 151 | 152 | // Move the entire existing block to the new chunk 153 | Tc2_SYSTEM.MEMMOVE( 154 | ADR(_Broadcast.entry[_nStart]), 155 | ADR(_Broadcast.entry[iSignal._Start]), 156 | SIZEOF(_BroadcastStruct) * iSignal._Size 157 | ); 158 | 159 | // Clear out the old region 160 | Tc2_SYSTEM.MEMSET( 161 | ADR(_Broadcast.entry[iSignal._Start]), 162 | 0, 163 | SIZEOF(_BroadcastStruct) * iSignal._Size 164 | ); 165 | 166 | // Mark the final slot in the new chunk as the new receiver 167 | _Broadcast.entry[_nEnd].nType := 2; 168 | _Broadcast.entry[_nEnd].variant.iReceiver := iReceiver; 169 | 170 | // Update the signal to reflect the new block location 171 | iSignal._Start := _nStart; 172 | iSignal._End := _nEnd; 173 | iSignal._Size := iSignal._Size + 1; 174 | 175 | // One more slot used 176 | _Broadcast.nRecLen := _Broadcast.nRecLen + 1; 177 | 178 | // If this signal was iFirst, re-scan for the new leftmost. 179 | // Otherwise, if we are now to the left of iFirst, update iFirst. 180 | IF _Broadcast.iFirst = iSignal THEN 181 | FOR i := 1 TO _Broadcast.nSignalLen DO 182 | _nNewStart := _Broadcast.iSignal[i]._Start; 183 | IF _nNewStart <> 0 AND_THEN _nNewStart < _nFirstId THEN 184 | _nFirstId := _Broadcast.iSignal[i]._Start; 185 | _Broadcast.iFirst := _Broadcast.iSignal[i]; 186 | END_IF 187 | END_FOR 188 | ELSIF iSignal._Start < _Broadcast.iFirst._Start THEN 189 | _Broadcast.iFirst := iSignal; 190 | END_IF 191 | END_IF]]> 192 | 193 | 194 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **Stage** 2 | _A framework for writing scalable and maintainable ST code_ 3 | 4 | [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/Krystian-L-Lis/Stage) 5 | 6 | --- 7 | 8 | ## Overview 9 | 10 | Stage is a framework designed to simplify PLC programming in TwinCAT 3.1. It promotes a modular approach to developing scalable and maintainable automation software through features based on composition, state and observer patterns. Stage integrates seamlessly into both simple and complex control applications, offering a structured and flexible development approach without unnecessary complexity. 11 | 12 | --- 13 | 14 | ## **Wiki** 15 | 16 | Check the [Wiki](https://github.com/Krystian-L-Lis/Stage/wiki) page! 17 | - Guides 18 | - API reference 19 | - Changelog 20 | - Obsidian-compatible 21 | 22 | --- 23 | 24 | ## **Requirements** 25 | 26 | Stage requires **Beckhoff TwinCAT 3.1**, specifically: 27 | 28 | - **Minimum TwinCAT version:** TwinCAT 3.1 - Build 4026 29 | - For TwinCAT system requirements, visit the official [Beckhoff TwinCAT System Requirements](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_overview/6162419083.html&id=) 30 | 31 | --- 32 | 33 | ## **Installation** 34 | 35 | 1. **Clone the repository:** 36 | ```sh 37 | git clone https://github.com/Krystian-L-Lis/Stage.git 38 | ``` 39 | 40 | 2. **Import the framework into TwinCAT:** 41 | 42 | ### **Option 1: Build from source** 43 | 44 | 1. Open your TwinCAT solution. 45 | 2. Locate the **Core PLC project**, expand it by clicking the arrow next to it. 46 | 3. **Right-click** on the Core PLC project and select **"Save as Library and Install"** to add it to the TwinCAT library repository. 47 | 4. **Right-click** on **References**, select **"Add Library"**, and locate the `Core` and/or `Utils` under `Stage` category to include it in your project. 48 | 5. For more detailed instructions on TwinCAT library installation, refer to the official Beckhoff guide on [Infosys](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/41891384434359666059.html&id=). 49 | 50 | ### **Option 2: Use precompiled files** 51 | 52 | 1. Download the compiled files(`Core.library` and/or `Utils.library`) from the [release page](https://github.com/Krystian-L-Lis/Stage/releases). 53 | 2. Open your TwinCAT PLC project and navigate to **References**, then **right-click** and select **"Library Repository" > "Install"**. 54 | Choose the downloaded `.library` file to add Stage to the repository. 55 | 3. After installation, **right-click** on **References**, select **"Add Library"**, and locate the `Core` and/or `Utils` under `Stage` category to include it in your project. 56 | 4. For more detailed instructions on TwinCAT library installation, refer to the official Beckhoff guide on [Infosys](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_plc_intro/41891384434359666059.html&id=). 57 | 58 | --- 59 | 60 | ## **Features** 61 | 62 | - Modular architecture through ECS inspired model. 63 | - Implement flexible state-driven logic. 64 | - Connect parts of your program via signals. 65 | - Manage workloads through jobs. 66 | 67 | --- 68 | ## **Tests & Examples** 69 | 70 | Tests and Examples can be found [here](https://github.com/Krystian-L-Lis/Stage-Examples). 71 | 72 | --- 73 | 74 | ## **Quick Start** 75 | 76 | This guide provides a brief overview of using the **Stage** framework. 77 | 78 | --- 79 | 80 | ### **Define a Simple Entity** 81 | Entities are declared within an entity scope, ensuring automatic registration of components. 82 | 83 | ```structured-text 84 | FUNCTION_BLOCK Pump IMPLEMENTS I_Callable, I_Execute, I_Init 85 | VAR_INPUT 86 | bOverload : BOOL; 87 | END_VAR 88 | VAR_OUTPUT 89 | bRunning : BOOL; 90 | END_VAR 91 | VAR 92 | _exe : Execute(THIS^); 93 | _init : Init(THIS^); 94 | 95 | // Define an entity scope 96 | _entityStart : EntityStart; 97 | 98 | // Automatically register components within the entity scope 99 | _tag : Tag := (Option := 'Pump'); 100 | _stateChangeEvent : Signal; 101 | _onCommand : Receiver(THIS^); 102 | 103 | _entityEnd : EntityEnd; 104 | END_VAR 105 | 106 | METHOD Init; END_METHOD // Implemented from I_Init 107 | METHOD Execute; END_METHOD // Implemented from I_Execute 108 | METHOD Call; // Implemented from I_Callable 109 | VAR_INPUT 110 | iArg : I_Arg; 111 | END_VAR 112 | END_METHOD 113 | 114 | END_FUNCTION_BLOCK 115 | 116 | ``` 117 | 118 | --- 119 | 120 | ### **Define States** 121 | 122 | ```structured-text 123 | // Create a context structure or interface 124 | TYPE Tank_Ctx: 125 | STRUCT 126 | rSomeSensor : LREAL; 127 | iPumpEventCache : I_Signal; 128 | iPumpCommandCache : I_Receiver; 129 | sHmiStatusText : Str; 130 | nHmiStatusColor : Color; 131 | END_STRUCT 132 | END_TYPE 133 | 134 | // Create an abstract state definition for a given context 135 | FUNCTION_BLOCK ABSTRACT _Tank_State EXTENDS State 136 | VAR 137 | _ctx : REFERENCE TO Tank_Ctx; 138 | END_VAR 139 | METHOD FB_Init 140 | VAR_INPUT 141 | ctx : REFERENCE TO Tank_Ctx; 142 | END_VAR 143 | _ctx REF= ctx; 144 | END_METHOD 145 | END_FUNCTION_BLOCK 146 | 147 | // Create a concrete state definition 148 | FUNCTION_BLOCK Tank_State_Empty EXTENDS _Tank_State 149 | METHOD PROTECTED OnEntry; END_METHOD // Override... 150 | METHOD PROTECTED OnExecute; END_METHOD // any or all... 151 | METHOD PROTECTED OnExit; END_METHOD // of these... 152 | METHOD PROTECTED CanActivate; CanActivate := TRUE; END_METHOD // methods. 153 | METHOD PROTECTED CanDeactivate; CanDeactivate := TRUE; END_METHOD 154 | END_FUNCTION_BLOCK 155 | ``` 156 | 157 | --- 158 | 159 | ### **Define an Entity with a State Manager** 160 | 161 | ```structured-text 162 | // Create a concrete state definition 163 | FUNCTION_BLOCK Tank_State_Full EXTENDS _Tank_State 164 | END_FUNCTION_BLOCK 165 | 166 | // Create a state machine entity definition 167 | FUNCTION_BLOCK Tank EXTENDS State 168 | VAR 169 | _ctx : Tank_Ctx; 170 | 171 | _entityStart : EntityStart; 172 | // Create a StateManager which wraps around the StateMachine 173 | // Apart from managing the state lifecycle, it also handles queues and change requests 174 | _smgr : StateManager; 175 | _empty : Tank_State_Empty(_ctx); 176 | _full : Tank_State_Full(_ctx); 177 | 178 | _entityEnd : EntityStart; 179 | END_VAR 180 | END_FUNCTION_BLOCK 181 | ``` 182 | 183 | --- 184 | 185 | ### **Browse the Entities Through the Registry** 186 | 187 | #### **Simple Method** 188 | 189 | ```structured-text 190 | // Browse entities 191 | WHILE IsOk(GetNextEntity(_iEntity)) DO 192 | // Use a helper function to browse and extract 193 | IF IsOk(GetTag(iEntity, 'Pump', _iPumpTag)) THEN 194 | EXIT; 195 | END_IF 196 | END_WHILE 197 | ``` 198 | 199 | --- 200 | 201 | #### **Verbose Method** 202 | 203 | ```structured-text 204 | // Alternatively, browse and cast components manually 205 | // This allows for multiple searches in one iteration 206 | WHILE IsOk(_iEntity.GetNextComp(_iComp)) DO 207 | IF IsOk(ICompToISignal(_iComp.Raw, _iSignal)) THEN 208 | _ctx.iPumpEventCache := _iSignal; 209 | ELSIF IsOk(ICompToIRec(_iComp.Raw, _iReceiver)) THEN 210 | _ctx.iPumpCommandCache := _iReceiver; 211 | END_IF 212 | 213 | // Exit early if both components are found 214 | IF _ctx.iPumpEventCache <> 0 AND _ctx.iPumpCommandCache <> 0 THEN 215 | EXIT; 216 | END_IF 217 | END_WHILE 218 | ``` 219 | 220 | --- 221 | 222 | ### **Emit Signals** 223 | 224 | ```structured-text 225 | VAR 226 | // Declare an emittable argument 227 | // Remember: arguments declared in a temporary scope 228 | // should not be cached or saved, as this will cause an exception! 229 | _bIsRunning : BoolArg(TRUE); 230 | END_VAR 231 | 232 | // Emit a signal 233 | _stateChangeEvent.Emit(_bIsRunning); 234 | 235 | // You should not use _bIsRunning after RETURN 236 | RETURN; 237 | ``` 238 | 239 | --- 240 | 241 | ## **Contributing** 242 | 243 | Contributions to the Stage framework are welcome! 244 | Feel free to fork the repository and submit pull requests. 245 | 246 | - **Fork the repository** and create a feature branch. 247 | - **Submit pull requests** for review. 248 | - **Discuss your ideas** by opening an issue before making major changes. 249 | 250 | This framework is in its early *stage* and requires extensive testing! 251 | 252 | --- 253 | 254 | ## **License** 255 | 256 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 257 | 258 | --- 259 | 260 | ## **Contact & Support** 261 | 262 | If you have questions or suggestions, feel free to reach out via: 263 | 264 | - **GitHub Issues:** [Submit an issue](https://github.com/Krystian-L-Lis/Stage/issues) 265 | 266 | --------------------------------------------------------------------------------