Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / [Tier 2]Using Sync() to wait for something is a problem

Author
Message
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 25th Jul 2012 20:04
In Tier 1 I have no problem with the following type of code:


I use something similar all over to display stuff and wait for the user to press the button (or something else).

But when I do the same thing in Tier 2, in hangs completely in Windows (at least):


(Using '!' instead of comparing to zero is the same thing in C++ because zero equates to false.)

This is the complete code to test (excluding headers and things, based on sample from another post):


Is there something I should be doing differently for the same effect (keep the code basically in one place until the trigger event happens and let the user do things like enter data in an editbox)?

Cheers,
Ancient Lady
AGK Community Tester
Pilz X Schizo
17
Years of Service
User Offline
Joined: 21st Mar 2007
Location: Massachusetts, USA
Posted: 25th Jul 2012 20:27 Edited at: 25th Jul 2012 20:39
Hey Ancient Lady, just tried adding a while loop with just a sync statement into my program, causes it to hang here as well. Very odd behavior indeed. My guess at the moment is that it has something to do with stopping App.Loop() from running.


EDIT:

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 25th Jul 2012 20:47
It happens no matter what you put in the while loop.

This is my most recent test:


The loop executes, but the app does not respond to any other events while it is executing.

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 25th Jul 2012 20:52
Suggest putting a state machine variable and handling events inside the main loop with a switch statement instead of having an interior while statement.

-- Jim
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 25th Jul 2012 21:05
I would like to do that. But something as simple as putting up a message and waiting for the button click is very annoying to put into the existing game state machine (aka switch/case).

Sorta easyish to do for message boxes that are 'in line' with the game execution. But not so with some things that just happen once, during setup before the main loop happens.

AGK doesn't wait for the input to be finished for either the TextInput or EditBox functions.

So, if I want the program to wait until the input is done (indicated by clicking on the 'button'), it would require some very sophisticated sets of states.

The first place it pops up is while waiting for the game player to enter their name. Then it goes on to try to register the name on the game server. If the name is already in use, the user gets a message telling them that and asking if it is them (showing the games currently registered for) and letting them say 'yes' and finish the registration or 'no' and go back to enter another name. It is a nice simple set of while statements that would be a royal pain to turn into a state machine.

Quite annoying.

Especially when the same Tier 1 code works without any problems at all.

Cheers,
Ancient Lady
AGK Community Tester
Pilz X Schizo
17
Years of Service
User Offline
Joined: 21st Mar 2007
Location: Massachusetts, USA
Posted: 25th Jul 2012 21:20
I have to agree that this is very inconvienent. We need a command similar to DoEvents() to allow app::Loop to do whatever it is doing behind the scenes as that seems to be the problem with while().
BatVink
Moderator
21
Years of Service
User Offline
Joined: 4th Apr 2003
Location: Gods own County, UK
Posted: 25th Jul 2012 22:30
I'm not a C++ coder, but are you able to put in some sort of sleep method? Maybe it would be enough for other threads to get a word in (or at least a byte )

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 25th Jul 2012 22:53
I tried sleep, but it didn't work. The sleep command relinquishes control to processes other than the app. Unfortunately, the app itself is what is checking for clicks and other interactions with the app interface. So, sleep doesn't work.

Like I said, it works fine in Tier 1, but the setup for Tier 2 apparently only does process checks before/after the call to app::Loop (the main processing function for the app class).

I tried looking for any public functions in the AppGameKit header files that might allow touch update/detection. But the only one in ctouch.h, cTouch::UpdateEvents() still hung the app if used in a while loop.

The call(s) I need are probably buried in the core AppGameKit libraries.

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 25th Jul 2012 22:58
I suspect the Basic interpreter may have an input check built into its runtime system. Paul or Lee could shed some light on this.

Without beating the same old drum, this is where the TAGKScene system in the Pascal works beautifully - here you would merely switch scenes for the input stuff - so it can in fact be a very complex state machine handled effortlessly.

-- Jim
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 25th Jul 2012 23:16
JimHawkins, I will eventually try Pascal. But I am currently working on translating my Tier 1 into Tier 2 and am not ready to try completely changing what already works.

As it is, I'm going to have to create work arounds for this issue until/unless the AppGameKit developers come up with a solution.

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 26th Jul 2012 00:32
Hi Ancient One - hope you had a good vacation. I've just got back from two wonderful weeks on Corfu!!

There isn't really a vast difference between the Pascal and C++ since the actual AppGameKit function calls are the same, but you don't need AGK:: in front of them. The advantage of Erik van Bilsen's excellent scene system is that a "scene" (like a focussed Form on Windows) handles its own input and you don't have to manage unusual states in nasty "while" etc statements inside the main application loop, which is what's causing grief here!

I totally understand you wanting to stay with the port from T1 to T2. But I couldn't help but point out a potential "get out of jail free" card.

-- Jim
Hodgey
14
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 26th Jul 2012 00:33
Obese is correct, it has to do with holding up the app::Loop method but I agree this is an inconvenience.

JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 26th Jul 2012 01:05
Hodgey - yes it seems as though the input checks are done at the end of the app::Loop() method, so they will never get through to anything in a subordinate while {..} loop.

-- Jim
erebusman
12
Years of Service
User Offline
Joined: 23rd Jul 2011
Location: Sacramento, CA
Posted: 26th Jul 2012 02:35 Edited at: 26th Jul 2012 02:53
I ran into the same problem with a while loop in T2 and confirmed it with this thread
http://forum.thegamecreators.com/?m=forum_view&t=188206&b=41

My thread here:

http://forum.thegamecreators.com/?m=forum_view&t=198272&b=43&msg=2369804#m2369804

I have been able to work around it...I just have to rethink everything as to "how can I accomplish this inline the app loop?"

It's making for messy code and I have to use loads of flags where I might otherwise use a while loop but I'm getting it done.

It's bad enough that it makes me wonder if I shouldn't be coding native code rather than AppGameKit as I do have a Mac... But I have not given up on AppGameKit yet.

EDIT: If you want an example of how I use flags rather than loops let me know I'll post one.
Hodgey
14
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 26th Jul 2012 02:59 Edited at: 26th Jul 2012 03:08
Ok, I seem to have found a way to use while loops inside the app::Loop() function (yes with sync() ) but, there are a few trade-offs. The first being that there's a condition you must include in the while loops and the second is that I haven't looked into making this cross platform (but in theory, it should be achievable).

Here's how it's done. Towards the end of the core.cpp in the int APIENTRY _tWinMain() function look for this:


Make bExitLoop a global (move the declaration to the top of the core.cpp and place it after the namespace. Remember to remove its local declaration). Then study this (template.cpp):

The update() must be a condition of the while loop (so it can exit if necessary and run the message pump).

Edit I should say that you can copy the update() function straight into your program.

Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 26th Jul 2012 03:02
This isn't really an issue per se, it's just a reality of dealing with a lower-level language where you have to control all of the little things. It'll generate some ugly code for sure, but that's the nature of the beast. It really isn't that complicated to create a simple flag to check for a specific action, you can even design a specific class to handle the storage of those flags and the required conditions.

By the way(I don't have AppGameKit to test this right now), is there a way to make App::Loop() a purely updating function that can be called at any time? In other words, making App::Loop() a delegate function made just to update AppGameKit while all the data manipulation is such is done in another function.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 26th Jul 2012 17:26
Hodgey, in Xcode, it is the drawView function in UntitledViewController.m that calls App.Loop, but it doesn't do any other processing.

For Android, it is still in Core.cpp, in the loop function (and it doesn't do any other processing other than orientation check/set).

I haven't tested the issue on the Mac/iOS yet. And my Android setup is busted because my Android device won't communicate anymore (physical interface is broken).

I think I'll be able to add a method to the template app class to handle messages similar to what you (Hodgey) just suggested. It will use #ifdefs to use the correct code to either handle windows messages or do nothing as appropriate. I'll post it if it works.

Dar13, I don't think I consider C++ a lower-level language. And, when a program gets complex enough, simple flags don't really work.

app::Loop() is the 'main' execution method. The issue is getting the platform to recognize actions (mouse clicks, keyboard, etc.) at all times. After looking at the platform specific code, it appears that Windows is the only one that has an issue.

If I had started from scratch, it wouldn't be so bad. But I am converting my Tier 1 app and am trying to avoid rewriting too much. I have turned some things into classes (like the file management and error handling functions) wherever it is easier. And, doing all my string handling without using AppGameKit functions (which is what I believe was causing my issues in Tier 1).

Cheers,
Ancient Lady
AGK Community Tester
Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 26th Jul 2012 20:07
Quote: "The issue is getting the platform to recognize actions (mouse clicks, keyboard, etc.) at all times. After looking at the platform specific code, it appears that Windows is the only one that has an issue."

The only way I've ever seen that done is through a constantly updating background thread or integration into the runtime(which AppGameKit Tier 1 seemingly does).

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 26th Jul 2012 21:59
The way Tier 2 is set up, we don't have the same control as for Tier 1 in some things. And getting the app to recognize events is one of them.

I also discovered that putting even one agk::Sync() command in the app::Begin() method will totally hang on an iPad (but not on the iPod).

I'm doing workarounds for the whole thing and hope that AppGameKit will come up with something that lets us have just that little bit more control (for syncing) that Tier 1 has.

My test to see if I could 'catch' the windows events manually, did not seem to work. It looks like the core (not core.cpp) agk stuff does some handling to apply events so things like GetPointerPressed returns something.

Cheers,
Ancient Lady
AGK Community Tester
Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 27th Jul 2012 02:49
Quote: "The way Tier 2 is set up, we don't have the same control as for Tier 1 in some things."

That seems counter-intuitive. I'm going to have to rethink about getting AppGameKit now, because I would only get it for Tier 2 and that's assuming that Tier 2 would be more powerful and flexible than Tier 1.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 27th Jul 2012 05:31
The one thing that I know that you cannot do in Tier 2 (that caused this thread) is use the agk::Sync() command anywhere but at the end of the agk::Loop() method. Doing so causes the app to hang and have strange behavior.

Other than that, Tier 2 is much more powerful. You have all of the string functions and classes so that you can avoid using the AppGameKit string functions (which I think was what was causing me problems, allocation and deallocation of things in garbage cleanup wasn't happening smoothly in my Tier 1 app). And you can do proper OOPing.

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 27th Jul 2012 08:54
@Dar13 - I agree with Ancient Lady. This is a very exceptional case, with a tight sub-loop inside the main loop. In general, as long as you avoid platform-specific code, you can use the full facilities offered by C++ or Object Pascal - which are vast.

You can also eliminate some of the poorer features of Basic - such as over-reliance on globals, and use things like call by reference, inheritance and so on.

-- Jim
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 14th Aug 2012 16:08
In tier 2 your app must return regularly from App::Loop() to allow the system to check for input and messages, since everything is on the same thread. As you discovered you can bring the message loop into the App::Loop() function to work around it, and on Windows I don't see any problem with this. However mobile devices probably won't be as easy as blocking in App::Loop() is likely to make the app look unresponsive and get closed.

In tier 1 we loop over the bytecode commands in App::Loop() until a sync is reached or a large amount of time has passed, at which point we leave Loop() to let the system do its thing then when Loop() gets called again we pick up at the next bytecode instruction to continue the tier 1 app.
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 14th Aug 2012 16:41
What we need is a Tier 2 command that lets us 'trigger' the checks for inputs and messages.

Paul, is there any possibility of a command like that? I'll be happy to put it in as a request in the Google list if it is possible.

Cheers,
Ancient Lady
AGK Community Tester
Paul Johnston
TGC Developer
21
Years of Service
User Offline
Joined: 16th Nov 2002
Location: United Kingdom
Posted: 14th Aug 2012 21:11
Unfortunately I don't know of a way. On iOS at least the Loop() function is called from a callback which must return for the system to progress, which means Loop() must return, which means the next call to Loop() will start at the beginning again.
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 14th Aug 2012 22:10
Oh well.

I've been working around it fairly well. It just means creating a variety of state engines (the main program loop and sub-'loops' in separate classes/fils for specific tasks that have many steps to complete).

I'm actually working on the last function in my WIP game. I finished the Tier 1 to Tier 2 conversion, added the 'Scores' page and am now finishing the 'How to Play' page.

After that, it's just a matter of making the maps for each level/field (and the icons, app store images and store text) and I'll be ready to publish (very excited about this!).

Cheers,
Ancient Lady
AGK Community Tester
JimHawkins
14
Years of Service
User Offline
Joined: 26th Jul 2009
Location: Hull - UK
Posted: 15th Aug 2012 00:29
Looking forward to it! Very best of luck!

-- Jim
Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 21st Aug 2012 20:17
I just discovered something interesting.

You can use agk::Sync() in places other than the main app::loop() method.

It works as long as all you are doing is updating the display and not trying to get any inputs from anywhere.

You can reposition things and change colors/alpha and the agk::Sync() command works!

Physics events still work. But not anything that needs to check the status of the device/keyboard/internet/etc. Things that need to be interpreted from the environment don't work.

But you can do simple loops and play sounds and move things!

This is a good thing.

It still doesn't fix my original problem, but it is nice to know.

Cheers,
Ancient Lady
AGK Community Tester
Hodgey
14
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 22nd Aug 2012 13:06
Quote: "It works as long as all you are doing is updating the display and not trying to get any inputs from anywhere."

Could you provide an example when the sync() doesn't work outside of app::Loop()? Is it specific to Windows?

Quote: "I'll be ready to publish (very excited about this!)."

Congratulations! I look forward to seeing it on the appstores.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 22nd Aug 2012 16:27
It is not specific to Windows.

This is the code I found yesterday while trying to track something down:


The call to moving_things::do_moving() causes several other sprites to move, rotate, shrink and fade.

You can also see that it plays two different sounds (they overlap)

I had converted a Tier 1 app to Tier 2 and some things got turned into nice classes and others are still \'straight\' code.


I have 99.999% of the code done. Now I need to make all the fields.

I have the app integrated so that the user can store game results on the game server and retrieve results from their or locally. The local file stores all games played (win or lose).

I need to create a leader board and have just started the site code for that, then it will be integrated with the game.

I hope to have it published by the end of October (we are off on holiday for a couple of weeks between now and then).

You can get some clues about the game from the site (with the yet to be finished scores page): http://www.triassicgames.com

Cheers,
Ancient Lady
AGK Community Tester
Hodgey
14
Years of Service
User Offline
Joined: 10th Oct 2009
Location: Australia
Posted: 24th Aug 2012 11:02
Quote: "This is the code I found yesterday while trying to track something down:"

More while loops. Just out of curiosity, what happens if you replace the agk::sync() with agk::update(0.0) ? Or does it need to render each iteration?

Quote: "You can get some clues about the game from the site (with the yet to be finished scores page):"

I had a quick browse and it looks like a fascinating game. You get points for originality.

Ancient Lady
Valued Member
20
Years of Service
User Offline
Joined: 17th Mar 2004
Location: Anchorage, Alaska, USA
Posted: 24th Aug 2012 15:50
Quote: "what happens if you replace the agk::sync() with agk::update(0.0)"

I tried it and it had the same effect as if the entire while loop never happened. I think all the elements of the Sync() are needed.

Quote: "You get points for originality."

Thank you. My husband and I are hoping that what I'm doing (the way the game plays) is unique enough to make us some big bucks.

Cheers,
Ancient Lady
AGK Community Tester

Login to post a reply

Server time is: 2024-05-02 13:43:16
Your offset time is: 2024-05-02 13:43:16