Mysterious output from Lua after modifying a control - lua

I am using Lua with wxLua to build a GUI. Normally when I exit the app, I get no output from Lua.
However I just added a function to a wxListView (called myListView) like this
myListView.foo = bar
function bar (self)
-- do something with the wxListView
end
Whether or not I ever called foo(), when I exit the app, I get the following output from Lua:
~wxLuaObject -2 1 0
If I comment out the assignment, I get no output when exiting the app. If instead, I nil out foo later on in the code:
myListView.foo = nil
I get the same output immediately when that line is executed and then again on program exit.
What does the output mean? What am I doing wrong? How do I fix it?
Thanks!

This seems to be an internal diagnostic for the case when wxLuaObject is destroyed and m_reference == LUA_NOREF (-2 as it is in your case) and Lua state object is not in closing state (0 as reported in your case):
// this is from modules/wxlua/src/wxlbind.cpp (starts on line 83 in my version)
wxLuaObject::~wxLuaObject()
{
if ((m_reference != LUA_NOREF) && m_wxlState->Ok() && !m_wxlState->IsClosing())
{
m_wxlState->wxluaR_Unref(m_reference, &wxlua_lreg_refs_key);
m_reference = LUA_NOREF;
}
//else if (!m_wxlState->IsClosing())
// wxPrintf(wxT("~wxLuaObject %d %d %d\n"), (int)m_reference, (int)m_wxlState->Ok(), (int)m_wxlState->IsClosing());
I have this message commented out in my wxlua code (2.8.12.1), but you may want to check your version and upgrade as needed. This is the only place where ~wxLuaObject message appears in the source code. It seems to be harmless, but it can potentially point to other issues with what you are doing.

Related

roblox LUA Expected 'end' (to close 'than' at line 3), got '='

function teleportTo(placeCFrame)
local plyr = game.Players.LocalPlayer;
if plyr.Character then
return plyr.Character.HumanoidRootPart.CFrame = placeCFrame;
end
end
teleportTo(game:GetService("Workspace").game:GetService("Workspace").Zeppelin.FuelTank1.Tank.CFrame)
my code is here, idk much about coding thanks for helping
and if you told me how to make the player teleport to a moving object it would be so super
The error is telling you what is going on.
When the code was being interpreted line by line, it expected the next symbol to be end, but instead it got =.
That means that something about how you're using the equals sign is incorrect. So when we look at the line :
return plyr.Character.HumanoidRootPart.CFrame = placeCFrame
You cannot assign a value on the same line as a return command. return is used to pipe a value out of a function so it can be used where the function was called.
But I'm pretty sure that isn't what you intended, you just want to set a player's position. So to fix your issue, remove the return.
if plyr.Character then
plyr.Character.HumanoidRootPart.CFrame = placeCFrame
end
The reason you are getting an error is because = is usually defined as setting a value, and no code can be executed after a return or it will error
If you wanted to, you could add return after all the code is done executing

How to determine if sysdig field exists or handle error if it doesn't

I'm using Sysdig to capture some events and have a small chisel (LUA script) to capture and format the events as necessary. On the on_init() I'm requesting fields like so :
f_field = chisel.request_field("<field>")
My question is how can I check if a field exists before requesting it? I'm going to use a new field only just released on 0.24.1 but ideally I'd like my chisel to continue to work on older versions of sysdig without this field. I've tried wrapping the call to chisel.request_field in a pcall() like so :
ok, f_field = pcall(chisel.request_field("<field>"))
and even implementing my own "get_field" function :
function get_field(field)
ok, f = pcall(chisel.request_field(field))
if ok then return f else return nil end
end
f_field = get_field("<field>")
if f_field ~= nil then
-- do something
end
but the error ("chisel requesting nonexistent field <field>") persists.
I can't see a way to check if a field exists but I can't seem to handle the error either. I really don't want multiple versions of my scripts if possible.
Thanks
Steve H
You're almost there. Your issue is in how you're using pcall. Pcall takes a function value and any arguments you wish to call that function with. In your example you're passing the result of the request_field function call to pcall. Try this instead..
ok, f = pcall(chisel.request_field, "field")
pcall will call the chisel method with your args in a protected mode and catch any subsequent errors.

How can I reset ESP8266 MicroPython after main.py crashes?

I have a NodeMCU ESP8266 board running MicroPython. I'm running a web server on my ESP8266. This is my first IoT project based on one of these boards.
The below is a snippet of the code.
This is being executed within main.py. Every now and then, something causes the code to crash (perhaps timing and request based). When main.py exits, for whatever reason, I'm dropped back at the python CLI.
I'd like for the board to reset when this happens (if there isn't a better way).
What is the best method of restarting/reseting the ESP8266?
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(5)
print('listening on', addr)
while True:
cl, addr = s.accept()
print('client connected from', addr)
cl_file = cl.makefile('rwb', 0)
print("Request:")
while True:
line = cl_file.readline()
print("Line:" , line)
if not line or line == b'\r\n':
print("breaking")
break
if line == b'GET /active HTTP/1.1\r\n':
MicroPython has machine.reset() function to reset a board.
Python (not just MicroPython) uses exception handling to handle errors.
Combining the two, you can easily achieve what you want. For example:
a = 4
b = 2
try:
a / b
except:
machine.reset()
If in the code above you replace value of b with 0, your board will reset. If you think about it for a bit, you probably will find out that it doesn't make much sense - you don't want your board suddenly reset if you just divide by 0 by mistake or otherwise. There're got to be better ways to handle errors! Likewise, you may want to think about your own case and see if resetting the board is really the best choice. If you think that yes, that's fine, just always keep in mind that you programmed your board to suddenly reset. Otherwise, your next question here may be "My board suddenly resets! Why???" ;-)
It may be late for the original question, but the answer I am going to share might help other people. Consider it is not a final solution, but in many scenarios, it may save a day. You can explore your case.
The solution is using the internal scheduling function of MicroPython. since its execution is guaranteed, then its behavior can be used as a tool to mimic a functional watchdog.
Following code will run with given timers and threshold which can be customized in your case, and if the timer reaches its threshold, and the value of wd_buffer is not updated for that time, then the function might be called, and we repeat the process again.
So in order to prevent the ESP getting restarted in this case after 12 sec, you have to in someplace in your code, periodically (shorter than 12 sec or adjust the timer and threshold according to your need) update the value of the Global wd_buffer variable. Hope it helps.
# Simple WD - Global Variable
wd_feeder = 0
wd_buffer = 0
wd_counter = 0
wd_threshold = 4
def wd_checker(calledvalue):
print('watchdog is checking... feeder= {} buffer= {}'.format(wd_feeder, wd_buffer))
global wd_counter
global wd_buffer
global wd_feeder
if wd_feeder == wd_buffer:
print('state is suspicious ... counter is {} incrementing the counter'.format(wd_counter))
wd_counter += 1
else:
wd_counter = 0
wd_feeder = wd_buffer
if wd_counter == wd_threshold:
print('Counter is reached its threshold, following function will be called')
wd_feeder = wd_buffer = wd_counter = 0
machine.reset()
if __name__ == '__main__':
scheduler_wd = machine.Timer(-1)
scheduler_wd.init(period=3000, mode=machine.Timer.PERIODIC, callback=wd_checker)
you could add a while loop checking for the Flash Button (GPIO pin 0) like this:
import machine
pin = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
while pin.value():
print('Put your code here...')
print('..this will looping until the Flash button is pressed...')
print('...and then it continues here.')
You could execute your code (which should be outside of the main.py -> other file) from the boot or the main.py. if it drops out it should execute the following code, which could trigger a reset.
You may have to catch the error first.
I hope I helped

readByteSync - is this behavior correct?

stdin.readByteSync has recently been added to Dart.
Using stdin.readByteSync for data entry, I am attempting to allow a default value and if an entry is made by the operator, to clear the default value. If no entry is made and just enter is pressed, then the default is used.
What appears to be happening however is that no terminal output is sent to the terminal until a newline character is entered. Therefore when I do a print() or a stdout.write(), it is delayed until newline is entered.
Therefore, when operator enters first character to override default, the default is not cleared. IE. The default is "abc", data entered is "xx", however "xxc" is showing on screen after entry of "xx". The "problem" appears to be that no "writes" to the terminal are sent until newline is entered.
While I can find an alternative way of doing this, I would like to know if this is the way readByteSync should or must work. If so, I’ll find an alternative way of doing what I want.
// Example program //
import 'dart:io';
void main () {
int iInput;
List<int> lCharCodes = [];
print(""); print("");
String sDefault = "abc";
stdout.write ("Enter data : $sDefault\b\b\b");
while (iInput != 10) { // wait for newline
iInput = stdin.readByteSync();
if (iInput == 8 && lCharCodes.length > 0) { // bs
lCharCodes.removeLast();
} else if (iInput > 31) { // ascii printable char
lCharCodes.add(iInput);
if (lCharCodes.length == 1)
stdout.write (" \b\b\b\b chars cleared"); // clear line
print ("\nlCharCodes length = ${lCharCodes.length}");
}
}
print ("\nData entered = ${new String.fromCharCodes(lCharCodes).trim()}");
}
Results on Command screen are :
c:\Users\Brian\dart-dev1\test\bin>dart testsync001.dart
Enter data : xxc
chars cleared
lCharCodes length = 1
lCharCodes length = 2
Data entered = xx
c:\Users\Brian\dart-dev1\test\bin>
I recently added stdin.readByteSync and readLineSync, to easier create small scrips reading the stdin. However, two things are still missing, for this to be feature-complete.
1) Line mode vs Raw mode. This is basically what you are asking for, a way to get a char as soon as it's printed.
2) Echo on/off. This mode is useful for e.g. typing in passwords, so you can disable the default echo of the characters.
I hope to be able to implement and land these features rather soon.
You can star this bug to track the development of it!
This is common behavior for consoles. Try to flush the output with stdout.flush().
Edit: my mistake. I looked at a very old revision (dartlang-test). The current API does not provide any means to flush stdout. Feel free to file a bug.

Control flow in Lua

I have a problem which i suppose must be very common and most of you would have faced it.
I have written a program in lua, say main.lua which on receiving key event should modify the coordinates and display the geometry figure.
This lua code calls reg.c, where it kind of registers.
Now in reg.c i have a function engine which receives the key pressed and passes it to the lua function responsible for key handling.
But by the time key event comes, lua code is done with the registration and exits, thus the call from engine() becomes illegal memory access leading to segmentation fault.
Also i suppose we can't have lua call hanging in reg function, and call engine function from somewhere else.
Then what should be the solution, please guide me through this.
#jacob: here is the prototype of what i am trying to achieve:
function key_handler() //this function will get the latest key pressed from some other function
{
draw.image();
draw.geometry();
...
...
while(1)
{
//draw Points until some condition goes wrong
}
}
Now, once entered into key_handler, while he is busy drawing the points unless and until the failing condition occurs, i am unable to receive key pressed till that time.
I hope this explanation is much simpler and have made my point, and will help others to understand the problem.
I am really sorry, but i am not good at expressing or making others understand.
One more thing, i ahve followed the C syntax to explain, however this is completely implemented in lua
Your code snippet is still largely non-informative (ideally one should be able to just run your code in a stock Lua interpreter and see your problem). If you're describing a Lua problem, use Lua code to describe it.
However I'm beginning to see where you want to go.
The thing you need to could do is have a coroutine that's called in your key handler, which passes an argument back to your handler:
function isContinue() --just to simulate whatever function you use getting keypresses.
-- in whatever framework you're using there will probably be a function key_pressed or the like.
print('Initialize checking function')
while true do
print('Continue looping?')
local ans = io.read():match('[yY]')
local action
if not ans then
print('Do what instead?')
action = io.read()
if action:match('kill') then -- abort keychecker.
break
end
end
coroutine.yield(ans,action)
end
print('finalizing isContinue')
return nil,'STOP' -- important to tell key_handler to quit too, else it'll be calling a dead coroutine.
end
function key_handler()
local coro = coroutine.create(isContinue)
local stat,cont,action
while true do
print'Draw point'
stat,cont,action = coroutine.resume(coro)
if not stat then
print('Coroutine errored:',cont)
elseif not cont then
print('isContinue interrupted keyhandler')
print("We'll "..action.." instead.")
break
end
end
print('finalizing key_handler')
end
key_handler()
-- type something containing y or Y to continue, all else aborts.
-- when aborting, you get asked what to do instead of continuing,
--- with "kill" being a special case.
This should be self explanatory. You should probably take a good look at Programming in Lua, chapter 9: Coroutines.
The big difficulty (well, if you're not accustomed to collaborative threading) is that a coroutine should yield itself: it's not the calling function that's in charge of returning control.
Hope this helps you.

Resources