|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
salumor Advanced Cheater Reputation: 0
Joined: 14 Jan 2019 Posts: 87
|
Posted: Sat Mar 16, 2024 5:25 pm Post subject: thread vs function, sync & co |
|
|
Hey guys, so i've got these questions on the following test-code
1.a) Why does testfunc disrupt the thread?
1.b) Do I need to put both in threads or would there be any other solution?
2.) What's the difference createThread vs. createNativeThread (couldnt find anything on it)
3.) When exactly to use synchronize
4.) synchronize(messageDialog)) does not seem to work, is it already snycr. or why? (note: yeah in this case its not in a (sub) "thread" but on other tests where this was the case it was behaving identically)
Code: | local testthread = function(th)
th.freeOnTerminate(true)
for i=1,100 do
if th.Terminated then return end
synchronize(print,i) --doesnt matter with sync/wo
sleep(1000)
end
end
local function testfunc()
local v1 = synchronize(messageDialog('v1',mtConfirmation, mbYes, mbNo)) --this doesnt provide a proper return value
local v2 = messageDialog('v2',mtConfirmation, mbYes, mbNo) --this works as intended
for i=1,3 do --just 3 steps, no need to cancle
print(tostring(v1),v2)
i=i+1
sleep(1000)
end
end
nt = createThread(testthread) --createNativeThread
testfunc() -- once the loop starts this interrups the other thread
--nt.terminate() |
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 147
Joined: 06 Jul 2014 Posts: 4518
|
Posted: Sat Mar 16, 2024 8:17 pm Post subject: |
|
|
1 - Don't sleep in the main thread and try to access the GUI at the same time. Weird things will happen. In fact, just never sleep in the main thread at all.
If you think you need to call the `sleep` function from the main thread, use a timer instead. Timers are asynchronous and won't block.
2 - `createNativeThread` and `createThread` are the same thing. I guess `createNativeThread` is just an old name that's kept around for backwards compatibility.
3 - Use `synchronize` when you want the main thread to run some piece of code- e.g. when accessing the GUI. IIRC `print` is an exception. Everything else- forms, address list, memory records, dialogs, timers, etc.- must be accessed only by the main thread.
4 - `synchronize` takes a function. `messageDialog` returns a value, not a function.
Code: | synchronize(messageDialog('v1',mtConfirmation, mbYes, mbNo))
-- if the call to `messageDialog` returns 6 (`mrYes`), this is the same thing as:
synchronize(6)
-- you probably meant:
synchronize(function()
return messageDialog('v1',mtConfirmation, mbYes, mbNo)
end)
-- or:
synchronize(messageDialog, 'v1', mtConfirmation, mbYes, mbNo) |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 465
Joined: 09 May 2003 Posts: 25509 Location: The netherlands
|
Posted: Sat Mar 16, 2024 9:12 pm Post subject: |
|
|
synchronize can access 'upvalues' if it's a local function
e.g;
Code: |
local r
local msg='some text unique to this thread'
synchronize(function()
r=messageDialog(msg,mtConfirmation, mbYes, mbNo)
end)
printf("from thread: r=%d",r)
|
next version CE will force kill scripts that access GUI controls from a thread and explain why
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
salumor Advanced Cheater Reputation: 0
Joined: 14 Jan 2019 Posts: 87
|
Posted: Sun Mar 17, 2024 2:26 am Post subject: |
|
|
Thanks, that clarifies some other questions I had! (and 4. yeah how could I miss that ). Additional questions
I actually wanted at some point to call testfunc() from the thread because it shall be executed after testthread() does its thing. Then I thought about them doing things individually, just wait till it happened.
? 1.a) Do I need to make the function global? Or would there be other/better ways? (also for nt I guess)
? 1.b) Is calling from the thread the preferred solution (because I dont need to wait in testfunc()) or any downsizes/additional thoughts?
✓ 1.c) Setting a value to be able to terminate on a synchronized thread-start done (but check 1.a)?
? 1.d) I have another testfunc2() - that again needs to be run after testfunc(). Do I always have to do nested calls once I start with threads? There is waitfor() but I don't see how to use it in this case.
✓ 2.) So synchronize(print,i) is not needed? Not even recommended? Or even some downside?
✓ 2.b) @DB Will that also be true when "next version CE force kills scripts that access GUI controls from a thread"
Code: | local testthread = function(th)
--th.freeOnTerminate(true)
for i=1,10 do
if th.Terminated then return end
print(i) --2.)/2.b) no synchronize?
if i==2 then
--[[synchronize(function()
tf=createThread(testfunc)
end)]]
tf = synchronize(createThread,testfunc) --1.b) call either from testthread --1.c) solved
print(tostring(tf))
--synchronize(testfunc2()) --1.d) wont help, createThread seems to take too long
end
sleep(1000)
end
end
function testfunc(th) --1.a) make it global?
--th.freeOnTerminate(true) --1.c) solved
local v1 = synchronize(messageDialog, 'v1', mtConfirmation, mbYes, mbNo)
local v2 = messageDialog('v2',mtConfirmation, mbYes, mbNo)
for i=1,3 do --1.b) code will depend on where to be called from, if from testthread sleep might not be neeed
if th.Terminated then return end
print(tostring(v1),v2)
i=i+1
sleep(1000)
end
synchronize(testfunc2())
return
end
function testfunc2() --1.a) make it global?
print("I dont sleep but shall be executed after testfunc(). Note: testthread() may or may not still be running.")
end
tf = {}
nt = createThread(testthread) --1.a) any way to make that local too and nt.terminate() to always work no matter where executed?
--tf = createThread(testfunc) --1.b) or from main thread independently
--not sure yet if I'll use a thread or timer but for simplicity ..
--tf.waitfor() --1.d) useless here or anywhere cause here the thread doesnt exist, in testthread it would only block, and dont use it in testfunc
--testfunc2() --1.d) how to execute after testfunc()
--nt.terminate()
--tf.terminate()
|
Last edited by salumor on Sun Mar 17, 2024 3:42 pm; edited 4 times in total |
|
Back to top |
|
|
AylinCE Grandmaster Cheater Supreme Reputation: 34
Joined: 16 Feb 2017 Posts: 1418
|
Posted: Sun Mar 17, 2024 5:16 am Post subject: |
|
|
Just to give options other than "synchronized" and "thread":
There is an example that when "no" is selected in v1, it ignores v2 and jumps to v3 or stops counting with "return".
Additionally, there is function ownership within the script without observing the order.
Code: | tblfunc = {}
msg = function(s)
r=messageDialog(s,mtConfirmation, mbYes, mbNo)
return r
end
tblfunc.func = function(s) return s() end
function testfunc()
a=1
v1=0
v2=0
v3=0
for i=1,6 do
if a==2 then
v1 = msg('v1')
end -- stop i=3
if a==3 then
if v1==7 then
print("no v1: "..tostring(v1).." a: "..a)
--v2 = msg('v2') --return (stop senc) or not v2 (jump: v3=msg('v3') a=5 )
--tblfunc[1](v1)
v3=msg('v3') a=5
tblfunc[1](v1,"v1")
--return
else
print("yes v1: "..tostring(v1).." a: "..a)
v2 = msg('v2')
--tblfunc[1](v1)
tblfunc[1](v1,"v1")
end
end -- stop i=2
if a==4 then
if v2==7 then
print("no v2: "..v2.." a: "..a)
v3 = msg('v3')
--tblfunc[2](v2)
tblfunc[1](v2,"v2")
else
print("yes v2: "..v2.." a: "..a)
v3 = msg('v3')
--tblfunc[2](v2)
tblfunc[1](v2,"v2")
end
end -- stop i=3
if a==5 then
if v3==7 then
print("no v3: "..v3.." a: "..a)
--tblfunc[3](v3)
tblfunc[1](v3,"v3")
else
print("yes v3: "..v3.." a: "..a)
--tblfunc[3](v3)
tblfunc[1](v3,"v3")
end
end -- stop i=4
if a~=3 and a~=4 and a~=5 then print("a: "..a) if a==6 then return end end
a = tonumber(a) + 1
sleep(1000)
end
end
function v_1(s1,s2) if s1==6 then print(s2.." start!") else print(s2.." stop!") end end
--function v_2(s) if s==6 then print("v2 start!") else print("v2 stop!") end end
--function v_3(s) if s==6 then print("v3 start!") else print("v3 stop!") end end
tblfunc[1] = v_1
--tblfunc[2] = v_2
--tblfunc[3] = v_3
testfunc()
|
_________________
|
|
Back to top |
|
|
salumor Advanced Cheater Reputation: 0
Joined: 14 Jan 2019 Posts: 87
|
Posted: Sun Mar 17, 2024 7:08 am Post subject: |
|
|
Thanks. I need thread because it should be running -not infinate but "can" run- for a longer time and the 1 Dialog I am using is actually in there. Just when testing out why/preparing question it turned the way its now.
Also I did pass on arguments (thus thread, not timer - didnt like tags), but those did go the path everything alive take finally. Still I like thread because it does match the idea whats happening more (on testthread).
But yeah, it may helps others.
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 465
Joined: 09 May 2003 Posts: 25509 Location: The netherlands
|
Posted: Sun Mar 17, 2024 12:01 pm Post subject: |
|
|
freeOnTerminate is true on new threads so you can skip those
and print/printf is safe to use in any situation
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|