Advertisement
emilistt

StateHandler.lua

Apr 3rd, 2022
826
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.97 KB | None | 0 0
  1. local RunService = game:GetService("RunService");
  2. local ReplicatedStorage = game:GetService("ReplicatedStorage");
  3. local Players = game:GetService("Players");
  4.  
  5. local Remotes = ReplicatedStorage.Remotes;
  6.  
  7. local StateRemote = Remotes.StateRemote;
  8.  
  9. local Modules = ReplicatedStorage.Modules;
  10. local Utility = Modules.Utility;
  11.  
  12. local TablesLibrary = require(Utility.TablesLibrary);
  13. local DefaultStates = require(script.DefaultStates);
  14. local FastSignal = require(Utility.FastSignal);
  15.  
  16. local StateHandler = {};
  17. StateHandler.Characters = {};
  18.  
  19. DEAD_CHARACTER_ERROR = "Character isn't alive";
  20. NOT_INITIALIZED_CHARACTER_ERROR = "Character isn't Initialized";
  21. ALREADY_INITIALIZED_CHARACTER_ERROR = "Character has already been Initialized";
  22. STATE_DOESNT_EXIST_ERROR = "State [%s] hasn't been found";
  23. TIMEOUT_WARNING = "[%s]'s state initialization await function has timed out!";
  24.  
  25. --[[
  26. TODO: When calling a function, if character isn't initialized, make it await until Character has been initialized or it's been time out(10s)
  27. ]]
  28.  
  29. --// PRIVATE
  30. local INIT_TIMEOUT = 10;
  31.  
  32.  
  33. local InitializationConnections = {};
  34.  
  35. local function GetInternalState(CharacterIndex, stateIndex)
  36.  
  37. end
  38.  
  39. --// PUBLIC
  40.  
  41. function StateHandler.Initialize(Character)
  42.     assert(Character, DEAD_CHARACTER_ERROR);
  43.     if StateHandler.Characters[Character] then
  44.         warn(ALREADY_INITIALIZED_CHARACTER_ERROR)
  45.         return;
  46.     end
  47.  
  48.     StateHandler.Characters[Character] = TablesLibrary.DeepCopyTable(DefaultStates);
  49.  
  50.     local Data = StateHandler.Characters[Character];
  51.  
  52.     for StateName, StateData in pairs(Data) do
  53.         Data[StateName].GetPropertyChangedSignal = function(PropertyName : string | nil)
  54.             if Data[StateName].Connection then
  55.                 return Data[StateName].Connection;
  56.             end
  57.             Data[StateName].Connection = FastSignal.new();
  58.  
  59.             return  Data[StateName].Connection;
  60.         end
  61.     end
  62.  
  63.     if InitializationConnections[Character] then
  64.         InitializationConnections[Character]:Fire();
  65.     end
  66.  
  67.     return Data;
  68. end
  69.  
  70. function StateHandler:AwaitInitialization(CharacterIndex : model) : number
  71.     if not StateHandler.Characters[CharacterIndex] then
  72.         task.defer(function()
  73.             task.wait(INIT_TIMEOUT);
  74.  
  75.             if not StateHandler.Characters[CharacterIndex] then
  76.                 warn( TIMEOUT_WARNING:format(CharacterIndex.Name) );
  77.             end
  78.         end)
  79.         if InitializationConnections[CharacterIndex] then
  80.             InitializationConnections[CharacterIndex]:Wait();
  81.         else
  82.             InitializationConnections[CharacterIndex] = FastSignal.new();
  83.             InitializationConnections[CharacterIndex]:Wait();
  84.         end
  85.     end
  86.  
  87.     InitializationConnections[CharacterIndex] = nil;
  88.  
  89.     print("Initialized!");
  90.  
  91.     return 1;
  92. end
  93.  
  94. function StateHandler:GetPropertyChangedSignal(CharacterIndex : Model, stateIndex : string | number | boolean, PropertyName : string | nil)
  95.     assert(CharacterIndex, DEAD_CHARACTER_ERROR);
  96.     assert(StateHandler.Characters[CharacterIndex], NOT_INITIALIZED_CHARACTER_ERROR);
  97.     assert(StateHandler.Characters[CharacterIndex][stateIndex], STATE_DOESNT_EXIST_ERROR:format(stateIndex));
  98.  
  99.     return StateHandler.Characters[CharacterIndex][stateIndex].GetPropertyChangedSignal(PropertyName);
  100. end
  101.  
  102. function StateHandler.Deinitialize(CharacterIndex)
  103.     assert(CharacterIndex, DEAD_CHARACTER_ERROR);
  104.     assert(StateHandler.Characters[CharacterIndex], NOT_INITIALIZED_CHARACTER_ERROR);
  105.  
  106.     StateHandler.Characters[CharacterIndex] = nil;
  107. end
  108.  
  109. function StateHandler:GetData(CharacterIndex, stateIndex)
  110.     assert(CharacterIndex, DEAD_CHARACTER_ERROR);
  111.    
  112.     if not StateHandler.Characters[CharacterIndex] then
  113.         StateHandler:Initialize(CharacterIndex);
  114.     end
  115.  
  116.     assert(StateHandler.Characters[CharacterIndex][stateIndex], STATE_DOESNT_EXIST_ERROR:format(stateIndex));
  117.  
  118.     if StateHandler.Characters[CharacterIndex][stateIndex].Duration then
  119.  
  120.     end
  121.  
  122.     return StateHandler.Characters[CharacterIndex][stateIndex].Value;
  123. end
  124.  
  125. function StateHandler:ReturnState(CharacterIndex, stateIndex)
  126.     assert(CharacterIndex, DEAD_CHARACTER_ERROR);
  127.     assert(StateHandler.Characters[CharacterIndex], NOT_INITIALIZED_CHARACTER_ERROR);
  128.     assert(StateHandler.Characters[CharacterIndex][stateIndex], STATE_DOESNT_EXIST_ERROR:format(stateIndex));
  129.  
  130.     return StateHandler.Characters[CharacterIndex][stateIndex];
  131. end
  132.  
  133. if RunService:IsClient() then
  134.  
  135.     function StateHandler:UpdateState(CharacterIndex, stateIndex, stateValue)
  136.         assert(CharacterIndex, DEAD_CHARACTER_ERROR);
  137.         assert(StateHandler.Characters[CharacterIndex], NOT_INITIALIZED_CHARACTER_ERROR);
  138.         assert(StateHandler.Characters[CharacterIndex][stateIndex], STATE_DOESNT_EXIST_ERROR:format(stateIndex));
  139.  
  140.         if StateHandler.Characters[CharacterIndex][stateIndex].Value == stateValue then return; end
  141.  
  142.         StateHandler.Characters[CharacterIndex][stateIndex].Value = stateValue;
  143.  
  144.         if StateHandler.Characters[CharacterIndex][stateIndex].Connection then
  145.             coroutine.wrap(function()
  146.                 StateHandler.Characters[CharacterIndex][stateIndex].Connection:Fire(stateValue);
  147.             end)();
  148.         end
  149.  
  150.         return stateValue;
  151.     end
  152.  
  153.     return StateHandler;
  154. elseif RunService:IsServer() then
  155.  
  156.     function StateHandler:UpdateState(CharacterIndex, stateIndex, stateValue, Duration, Priority)
  157.         assert(CharacterIndex, DEAD_CHARACTER_ERROR);
  158.         assert(StateHandler.Characters[CharacterIndex], NOT_INITIALIZED_CHARACTER_ERROR);
  159.         assert(StateHandler.Characters[CharacterIndex][stateIndex], STATE_DOESNT_EXIST_ERROR:format(stateIndex));
  160.  
  161.         if StateHandler.Characters[CharacterIndex][stateIndex].Value == stateValue then return; end
  162.        
  163.         local oldStateValue = StateHandler.Characters[CharacterIndex][stateIndex].Value;
  164.  
  165.         StateHandler.Characters[CharacterIndex][stateIndex].Value = stateValue;
  166.  
  167.         if Duration and StateHandler.Characters[CharacterIndex][stateIndex].Duration then
  168.             if (StateHandler.Characters[CharacterIndex][stateIndex].Priority > Priority and
  169.                 StateHandler.Characters[CharacterIndex][stateIndex].StartTime + StateHandler.Characters[CharacterIndex][stateIndex].Duration < os.clock())
  170.             then
  171.                 return;
  172.             end
  173.            
  174.             local StartTime = os.clock();
  175.            
  176.             StateHandler.Characters[CharacterIndex][stateIndex].Priority = Priority;
  177.             StateHandler.Characters[CharacterIndex][stateIndex].Duration = Duration;
  178.             StateHandler.Characters[CharacterIndex][stateIndex].StartTime = StartTime;
  179.            
  180.             task.delay(Duration, function()
  181.                 if (StateHandler.Characters[CharacterIndex][stateIndex].StartTime == StartTime and StateHandler.Characters[CharacterIndex][stateIndex].Priority == Priority)
  182.                     or StateHandler.Characters[CharacterIndex][stateIndex].Priority < Priority then
  183.                    
  184.                     StateHandler.Characters[CharacterIndex][stateIndex].Value = oldStateValue;
  185.                 end
  186.             end)
  187.         end
  188.  
  189.         if StateHandler.Characters[CharacterIndex][stateIndex].Connection then
  190.             coroutine.wrap(function()
  191.                 StateHandler.Characters[CharacterIndex][stateIndex].Connection:Fire(stateValue);
  192.             end)();
  193.         end
  194.  
  195.         local Player = Players:GetPlayerFromCharacter(CharacterIndex);
  196.  
  197.         if Player then
  198.             StateRemote:FireClient(Player, stateIndex, stateValue);
  199.         end
  200.        
  201.         return stateValue;
  202.     end
  203.  
  204.     return StateHandler;   
  205. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement