Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


thread vs function, sync & co

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 87

PostPosted: Sat Mar 16, 2024 5:25 pm    Post subject: thread vs function, sync & co Reply with quote

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
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 147

Joined: 06 Jul 2014
Posts: 4518

PostPosted: Sat Mar 16, 2024 8:17 pm    Post subject: This post has 1 review(s) Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 465

Joined: 09 May 2003
Posts: 25509
Location: The netherlands

PostPosted: Sat Mar 16, 2024 9:12 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 87

PostPosted: Sun Mar 17, 2024 2:26 am    Post subject: Reply with quote

Thanks, that clarifies some other questions I had! (and 4. yeah how could I miss that Embarassed). 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
View user's profile Send private message
AylinCE
Grandmaster Cheater Supreme
Reputation: 34

Joined: 16 Feb 2017
Posts: 1418

PostPosted: Sun Mar 17, 2024 5:16 am    Post subject: Reply with quote

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()

_________________
Hi Hitler Different Trainer forms for you!
https://forum.cheatengine.org/viewtopic.php?t=619279
Enthusiastic people: Always one step ahead
Do not underestimate me Master: You were a beginner in the past
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
salumor
Advanced Cheater
Reputation: 0

Joined: 14 Jan 2019
Posts: 87

PostPosted: Sun Mar 17, 2024 7:08 am    Post subject: Reply with quote

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
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 465

Joined: 09 May 2003
Posts: 25509
Location: The netherlands

PostPosted: Sun Mar 17, 2024 12:01 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites