Sleep Lua script without halting entire program? - lua

I'm writing a GUI that's meant to be easily customizable by the end-users. The functions are in C++ and are called from Lua. I'm trying to make a Sleep() type function that will pause the script but not the program itself.
I was able to get it working by using threads and making one for each function. However, I want it to be an individual function. As in, instead of having it part of the CreateButton function and every other function, simply having a Delay or Sleep function that only halts the script, not the entire program.
Me being a novice at Lua, I really don't know how to go about this. Any help is appreciated.

I'd look into making a state machine using coroutines and message passing. Treat each button push like a c++ string that gets passed into coroutine resume. You can then build a little state machine that switches on the message. You can then do some UI work and then put the coroutine back to sleep till something sends it another message.
This is pretty handy if you have a state machine that does UI.
pseudo code:
c_obj:wait_for_message("mouse_down");
local message = coroutine.yield();
if(message == "mouse_down") then
update draw function.
end
c_obj:wait_for_message("mouse_up");
local message = coroutine.yield();
if(message == "mouse_up") then
Update UI..
update draw function.
end
etc...

To make your busy-waiting solution more efficient, how about using select() or similar to wait for some GUI events to process, rather than spinning? It seems like something you would need to do in the GUI regardless of the scripting side of things.

Related

Trying to run two loops at the same time Minecraft ComputerCrafft

This is my code
https://pastebin.com/fnZreFKA
I have tried all the coroutine options, I have print statements at the start of each of the two functions, it prints, but it doesn't do anything in the loop
coroutine.wrap(constantWork)()
coroutine.wrap(lookForKeys)()
The loops start after line 170
Because they are not detached threads, they are green synchronous threads, only one of them will run the code at the time.
To simulate multitasking you forgot to use yield. coroutine.yield pauses the thread and runs the next code after you called the coroutine. You can resume the coroutine later on by calling wrapped coroutine again or using coroutine.resume if you created it using coroutine.create.
Read the documentation here: https://www.lua.org/pil/9.html
coroutine.wrap creates a new coroutine based on the function you passed it, and then creates a new function based on the coroutine. The first time you call it, it calls the original function until it yields. The next time, it returns from the yield and runs until the next yield. And so on.
In ComputerCraft, yielding is the same as waiting for an event.
ComputerCraft comes with the parallel library which runs two or more functions as coroutines in parallel. It does all the work for you.
You can use parallel.waitForAll or parallel.waitForAny, depending on when you want it to return.
Usage: parallel.waitForAll(constantWork, lookForKeys)

{LUA} How to fire another script in script?

I have a question from Lua/Roblox!
Basically, I want to fire a script from a script. This may sound like a stupid question, but actually it isn't :P
For example:
I have a script: script1 in ServerScriptStorage.
And, I want to code it to fire contents of script2.
Examples:
Content of script1:
game.Players.PlayerAdded:Connect(function()
HERE SCRIPT2 FIRING!
end)
Content of script2:
print("This message is triggered by event in script!")
This is fairly simple task I suppose, so please give me the SIMPLEST and SHORTEST version of code. I don't need any exclusives such like launching 2 script in 1. I'm a begginer script, so please keep it simple.
Thanks, NorteX.
In pure Lua, using dofile would probably make the most sense. However, in Roblox, the approach must be much different. The way I would recommend doing this is using a ModuleScript for "Script2". Then you would load the script using require(). Because "requiring" a script caches the returned value for future "requires", this means that the contents of the ModuleScript will only be executed once. Thus, if you have code you want to run multiple times, you should encapsulate it in a function that the ModuleScript returns.
Here's how the code would look like given your setup:
Script1:
local script2 = require(game.ServerScriptService.Script2)
game.Players.PlayerAdded:Connect(function(player)
script2()
end)
Script2:
-- In game.ServerScriptService.Script2 as a ModuleScript
return function()
print("This message is triggered by event in script!")
end
Check out the documentation for ModuleScripts to understand more about them.
workspace.SCRIPT2.Disabled = true -- Disables SCRIPT2 , you can remove this and manually disable it in SCRIPT2's properties.
game.Players.PlayerAdded:Connect(function()
workspace.SCRIPT2.Disabled = false -- Activates SCRIPT2. You can alter the "disabled" state multiple time to make it reboot and operate more than once.
end)
Also, you could replace workspace.SCRIPT2.Disabled by the location where your second script is, by example, workspace.FolderOne.scripts.SCRIPT2.Disabled . Just be sure it points to the script and keeps the "disabled" part on, so it knows to disable / enable it.

Lua: run code while waiting for input

I'm currently working on a lua program.
I want to use it in Minecraft with a mod called "OpenComputers" which allows the use of lua scripts on emulated systems.
The programm I'm working on is relatively simple: you have a console and you enter a command to control a machine.
It looks like this:
while(true) do
io.write("Enter command\n>")
cmd = io.read()
-- running code to process the command
end
But the problem is: I need a routine running in the background which checks data given by the machine.
while(true) do
-- checking and reacting
end
How can I make this work?
I can't jump to a coroutine while waiting on io.read()
It's not enough to check after someone used a command (sometimes I don't use it for days but I still have to keep an eye on it)
I'm relatively new to lua so please try to give a simple solution and - if possible - one that does not rely on third party tools.
Thank you :)
If you have some experience with opencomputers, you can add a(n asynchronous) listener for "key_down", and store the user input in a string (or whatever you want).
For example:
local userstr = ""
function keyPressed(event_name, player_uuid, ascii)
local c = string.char(ascii)
if c=='\n' then
print(userstr)
userstr = ""
else
userstr=userstr..c
end
--stores keys typed by user and prints them as a string when you press enter
end
event.register("key_down", keyPressed)
Running multiple tasks is a very broad problem solved by the operating system, not something as simple as Lua interpreter. It is solved on a level much deeper than io.read and deals with troubles numerous enough to fill a couple of books. For lua vm instead of physical computer, it may be simpler but it would still need delving deep into how the letters of code are turned into operations performed by the computer.
That mod of yours seems to already emulate os functionality for you: 1,2. I believe you'll be better off by making use of the provided functionality.

Running script for a group to access functions within group parts

I was just wondering in roblox if anyone has ever come upon a situation where they needed to run scripts from another script. My situation is that I am making a control point system for a game. I need to be able to know if the other points are captured in order to capture the next ones so I am attempting to write a controller on top of it but i am not sure exactly how to access the functions from within the control point script.
Yes! ROBLOX provides a very useful feature called ModuleScripts for the very purpose of calling scripts from other scripts. The icon for ModuleScripts looks the same as the icon for regular Scripts except with a little brick in the bottom-right.
The way it works is that regular Scripts can call ModuleScripts in the game using the special require() function. The easiest way to explain this is with an example.
To begin, let's imagine that we have a Script and a ModuleScript. The Script will be located at game.Workspace.normalScript, and the ModuleScript will be located inside a brick called part at game.Workspace.part.moduleScript.
moduleScript will contain the following code:
script.Parent.Transparency = .5 --"Parent" is the part since this ModuleScript is located inside the part
Now, normalScript will contain the following code:
require(game.Workspace.part.moduleScript)
When you run the game, normalScript will execute moduleScript, changing the transparency of part to .5. When one calls require() on a ModuleScript, it will act as though it were a normal function being called. moduleScript acted as though it were a function, and ModuleScripts in general act the same way as functions for the most part.
This also means that ModuleScripts can return values like functions. For example, if we have the following code in moduleScript:
return 3+3
Now, our script will contain the following code:
local number = require(game.Workspace.moduleScript)
print(number) --> 6
This code will print "6" to the console since moduleScript returned 6. As you might guess, this means that ModuleScripts have many more uses than simply remotely executing code.
Here are two more examples of uses of ModuleScripts:
1) Returning functions:
moduleScript:
return function()
print("hey")
end
normalScript:
local func = require(game.Workspace.moduleScript)
func() --> hey
2) Returning modules such as apple below:
moduleScript:
local apple = {}
apple.flavor = "sweet"
return apple
normalScript:
local fruit = require(game.Workspace.moduleScript)
print(fruit.flavor) --> sweet
These are rather silly examples of ModuleScript uses, but ModuleScripts can actually be very powerful tools. For some cool examples, visit the ROBLOX Wiki page on ModuleScripts and scroll about halfway down.

Hacking Lua - Inject new functions into built Lua

I am trying to hack a game (not for cheating though) by introducing new built-in methods and functions in order to communicate with the game using sockets. Here is a small "pseudo code" example of what I want to accomplish:
Inside the Lua code I am calling my_hack() and pass the current game state:
GameState = {}
-- Game state object to be passed on
function GameState:new()
-- Data
end
local gameState = GameState:new()
-- Collect game state data and pass it to 'my_hack' ..
my_hack(gameState)
and inside my_hack the object is getting sent away:
int my_hack(lua_State * l)
{
void* gameState= lua_topointer(l, 1);
// Send the game state:
socket->send_data(gameState);
return 0;
}
Now, the big question is how to introduce my_hack() to the game?
I assume, that all built in functions must be kept in some sort of lookup table. Since all Lua code is getting interpreted, functions like import etc. will have to be statically available, right? If that is correct, then it should be "enough" to find out where this code is residing in order to smuggle my code into the game that would allow me to call my_hack() in a Lua script.
There should be two options: The first is that the Lua built is embedded inside the executable and is completely static and the second is that all Lua code gets loaded dynamically from a DLL.
This question goes out to anybody who has a slightest clue about where and how I should keep looking for the built in functions. I've tried a few things with Cheat Engine but I wasn't too successful. I was able to cheat a bit ^^ but that's not what I'm looking out for.
Sorry for not providing a full answer, but if you can provide a custom Lua VM and change the standard libraries, you should be able to to change the luaL_openlibs method in the Lua source to provide a table with my_hack() inside of it.
Since the Lua interpreter is usually statically compiled into the host executable, modifying the interpreter in some way will probably not be possible.
I think your best bet is to find some piece of Lua code which gets called by the host, and from that file use dofile to run your own code.

Resources