This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Perun's profile picture

Passing environment into shell

Started by Perun, 14 September 2013 - 03:24 AM
Perun #1
Posted 14 September 2013 - 05:24 AM
Title: Passing environment into shell

Im not sure, maybe somebody did already ask for this. I am doing a program that should handle eventHandlers in more fashionate way. I found out that there sould be two ways how to do it. 1. bypass all calls that make thread yield and do the eventHandling before that. (not sure if I can do it globally) (or do I, when does the invocations get flushed???)
2. have a parallel program that handles all events and passes them in a table, which is then used by doEvents function. But I had troubles with passing environment variebles through os.run(env, "rom/programs/shell"). I didn't have problems passing it into any other programs. I kind of got stuck here and am thinking of redoing it into the first variant.

Is it so that shell creates its own environment and flushes everything passed by the first parameter??

Eventually what are all the calls that make the main thread yield??

Well and when I try to do it on a single thread I want to put the "endOfInvocs" event to know when to stop listening the events, but somehow it doesnt work.

local function listenSingle()
print("started listening")
local Args = {}
os.queueEvent("EndOfInvocs") -- none of read, sleep or os.pullEvent and other yielding calls should be called here
Args[1] = _pullEvent()  -- otherwise the program ends in infinite loop
local eventStr = Args[1]
while eventStr ~= "EndOfInvocs" do
  print(eventStr)
  local event = StringToEvent(eventStr)
  table.remove(Args,1)
  for i,handler in pairs(_Events[event].handlers) do
   table.insert(_invocations,{func = handler.func,Args = Args})
  end
  Args = {_pullEvent()}
  eventStr = Args[1]
end
end
GravityScore #2
Posted 14 September 2013 - 02:30 PM
I don't really understand what you're saying in your explanation… But a few things:

- Post your full code. You made reference to doEvents, but there's nothing about that in the code.
- What do you mean by "flushes"?
- There is no "main thread" so to speak. Lua uses coroutines, which is cooperative multitasking - meaning that two things aren't really running simultaneously. Also, things that will cause a "main" coroutine to yield can also be used to yield other coroutines - it doesn't change from coroutine to coroutine. These things are things like coroutine.yield(), os.pullEvent(), os.pullEventRaw(), sleep(), any turtle function, etc.
- Why in your code do you queue an event, then call os.pullEvent straight after it? That seems quite pointless…

If you're having trouble with os.run, you could try using loadfile and setfenv instead:

local env = setmetatable({}, {__index = getfenv()})

-- Add any extra environment variables here
env["hello"] = "hello there!"

local func, err = loadfile("path/to/file.lua")
assert(not err, err) -- Check that the file didn't cause a parse error
setfenv(func, metatable)
local _, err = pcall(func) -- Catch any error the file may bring up
assert(not err, err) -- Handle the error the file brought up if it did bring one up at all