Re: Blocking for input during a loop?

2010-01-20 Thread Michael Ash
On Tue, Jan 19, 2010 at 1:16 PM, Jens Alfke j...@mooseyard.com wrote:

 On Jan 19, 2010, at 6:10 AM, Per Bull Holmen wrote:

 I have made one class called GameController, which is overridden by
 subclasses to control one specific type of game (PS: I will soon rename the
 class Controller to MainController, and instance variable controller
 to mainController). The GameController base class also mediates between
 input from the main thread, and the game thread, with help from the class
 InputBuffer:

 You've basically implemented coroutines, actually a simple form of an actor,
 using multiple threads. Each coroutine is running an event loop, and the
 game one blocks waiting for incoming events from the UI one.

 (Ideally it's possible to implement this without using multiple threads; I
 tried to do that about two years ago using the low-level ucontext library,
 but it turns out that the stack manipulation it does is incompatible with
 Objective-C's exception handling system.)

You might be interested in my MAGenerator code:

http://www.mikeash.com/svn/MAGenerator/

While generators aren't exactly coroutines, they're equivalently
capable (you just need to create a dispatcher to switch between
different active generators). Of course it's a hack, but I'd say much
less of one than low-level stack manipulation, and all the hack is at
the level of syntax.

For this particular case, MAGenerator would allow you to write the
game code in straightforward top-to-bottom code, while still yielding
control to the event loop. Your event responders would invoke the
generator with whatever the user action was, and control would resume
in the generator where it left off. The HTTPParser example in
GeneratorTests.m illustrates this approach, albeit for a very
different purpose.

Mike
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-19 Thread Ben Haller

On 18-Jan-10, at 9:29 PM, Per Bull Holmen wrote:

...Again, I have clearly not explained what I wanted to do properly.  
No, I did not want what you describe. I have done it now, I chose to  
use threads, and it got far cleaner than the standard Cocoa way.  
No, I don't have to handle any other input than what's relevant for  
the game, Cocoa handles the rest, thank you... :)


  Perhaps you could post your solution, for the edification of the  
list?


I really appreciate your replies! I must have explained it poorly...  
anyway if someone still want to convince me I'm doing things the  
wrong way, then I'm guessing either they are so in love with MVC  
they have lost their sense of reality, or they still haven't  
understood what I'm trying to explain... :)


  Or perhaps, once you post your solution, someone will point out a  
problem with it that you haven't foreseen?


Ben Haller
Stick Software

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-19 Thread Per Bull Holmen
Ben Haller wrote:
 On 18-Jan-10, at 9:29 PM, Per Bull Holmen wrote:
 
  ...Again, I have clearly not explained what I wanted to do properly. No, I 
  did not want what you describe. I have done it now, I chose to use threads, 
  and it got far cleaner than the standard Cocoa way. No, I don't have to 
  handle any other input than what's relevant for the game, Cocoa handles the 
  rest, thank you... :)
 
   Perhaps you could post your solution, for the edification of the list?

Yes. It's very unfinished, and likely to contain bugs and memory leaks, though. 
I haven't even started looking at memory handling.

  I really appreciate your replies! I must have explained it poorly... anyway 
  if someone still want to convince me I'm doing things the wrong way, then 
  I'm guessing either they are so in love with MVC they have lost their sense 
  of reality, or they still haven't understood what I'm trying to explain... 
  :)
 
   Or perhaps, once you post your solution, someone will point out a problem 
 with it that you haven't foreseen?

Definitely. I'm not trying to say my solution is guaranteed to be the best! 
Just that I don't agree MVC is always the best way by definition. It does still 
depend on what you're trying to do, and it is also a matter of taste, feel free 
to dislike my solution! I should explain to you that this game is just for 
myself and friends, though, not for commercial release.

/* 

I have made one class called GameController, which is overridden by subclasses 
to control one specific type of game (PS: I will soon rename the class 
Controller to MainController, and instance variable controller to 
mainController). The GameController base class also mediates between input 
from the main thread, and the game thread, with help from the class InputBuffer:

- */

/* GameController */

#import Cocoa/Cocoa.h
#import TonePlayer.h
#import Controller.h

typedef enum {
NoInput = 0,
CodeInput,
ToneInput
} InputType; // + response?! Senere!

typedef enum {
NoInputAvailable,
InputIsAvailable
} InputStatus;

@interface InputBuffer : NSObject {
int toneCodes[ 16 ];
int octaves[ 16 ];
InputType types[ 16 ];
NSConditionLock *inputLock;
int size;
}

-(void)addInput:(int)code; // Always called from main thread
-(void)addInputTone:(int)tone octave:(int)octave; // Always called from main 
thread
-(InputType)getInputToneCode:(int *)toneCode octave:(int *)octave; // Always 
called from game thread
-(BOOL)isEmpty;

@end

@interface GameController : NSObject {
TonePlayer *tonePlayer;
InputBuffer *inputBuffer;
IBOutlet id controller;
}

// public
-(void)runGame; // Launches game loop in background...
-(void)acceptInputTone:(int)tone octave:(int)octave; // Accepts input when game 
loop is running...
-(void)acceptInput:(int)code;

// private
-(int)hiOctave;
-(int)loOctave;
-(int)randomOctave;
-(int)waitForInput;
-(void)waitForInputTone:(int *)tone octave:(int *)octave;
-(int)waitForInputTone:(int *)tone octave:(int *)octave code:(int *)code;
-(int)askRetries;
-(void)playTone:(int)tone octave:(int)octave;
-(Controller *)controller;
-(void)backGroundGameLoop:(id)dummy; // Don't override. Launched in new thread 
for game loop.

-(void)prepareGameLoop;  // Overriden by subclasses to prepare for 
the game, in the main thread...
-(void)doGameLoop;   // Overriden by subclasses to do the 
actual work, in a separate thread...
-(void)cleanupGameLoop:(id)dummy;// Overriden by subclasses to clean up 
after the game, in the main thread...

@end

/* 

Notice that game loop here does not mean the repetitive, periodic game loop 
which is common for action games. This is not an action game, but one that 
waits patiently for the user to respond to questions. The loop is a loop of 
questions, but each subclass is free to define a radically different game flow. 
OK, here is the implementation of the input buffer. This is probably 
overkill... :)

 */

@implementation InputBuffer

-(id)init {
inputLock = [[NSConditionLock alloc] initWithCondition:NoInputAvailable];
return( self );
}

-(void)purge { // Don't call if empty!!
if( --size ) {
memmove( toneCodes, toneCodes[ 1 ], size * sizeof( int ) );
memmove( octaves, octaves[ 1 ], size * sizeof( int ) );
memmove( types, types[ 1 ], size * sizeof( InputType ) );
}
}

-(void)addInput:(int)code { // Always called from MAIN thread
[inputLock lock];
if( size == 16 )
[self purge];
toneCodes[ size ] = code;
types[ size ] = CodeInput;
++size;
[inputLock unlockWithCondition:InputIsAvailable];
}

-(void)addInputTone:(int)tone octave:(int)octave { // Always called from MAIN 
thread
[inputLock lock];
if( size == 16 )
[self purge];
toneCodes[ size ] = tone;
octaves[ size ] = octave;
types[ size ] = ToneInput;
++size;

Re: Blocking for input during a loop? (Yahoo mail destroyed my indentation)

2010-01-19 Thread Per Bull Holmen
Hi all

Sorry that Yahoo mail (my mail service) destroyed my indentation on the last 
post. I guess that wasn't easy to read... :( 

Actually I don't know how to send the code properly with Yahoo Mail. If I find 
it out I might repost. Perhaps pasting it into XCode would restore the 
indentation. Sorry again...

Per
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop? (Yahoo mail destroyed my indentation)

2010-01-19 Thread Greg Guerin

Per Bull Holmen wrote:

Sorry that Yahoo mail (my mail service) destroyed my indentation on  
the last post. I guess that wasn't easy to read... :(


Actually I don't know how to send the code properly with Yahoo  
Mail. If I find it out I might repost. Perhaps pasting it into  
XCode would restore the indentation. Sorry again...



Try pasting your code to a service like pastebin.com, then post the  
URL to the list.


  -- GG

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-19 Thread Jens Alfke


On Jan 19, 2010, at 6:10 AM, Per Bull Holmen wrote:

I have made one class called GameController, which is overridden by  
subclasses to control one specific type of game (PS: I will soon  
rename the class Controller to MainController, and instance  
variable controller to mainController). The GameController base  
class also mediates between input from the main thread, and the game  
thread, with help from the class InputBuffer:


You've basically implemented coroutines, actually a simple form of an  
actor, using multiple threads. Each coroutine is running an event  
loop, and the game one blocks waiting for incoming events from the UI  
one.


(Ideally it's possible to implement this without using multiple  
threads; I tried to do that about two years ago using the low-level  
ucontext library, but it turns out that the stack manipulation it does  
is incompatible with Objective-C's exception handling system.)


This is a fine way to do things, except that you can't call AppKit  
from the game thread, and in general have to be careful about  
accessing shared state. More subtly, you've written your game code  
with the expectation that, each time it waits for user input, there is  
only one type of input the user can enter. For example, you wait for  
the user to enter a new note to play. If the game gets more complex,  
there may be multiple types of things the user can do (maybe deleting  
or editing notes) and then your code has to add something like a  
switch() statement to handle each possible action. In my experience,  
this quickly becomes unwieldy and results in spaghetti code, at which  
point the regular asynchronous event-loop mechanism becomes cleaner.  
(Historically this is a prime reason why GUI libraries use it in the  
first place.)


—Jens___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop? (Yahoo mail destroyed my indentation)

2010-01-19 Thread Per Bull Holmen
Greg Guerin wrote:

 Per Bull Holmen wrote:
 
  Sorry that Yahoo mail (my mail service) destroyed my indentation on
  the last post. I guess that wasn't easy to read... :(
  
  Actually I don't know how to send the code properly with Yahoo Mail.
  If I find it out I might repost. Perhaps pasting it into XCode would
  restore the indentation. Sorry again...
 
 
 Try pasting your code to a service like pastebin.com, then post the
 URL to the list.
 
   -- GG
 

Thanks. That was a great little tool. I included the original message above the 
code for your convenience.

http://pastebin.com/d3429ee7

I mention a possible bug at the very end of the code, I have probably removed 
it with the following change: 

http://pastebin.com/m2781863c

Per
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-19 Thread Per Bull Holmen
Jens Afke wrote:
 You've basically implemented coroutines, actually a simple form of
 an actor, using multiple threads. Each coroutine is running an event
 loop, and the game one blocks waiting for incoming events from the UI
 one.

/.../

 This is a fine way to do things, except that you can't call AppKit
 from the game thread, and in general have to be careful about
 accessing shared state. More subtly, you've written your game code
 with the expectation that, each time it waits for user input, there is
 only one type of input the user can enter. For example, you wait for
 the user to enter a new note to play. 

Agreed.

 If the game gets more complex, there may be multiple types of things
 the user can do (maybe deleting or editing notes) and then your code
 has to add something like a switch() statement to handle each possible
 action. In my experience, this quickly becomes unwieldy and results in
 spaghetti code, at which point the regular asynchronous event-loop
 mechanism becomes cleaner. (Historically this is a prime reason why
 GUI libraries use it in the first place.)

Definitely agreed. But that is not the type of thing my game is intended to do. 
Thanks for helping me a little with terminology, though! Since I'm just a 
hobbyist I get stuck not being able to explain what I want to do, cause I don't 
know what it's called... :)
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-19 Thread Jens Alfke


On Jan 19, 2010, at 10:16 AM, Jens Alfke wrote:

You've basically implemented coroutines, actually a simple form of  
an actor, using multiple threads.


The listserv stripped the links from that sentence. They were:
http://en.wikipedia.org/wiki/Coroutine
http://en.wikipedia.org/wiki/Actor_model

Is this a new regression in the listserv? It didn't use to strip HTML  
message parts. This sucks. :-p


—Jens___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-19 Thread Per Bull Holmen
Jens Afke wrote:

 The listserv stripped the links from that sentence. They were:
http://en.wikipedia.org/wiki/Coroutine
http://en.wikipedia.org/wiki/Actor_model

Thanks. This is will be very useful as I learn more about game programming. 

:)

Per
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-18 Thread Per Bull Holmen



 - Original Message 
 From: Kyle Sluder kyle.slu...@gmail.com
 To: Per Bull Holmen pbhol...@yahoo.com
 Cc: cocoa-dev@lists.apple.com
 Sent: Mon, January 18, 2010 6:29:32 AM
 Subject: Re: Blocking for input during a loop?
 
  On Sun, Jan 17, 2010 at 1:59 PM, Per Bull Holmen pbhol...@yahoo.com wrote:
  Is it possible, in Cocoa, do program a loop which goes something like this:
 
  for i=1 to 20
  do something
  block for GUI user input
  do something with the input
  repeat
 
 This is a bad idea. Don't block the UI thread, because then the user
 will see a beachball.
 
 Sounds like you need to reread the Cocoa Event Handling Guide:
 http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/EventOverview/Introduction/Introduction.html
 
 Your architectural difficulties also betray an unfamiliarity with MVC
 design. I suggest you read the Cocoa Design Patterns section of the
 Cocoa Fundamentals Guide, delve into the AppKit classes to see how
 that document relates to the actual framework, and then iterate your
 own design over and over (perhaps with pencil and paper for a while),
 keeping in mind the things you've learned from the documentation and
 from using the classes in AppKit. AppKit classes need to maintain a
 lot of state information, particularly when doing things like dragging
 or other input-driven processes. Here is the relevant document:
 http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6
 
 --Kyle Sluder

Thanks for the response. 

I have created several applications the standard Cocoa way so to speak, since 
10.2, using the target/action mechanisms, responder chain, bindings, and 
MVC-paradigm. It's great! This time, I firstly also did it the way I'm used to 
doing it, but as I thought I had explained to you, it got very cumbersome for 
me to use for the task at hand. The controller classes got very complex, with 
too many state variables - too many potential bugs, it got very difficult to 
extend, so I thought I'd find another way of doing it. I am absolutely 
convinced that I should learn a lot more about the stuff you want me to read, 
and it's quite possible I could have done it better, but I do have a problem 
with you asking me to read about 500 pages of documentation, without first 
giving me a reason to believe it would solve my problem.

You say my initially proposed loop is a bad idea - but lots of applications use 
this type of loop. The difference is that they do it only inside one window, 
and block user access to all other parts of the application (modal windows). 
They do this for wizards and the like, which are far closer to how the game 
will eventually be than a regular application. So, maybe that's the way to 
go? As I thought I had made clear, the loop doesn't have to happen in the UI 
(main) thread. It's just that if the loop wants to interact with views, 
controls etc., I'd have to arrange for messaging to the main thread, which 
could also get awkward.

Per
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-18 Thread Jens Alfke

On Jan 18, 2010, at 3:38 AM, Per Bull Holmen wrote:

 You say my initially proposed loop is a bad idea - but lots of applications 
 use this type of loop. The difference is that they do it only inside one 
 window, and block user access to all other parts of the application (modal 
 windows). They do this for wizards and the like, which are far closer to how 
 the game will eventually be than a regular application.

That's not really true. A modal dialog is still running the runloop, it's just 
a nested runloop. So at the outer level it looks like the app has blocked in 
order to run the modal dialog, what's actually happening is that the runloop is 
still in charge and handling events as usual, it's just ignoring mouse clicks 
outside that window. When the runloop is finished with the modal window it 
returns control back to the original code.

What you're talking about is an inverted flow of control where your code is in 
charge and periodically calls the runloop to handle an event. It's possible to 
write code that way, but it gets really messy in the real world because you're 
privileging one possible flow of control while ignoring the others. So you may 
be waiting for the user to press button A or button B, but what happens if the 
user decides to choose the Quit command? Now your loop has to handle that too. 
What you'll end up with is an explosion of different cases in your 
event-handling code, which gets just as messy as the normal flow of control 
would have been, only worse because all the complexity is in one big switch 
statement.

By contrast, if you've got a cleanly-factored model, you'll be able to keep 
track of the state cleanly. The model object(s) will have the state, and the 
controller code will call the model to change from one state to another.

—Jens___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-18 Thread Per Bull Holmen
Thank you all for the replies! :)

Anyway, you've clearly misunderstood. I have clearly not explained properly 
what I wanted to do, sorry about that. Probably because I'm not quite into the 
lingo. I've found a great solution, but in case anyone has a technical interest 
I'll try to explain it better...

Jens Alfke wrote:

 On Jan 18, 2010, at 3:38 AM, Per Bull Holmen wrote: 

  You say my initially
  proposed loop is a bad idea - but lots of applications use this type of
  loop. The difference is that they do it only inside one window, and
  block user access to all other parts of the application (modal windows).
  They do this for wizards and the like, which are far closer to how the
  game will eventually be than a regular application.
 
 That's not really true. A modal dialog is still running the runloop,
 it's just a nested runloop. So at the outer level it looks like the app
 has blocked in order to run the modal dialog, what's actually happening
 is that the runloop is still in charge and handling events as usual,
 it's just ignoring mouse clicks outside that window. When the runloop is
 finished with the modal window it returns control back to the original
 code.

I was not talking about not running the runloop (on the contrary), I was 
speaking strictly on code level: Write a piece of code that blocks execution 
and waits for user input, just like I wrote, as opposed to the typical 
MVC/event driven way, which is marvellous for document based apps and in fact 
almost all applications, but isn't perfect for every use (even Apple concedes 
that). Games with intricate branched game logics is one great example. Whether 
the runtime system runs a runloop, and handles events such as the quit 
command was not part of my question.

What I meant was writing code something like this:
1) Do something
2) Block/wait for the user to respond to, say, a question etc... (without 
having to terminate the function/method and have to store a lot of intermediate 
variables)
3) Do something with the input.

Whether this happens inside a loop was really besides the point. Whether 
NSRunLoop runs etc... irrelevant. And YES, with a modal dialog you not only CAN 
do this, it's also often done, and I've done it lots of times. NSRunAlertPanel 
and NSOpenPanel are two, very simple examples. (that is, when you call it, the 
calling code is blocked untill the modal session is over). The only problem 
with the modal way, in this case, is that it only accepts input from one single 
window.

 What you're talking about is an inverted flow of control where your code
 is in charge and periodically calls the runloop to handle an event. It's
 possible to write code that way, but it gets really messy in the real
 world because you're privileging one possible flow of control while
 ignoring the others. So you may be waiting for the user to press button
 A or button B, but what happens if the user decides to choose the Quit
 command? Now your loop has to handle that too. What you'll end up with
 is an explosion of different cases in your event-handling code, which
 gets just as messy as the normal flow of control would have been, only
 worse because all the complexity is in one big switch statement.

Again, I have clearly not explained what I wanted to do properly. No, I did not 
want what you describe. I have done it now, I chose to use threads, and it got 
far cleaner than the standard Cocoa way. No, I don't have to handle any other 
input than what's relevant for the game, Cocoa handles the rest, thank you... :)

The thing is that the way Cocoa usually handles things is really great for the 
vast majority of apps, but in an interactive game with an intricate, branched 
flow of game logic, you'll sometimes want to write the game logic in more 
coherent pieces of code that focus on logic/control flow, rather than updating 
a lot of intermediate state variables. It just gets cleaner, more maintainable, 
and more extensible this way. I was able to do this great within the Cocoa 
system, I just had to write a simple, sort of a mediating layer between the 
game controller (which runs in a separate thread) and the main UI thread.

I really appreciate your replies! I must have explained it poorly... anyway if 
someone still want to convince me I'm doing things the wrong way, then I'm 
guessing either they are so in love with MVC they have lost their sense of 
reality, or they still haven't understood what I'm trying to explain... :)

Per
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Blocking for input during a loop?

2010-01-17 Thread Per Bull Holmen
Hi

Is it possible, in Cocoa, do program a loop which goes something like this:

for i=1 to 20
do something
block for GUI user input
do something with the input
repeat

It is for a simple game that plays tones etc, and lets the user guess what was 
played. Originally, I had implemented it without a loop, just using regular 
target/action mechanisms. The code got awfully complex with too many state 
variables, and it got difficult to implement new functionality etc. So, I tried 
implementing it as a loop running in a separate thread, but the loop is 
supposed to add/remove subviews on an NSView as the game progresses, and I 
found out that NSView doesn't want you to do that from a different thread than 
the main thread. I thought it would get cumbersome to arrange for messaging to 
the main thread to switch views, so I thought maybe running the loop in the 
main thread, and using NSRunLoop might be a solution?

I have no clue about NSRunLoop, but I tried that idea, and implement the method 
waiting for UI input this way:

-(int)waitForInput {
while( inputAvailable != CodeInput )
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate 
dateWithTimeIntervalSinceNow:1.0]];
inputAvailable = NoInput;
return( inputCode );
}

The event handling methods should then update the instance variable 
inputAvailable to equal CodeInput (an enum value), and the inputCode would be 
updated to tell the game loop what choice the user made. But during the 
NSRunLoop statement no input is accepted at all. The handler methods are never 
run. I guess I'm completely lost and that NSRunLoop was never meant for this 
type of thing.

The game has several windows in which the user can click to respond to the game 
questions, therefore trying to run modally for one window is not ideal. If 
running modal for a window is the recomended way, I might look into collecting 
all the current input views into one window.

So, what do you recommend?
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Blocking for input during a loop?

2010-01-17 Thread Kyle Sluder
On Sun, Jan 17, 2010 at 1:59 PM, Per Bull Holmen pbhol...@yahoo.com wrote:
 Is it possible, in Cocoa, do program a loop which goes something like this:

 for i=1 to 20
 do something
 block for GUI user input
 do something with the input
 repeat

This is a bad idea. Don't block the UI thread, because then the user
will see a beachball.

Sounds like you need to reread the Cocoa Event Handling Guide:
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/EventOverview/Introduction/Introduction.html

Your architectural difficulties also betray an unfamiliarity with MVC
design. I suggest you read the Cocoa Design Patterns section of the
Cocoa Fundamentals Guide, delve into the AppKit classes to see how
that document relates to the actual framework, and then iterate your
own design over and over (perhaps with pencil and paper for a while),
keeping in mind the things you've learned from the documentation and
from using the classes in AppKit. AppKit classes need to maintain a
lot of state information, particularly when doing things like dragging
or other input-driven processes. Here is the relevant document:
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6

--Kyle Sluder
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com