Prexxo

Event Class, Brief explanation

Jun 18th, 2021
1,138
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2.     Simple Events, brief explanation on logic behind them
  3.  
  4.     About events :
  5.     Event-driven programming is a method in programming to handle systems based on exection of given events,
  6.     it allows us to avoid constantly checking if "x" changed but we rather tell it when it has, therefore greatly optimizing it.
  7.  
  8.     NOTES :
  9.     Each callback invoked creates a new thread to allow yielding.
  10.    
  11.     Using coroutine.wrap function to make a method which yields the thread until the event has been fired is discouraged and not
  12.     efficient to do. Unless the engine, library, whatever you're using allows you to do so more efficiently then feel free to.
  13.  
  14.     Making a WeakFire or WeakConnection methods which don't create a thread when triggered is an option though not advised.
  15.     You can easily mess up and keep in mind it's cons as well as consider if it's even worth using..
  16.  
  17. --]]
  18.  
  19. local function EventDisconnect(Connection)
  20.     --[[
  21.     Using Callback index we fetch the connections call back and remove it from the list so it is't affected by fire method anymore.
  22.    
  23.     Important to use table.remove and not manually set value to nil in order to keep the array without any nil spots to avoid iteration problems.
  24.    
  25.     --]]
  26.  
  27.     local Event = Connection.Event
  28.     Event.NumberOfCallbacks = Event.NumberOfCallbacks - 1
  29.  
  30.     table.remove(Event.Callbacks, Connection.CallbackIndex)
  31. end
  32.  
  33. local function EventConnect(Event, Callback)
  34.     --[[
  35.     Increase "NumberOfCallbacks" variable to keep track on how many call backs are in the list which we later use to directly
  36.     index the call back in list in order to disconnect.
  37.  
  38.     Callback function is cached in a list so when we fire the event we can simply loop through all of them and invoke each function connected.
  39.  
  40.     A table is returned in order to give an option to disconnect the connection and avoid memory leaks. (Table:Method(), self reference is passed for convenient indexing)
  41.  
  42.     --]]
  43.  
  44.     local NumberOfCallbacks = Event.NumberOfCallbacks + 1
  45.     Event.NumberOfCallbacks = NumberOfCallbacks
  46.    
  47.     Event.Callbacks[NumberOfCallbacks] = Callback
  48.  
  49.     return {
  50.         Event = Event,
  51.         CallbackIndex = NumberOfCallbacks,
  52.  
  53.         Disconnect = EventDisconnect,
  54.     }
  55. end
  56.  
  57. local function EventFire(Event, ...)
  58.     --[[
  59.     Iterate through the list of call backs and invoke them.
  60.  
  61.     Each call back is executed in a seperate thread in case they have a yield in them which would error and unwanted yields between each call
  62.  
  63.     example :
  64.  
  65.     Event:Connect(function(...)
  66.         print(...)
  67.         wait(3)
  68.     end
  69.  
  70.     for i = 1, 10 do
  71.         Event:Fire("Hello")
  72.     end;
  73.  
  74.     Each time the event is fired the callback will print the message "Hello" wait 3 seconds then continue to invoke the next one
  75.  
  76.  
  77.     --]]
  78.  
  79.     local Callbacks = Event.Callbacks
  80.  
  81.     for Index = 1, Event.NumberOfCallbacks do
  82.         coroutine.wrap(Callbacks[Index])(...)
  83.     end
  84. end
  85.  
  86. local EventClass = {}
  87.  
  88. function EventClass.new()
  89.     return {
  90.         --// Properties
  91.         Callbacks = {},
  92.         NumberOfCallbacks = 0,
  93.  
  94.         --// Methods
  95.         Connect = EventConnect,        
  96.         Fire = EventFire,
  97.     }
  98. end
  99.  
  100.  
RAW Paste Data