Pages: 1
  Print  
Author Topic: Asynchronous Dialogs/Win32 Threads Implemented  (Read 2454 times)
Offline (Male) Goombert
Posted on: January 29, 2014, 08:13:54 PM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3108

View Profile
I have implemented the Win32 thread functions to allow threading of scripts, this completely does away with the need for Asynchronous events allowing users to properly use cross-platform threading.

This is the pull request I have made.
https://github.com/enigma-dev/enigma-dev/pull/634

Interim documentation is available on this page.
http://enigma-dev.org/docs/Wiki/Game_State_Functions

A basic example is the following.
1) Create a new script called "scr_asynch_message" and add the following code.
Code: (EDL) [Select]
show_message("Hello, world!");2) Create a new object and in the create event add the following code.
Code: (EDL) [Select]
script_thread(scr_asynch_message);3) In the draw event add the following code.
Code: (EDL) [Select]
draw_set_color(c_red);
repeat (50) {
        draw_circle(random(room_width), random(room_height), 5, false);
}
4) Create a new room and place a single instance of this object
5) Run the game

As you can see an asynchronous message dialog will appear while the game continues to randomly draw circles in the background.
« Last Edit: January 30, 2014, 04:49:29 AM by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Male) DaSpirit
Reply #1 Posted on: January 29, 2014, 08:46:22 PM

Member
Location: New York City
Joined: Mar 2013
Posts: 124

View Profile
As awesome as this is, it's not very useful with ENIGMA itself not being thread safe.
Logged
Offline (Male) Goombert
Reply #2 Posted on: January 29, 2014, 08:49:45 PM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3108

View Profile
What do you mean ENIGMA's not thread-safe? It's at least thread-safe for basic functions for now, and asynchronous dialogs.
« Last Edit: January 29, 2014, 09:01:44 PM by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Male) DaSpirit
Reply #3 Posted on: January 29, 2014, 09:11:44 PM

Member
Location: New York City
Joined: Mar 2013
Posts: 124

View Profile
I'm going to assume you don't know what "thread safe" means so I'm going to show you what it means.

Make a script that creates a few objects and run it in a few threads at the same time. Next, check the ids. You'll notice that they overlap. This is because threading is a race and sometimes, this happens (due to the way that you have to get a variable first and then increment it, so that if both get it at the same time, they're both change it to the same value). To make ENIGMA thread safe, every variable either has to be locked by a mutex or use the faster, but less safe atomic type. A mutex essentially locks a bus. To do this, you have to make every variable in ENIGMA use a mutex (or lock instances of classes as whole).
Logged
Offline (Male) Goombert
Reply #4 Posted on: January 29, 2014, 09:22:53 PM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3108

View Profile
You mean mutual exclusion, not important right now since its only used for asynchronous messages atm.
https://en.wikipedia.org/wiki/Mutual_exclusion

I was not aware of that though, so thanks for informing me. However I have to disagree because if somebody has that going on they clearly haven't written their threads correctly. This occured with me when making some plugin changes where the plugin plays red light green light when loading so that it can register the EGM format, start loading the plugin DLL in a thread, and at the same time return to the main LGM thread and start loading the project and then fire a reload performed which propagates back to the plugin when the driver is finished being initialized.

Take a look at the main entry point for the LGM plugin and you'll see.
https://github.com/enigma-dev/lgmplugin/blob/master/org/enigma/EnigmaRunner.java#L201
The fixes to my original version are thanks to TGMG.
« Last Edit: January 29, 2014, 09:34:24 PM by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Male) DaSpirit
Reply #5 Posted on: January 29, 2014, 09:37:25 PM

Member
Location: New York City
Joined: Mar 2013
Posts: 124

View Profile
Quote
However I have to disagree because if somebody has that going on they clearly haven't written their threads correctly.
There is no way to add it correctly as of yet, though. We need mutexes and atomic types (which I don't know how we'd implement without templates in EDL).
Logged
Offline (Male) Goombert
Reply #6 Posted on: January 30, 2014, 05:32:24 AM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3108

View Profile
Not to sound like I am ignoring you we discussed this further on the IRC.

But I want to add to this post I also went ahead and added the asynchronous dialog functions to a new Asynchronous dialog extension. It works perfectly just like Studio and I ran plenty of tests on it. The reason for making it an extension is because of how retarded these functions are and that they rely on other extensions such as data structures as well as threading (though not an extension).

I have partially corrected their stupidity by making the async functions not just return a retarded id but they actually return the index of the thread. Then you can bypass the async dialog event all together and just call thread_get_return(id);

Interim documentation is available on the Wiki.
http://enigma-dev.org/docs/Wiki/Message_Box_Functions
Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Unknown gender) TheExDeus
Reply #7 Posted on: January 30, 2014, 08:03:30 AM

Developer
Joined: Apr 2008
Posts: 1872

View Profile
Quote
As awesome as this is, it's not very useful with ENIGMA itself not being thread safe.
It's just as useful as the GMThreads extension way back for GM. It was used (to great success) to do async loading. Right now every sprite_add, background_add etc. is blocking. What you can do is create a pretty animated loading screen and load them in a thread. You can even load them during gameplay. And there race conditions are hard to do, because you only use the _add functions in that thread. If you also keep tabs on what is loaded and what is not (global.spr_player = -1, then in a thread global.spr_player = spr_add(..)) then you are fine. I have done that before and didn't have any problems. This can also be done to speed up the loading, as you can load many resources in parallel.

And there are many other cases where with sane programming you can get away without using a mutex.

edit: And just for a record - what namespace the threads run in? Can you actually access instance local's and such? Or just globals like GMThreads?
edit2: And is it async to room_speed too? Like an infinite loop in the script will run it as fast as possible (like thousands of times a second and thus create a CPU spike)?
« Last Edit: January 30, 2014, 08:09:09 AM by TheExDeus » Logged
Offline (Male) Goombert
Reply #8 Posted on: January 30, 2014, 08:36:17 AM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3108

View Profile
Quote
This can also be done to speed up the loading, as you can load many resources in parallel.
I have been thinking about that this entire time. Though what got me started on it was video streaming for that new guy who posted yesterday.

Quote
edit: And just for a record - what namespace the threads run in? Can you actually access instance local's and such? Or just globals like GMThreads?
If you can access object locals from a script then yes obviously, but that could lead to the mutex issues DaSpirit and dazappa are complaining about.

Quote
And is it async to room_speed too? Like an infinite loop in the script will run it as fast as possible (like thousands of times a second and thus create a CPU spike)?
Hum, that's a good question, I think I want to say it goes to infinity because only the main thread does the framerate stuff. So nothing is blocking the execution. But there is always sleep()

Just set a global.framerate_rendered = true; everytime the draw event occurs, then check that in your thread.
« Last Edit: January 30, 2014, 08:39:28 AM by Robert B Colton » Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Offline (Unknown gender) Darkstar2
Reply #9 Posted on: January 30, 2014, 01:00:56 PM
Member
Joined: Jan 2014
Posts: 1244

View Profile Email
Very interesting, so with this you can have a loading screen, background music playing and loading of resources in memory at the same time right ?
Logged
Offline (Male) Goombert
Reply #10 Posted on: January 30, 2014, 07:58:23 PM

Developer
Location: Cappuccino, CA
Joined: Jan 2013
Posts: 3108

View Profile
Yeah that is pretty much what this is, the changes are already in the new Windows Portable ZIP.
http://enigma-dev.org/docs/Wiki/Install:Windows
Logged
I think it was Leonardo da Vinci who once said something along the lines of "If you build the robots, they will make games." or something to that effect.

Pages: 1
  Print