Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Non-preemptive task scheduler created by Jason Lee
- local API={
- version={0,1,3};
- }
- function deep_copy(object)
- local object_copy={}
- for k,v in pairs(object) do
- if type(v)=="table" then
- v=deep_copy(v)
- end
- object_copy[k]=v
- end
- return object_copy
- end
- function set_environment(current_environment,object_name,value)
- if type(program)=="function" then
- local environment=getfenv(current_environment)
- environment[object_name]=value
- setfenv(current_environment,environment)
- elseif type(current_environment)=="table" then
- for _,object in pairs(current_environment) do
- if type(object)=="function" then
- local environment=getfenv(object)
- environment[object_name]=value
- setfenv(object,environment)
- end
- end
- end
- end
- function set_environment_with_list(current_environment,list)
- for object_name,value in pairs(list) do
- set_environment(current_environment,object_name,value)
- end
- end
- function create_property(value)
- local property={value=value;binds={};}
- function property:invoke(custom_value)
- for _,bind in pairs(self.binds) do
- if bind~=nil and bind.action~=nil and type(bind.action)=="function" then
- bind.action(custom_value or self.value)
- end
- end
- end
- function property:set_value(value)
- if self==value or self.value==value then return end
- self.value=value
- self:invoke(self.value)
- end
- function property:add_value(value,index)
- if value~=nil and type(self.value)=="table" then
- table.insert(self.value,index or #self.value+1,value)
- self:invoke(self.value)
- end
- end
- function property:remove_value(index)
- if index~=nil and type(self.value)=="table" and self.value[index]~=nil then
- table.remove(self.value,index)
- self:invoke(self.value)
- end
- end
- function property:attach_bind(action)
- if action==nil or type(action)~="function" then return end
- local bind={action=action;}
- function bind:detach() bind.action,bind=nil,nil end
- table.insert(self.binds,#self.binds+1,bind)
- return bind
- end
- return property
- end
- function API:create_scheduler()
- local scheduler={
- current_tick=0;
- threads={};
- }
- function scheduler:create_thread(environment)
- if environment==nil then return end
- local thread={
- runtime={
- run_state=create_property(true);
- resume_tick=0;
- };
- scheduler=scheduler;
- libraries={};
- }
- function thread.runtime:wait(duration) duration=duration or 0
- thread.runtime.resume_tick=scheduler.current_tick+duration
- coroutine.yield()
- return true
- end
- function thread:set_run_state(state)
- thread.runtime.run_state:set_value(state or false)
- end
- function thread:import(library,library_name)
- if library==nil or thread==nil or library_name==nil then return end
- if type(library)=="string" then library=require(library) end
- if type(library)=="table" then library=deep_copy(library) end
- set_environment_with_list(library,{
- thread=thread;
- lib=library;
- import=function(a,b) return thread:import(a,b) end;
- wait=function(a) return thread.runtime:wait(a) end;
- })
- thread.libraries[library_name]=library
- if type(library)=="table" and library.post_import_setup~=nil then
- library:post_import_setup()
- end
- return library
- end
- function thread:delete()
- thread.runtime.run_state:set_value(false)
- thread=nil
- end
- thread.coroutine=coroutine.create(environment)
- table.insert(scheduler.threads,#scheduler.threads+1,thread)
- return thread
- end
- function scheduler:cycle(tick)
- local output_buffer={}
- if tick~=nil and type(tick)=="number" then
- scheduler.current_tick=tick
- end
- for i,thread in pairs(scheduler.threads) do
- if thread==nil or coroutine.status(thread.coroutine)=="dead" then
- table.remove(scheduler.threads,i)
- elseif thread.runtime.run_state.value==true and thread.runtime.resume_tick<=scheduler.current_tick then
- local _,output=coroutine.resume(thread.coroutine,thread)
- table.insert(output_buffer,#output_buffer+1,output)
- end
- end
- return output_buffer
- end
- return scheduler
- end
- return API
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement