Advertisement
Guest User

Untitled

a guest
Jan 17th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.07 KB | None | 0 0
  1. --Non-preemptive task scheduler created by Jason Lee
  2.  
  3. local API={
  4.     version={0,1,3};
  5. }
  6.  
  7. function deep_copy(object)
  8.     local object_copy={}
  9.     for k,v in pairs(object) do
  10.         if type(v)=="table" then
  11.             v=deep_copy(v)
  12.         end
  13.         object_copy[k]=v
  14.     end
  15.     return object_copy
  16. end
  17.  
  18. function set_environment(current_environment,object_name,value)
  19.     if type(program)=="function" then
  20.         local environment=getfenv(current_environment)
  21.         environment[object_name]=value
  22.         setfenv(current_environment,environment)
  23.     elseif type(current_environment)=="table" then
  24.         for _,object in pairs(current_environment) do
  25.             if type(object)=="function" then
  26.                 local environment=getfenv(object)
  27.                 environment[object_name]=value
  28.                 setfenv(object,environment)
  29.             end
  30.         end
  31.     end
  32. end
  33.  
  34. function set_environment_with_list(current_environment,list)
  35.     for object_name,value in pairs(list) do
  36.         set_environment(current_environment,object_name,value)
  37.     end
  38. end
  39.  
  40. function create_property(value)
  41.     local property={value=value;binds={};}
  42.     function property:invoke(custom_value)
  43.         for _,bind in pairs(self.binds) do
  44.             if bind~=nil and bind.action~=nil and type(bind.action)=="function" then
  45.                 bind.action(custom_value or self.value)
  46.             end
  47.         end
  48.     end
  49.     function property:set_value(value)
  50.         if self==value or self.value==value then return end
  51.         self.value=value
  52.         self:invoke(self.value)
  53.     end
  54.     function property:add_value(value,index)
  55.         if value~=nil and type(self.value)=="table" then
  56.             table.insert(self.value,index or #self.value+1,value)
  57.             self:invoke(self.value)
  58.         end
  59.     end
  60.     function property:remove_value(index)
  61.         if index~=nil and type(self.value)=="table" and self.value[index]~=nil then
  62.             table.remove(self.value,index)
  63.             self:invoke(self.value)
  64.         end
  65.     end
  66.     function property:attach_bind(action)
  67.         if action==nil or type(action)~="function" then return end
  68.         local bind={action=action;}
  69.         function bind:detach() bind.action,bind=nil,nil end
  70.         table.insert(self.binds,#self.binds+1,bind)
  71.         return bind
  72.     end
  73.     return property
  74. end
  75.  
  76. function API:create_scheduler()
  77.     local scheduler={
  78.         current_tick=0;
  79.         threads={};
  80.     }
  81.    
  82.     function scheduler:create_thread(environment)
  83.         if environment==nil then return end
  84.         local thread={
  85.             runtime={
  86.                 run_state=create_property(true);
  87.                 resume_tick=0;
  88.             };
  89.             scheduler=scheduler;
  90.             libraries={};
  91.         }
  92.        
  93.         function thread.runtime:wait(duration) duration=duration or 0
  94.             thread.runtime.resume_tick=scheduler.current_tick+duration
  95.             coroutine.yield()
  96.             return true
  97.         end
  98.        
  99.         function thread:set_run_state(state)
  100.             thread.runtime.run_state:set_value(state or false)
  101.         end
  102.        
  103.         function thread:import(library,library_name)
  104.             if library==nil or thread==nil or library_name==nil then return end
  105.             if type(library)=="string" then library=require(library) end
  106.             if type(library)=="table" then library=deep_copy(library) end
  107.             set_environment_with_list(library,{
  108.                 thread=thread;
  109.                 lib=library;
  110.                 import=function(a,b) return thread:import(a,b) end;
  111.                 wait=function(a) return thread.runtime:wait(a) end;
  112.             })
  113.             thread.libraries[library_name]=library
  114.             if type(library)=="table" and library.post_import_setup~=nil then
  115.                 library:post_import_setup()
  116.             end
  117.             return library
  118.         end
  119.        
  120.         function thread:delete()
  121.             thread.runtime.run_state:set_value(false)
  122.             thread=nil
  123.         end
  124.        
  125.         thread.coroutine=coroutine.create(environment)
  126.         table.insert(scheduler.threads,#scheduler.threads+1,thread)
  127.         return thread
  128.     end
  129.    
  130.     function scheduler:cycle(tick)
  131.         local output_buffer={}
  132.         if tick~=nil and type(tick)=="number" then
  133.             scheduler.current_tick=tick
  134.         end
  135.         for i,thread in pairs(scheduler.threads) do
  136.             if thread==nil or coroutine.status(thread.coroutine)=="dead" then
  137.                 table.remove(scheduler.threads,i)
  138.             elseif thread.runtime.run_state.value==true and thread.runtime.resume_tick<=scheduler.current_tick then
  139.                 local _,output=coroutine.resume(thread.coroutine,thread)
  140.                 table.insert(output_buffer,#output_buffer+1,output)
  141.             end
  142.         end
  143.         return output_buffer
  144.     end
  145.    
  146.     return scheduler
  147. end
  148.  
  149. return API
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement