Thread

A little help with a program (Sdk)

A little help with a program // Sdk

1  |  

jan-willem de bleser

Sep 18, 1998, 10:54pm
This is a multi-part message in MIME format.
--------------A0DAC8C25DBD29070F78C186
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I have the following program (derived from sample #1) which is a
greetbot. It runs as a console application in dos or windows. Im trying
to get it to accept commands at the console so i can make the bot move
and talk at my command. how would i do that?

the program:
#include <aw.h> //i added the library and header to my program
directories. unless you have done
//that, use "aw.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

void handle_avatar_add (void);
void object_add (void);
void avatar_delete (void);
void input(char command[100]);

main (int argc, char *argv[])
{

int rc;
char junk[1];

/* check command line */
if (argc < 3) {
printf ("Usage: %s number password\n", argv[0]);
printf ("Press any key to continue");
gets (junk);
exit (1);
}

/* initialize Active Worlds API */
if (rc = aw_init (AW_BUILD)) {
printf ("Unable to initialize API (reason %d)\n", rc);
printf ("Press any key to continue");
gets (junk);
exit (1);
}

/* install handler for avatar_add and object_add event */
aw_event_set (AW_EVENT_AVATAR_ADD, handle_avatar_add);
aw_event_set (AW_EVENT_OBJECT_ADD, object_add);
aw_event_set (AW_EVENT_AVATAR_DELETE, avatar_delete);

/* create bot instance */
if (rc = aw_create (0, 0, 0)) {
printf ("Unable to create bot instance (reason %d)\n", rc);
printf ("Press any key to continue");
gets (junk);
exit (1);
}

/* log bot into the universe */
aw_int_set (AW_LOGIN_OWNER, atoi (argv[1]));
aw_string_set (AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]);
aw_string_set (AW_LOGIN_APPLICATION, "SDK Sample Application #1");
aw_string_set (AW_LOGIN_NAME, "Bot of Zasz");
if (rc = aw_login ()) {
printf ("Unable to login (reason %d)\n", rc);
printf ("Press any key to continue");
gets (junk);
exit (1);
}

/* log bot into the world called "beta" */
if (rc = aw_enter ("Beta", 0)) {
printf ("Unable to enter world (reason %d)\n", rc);
printf ("Press any key to continue");
gets (junk);
exit (1);
}

/* announce our position in the world */
aw_int_set (AW_MY_X, 1000); /* 1W */
aw_int_set (AW_MY_Z, 1000); /* 1N */
aw_int_set (AW_MY_YAW, 2250); /* face towards GZ */
if (rc = aw_state_change ()) {
printf ("Unable to change state (reason %d)\n", rc);
printf ("Press any key to continue");
gets (junk);
exit (1);
}

/* main event loop */
char req, command[81];

while (!aw_wait (-1))
;

/* close everything down */
aw_destroy ();
aw_term ();
return 0;

}

void handle_avatar_add (void)
{

char message[100];

sprintf (message, "Hello %s. Welcome to Beta.", aw_string
(AW_AVATAR_NAME));
aw_say (message);
/* log the event to the console */
printf ("avatar_add: %s\n", aw_string (AW_AVATAR_NAME));

}

void object_add (void)
{

printf ("Someone has added a %s nearby", aw_string (AW_OBJECT_MODEL));

}

void avatar_delete (void)
{

char message[100];

sprintf (message, "%s has left the building\n", aw_string
(AW_AVATAR_NAME));
aw_say (message);
printf ("avatar_delete: %s\n", aw_string (AW_AVATAR_NAME));

}

--------------A0DAC8C25DBD29070F78C186
Content-Type: text/x-vcard; charset=us-ascii; name="vcard.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Jan-willem De Bleser
Content-Disposition: attachment; filename="vcard.vcf"

begin: vcard
fn: Jan-willem De Bleser
n: De Bleser;Jan-willem
org: High school
email;internet: debleser at mediaone.net
x-mozilla-cpt: ;0
x-mozilla-html: FALSE
version: 2.1
end: vcard


--------------A0DAC8C25DBD29070F78C186--

pc wizard

Sep 18, 1998, 11:18pm
I don't know much about programming (I'm just now learning, while I'm
working on my own SDK bot), but I would think that if you wanted to be able
to type stuff in while the program is running it would have to have some
sort of windows interface (a dialog box with text field or something), maybe
I don't know enough about console applications or something, but as far as I
know you can't type stuff in while a console app is running... If you can,
then I'd like to know how to do that too.

PC Wizard
ICQ-537376
wizardry at home.com
http://pcwizard.ml.org


[View Quote]

jan-willem de bleser

Sep 18, 1998, 11:22pm
This is a multi-part message in MIME format.
--------------64CD37FA0AB03E0CF1307409
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Ive seen it done. im guessing you do it somewhere in "while (!aw_wait (-1))
!newline! ;", but i cant get it to work



[View Quote] > I don't know much about programming (I'm just now learning, while I'm
> working on my own SDK bot), but I would think that if you wanted to be able
> to type stuff in while the program is running it would have to have some
> sort of windows interface (a dialog box with text field or something), maybe
> I don't know enough about console applications or something, but as far as I
> know you can't type stuff in while a console app is running... If you can,
> then I'd like to know how to do that too.
>
> PC Wizard
> ICQ-537376
> wizardry at home.com
> http://pcwizard.ml.org
>
[View Quote]

--------------64CD37FA0AB03E0CF1307409
Content-Type: text/x-vcard; charset=us-ascii; name="vcard.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Jan-willem De Bleser
Content-Disposition: attachment; filename="vcard.vcf"

begin: vcard
fn: Jan-willem De Bleser
n: De Bleser;Jan-willem
org: High school
email;internet: debleser at mediaone.net
x-mozilla-cpt: ;0
x-mozilla-html: FALSE
version: 2.1
end: vcard


--------------64CD37FA0AB03E0CF1307409--

esumerfd

Sep 21, 1998, 11:51am
You don't need windows unless you want to make the interface pretty. A command
line interface, like the dos prompt, is possible with a console app and is much
easier to implement if you haven't done much programming.

Your problem is the architectural design of the sdk. It is event driven so while
your program is in aw_wait it is waiting for a message from the server. It is not
able to wait for a keystroke at the same time.

An extension needs to be made to the sdk for adding user events (Roland?), such as
keyboard events. For example, aw_add_event(int, function); This would cause the aw
sdk to wait on your event as well as its own and call your function when it is
fired.

In the mean time you can use polling but it is not ideal. For example call
aw_wait(10) so it will wait for 10 milliseconds for an sdk event to occur then
drop back into your program. Then in your console app you can use the standard C
function gets() which would allow you to enter a string and press enter. You can
then do what you like based on the command entered.

The problem is that this is a blocking call. Once you have called gets it will not
return to your program until you press enter. While it is waiting for you, your
avatar will not be able to react to events.

If you want to get into some more serious programing them you can design a
multi-threaded solution which would be a little more realistic. Bare in mind that
the aw sdk is not thread safe so do not allow two different threads to call the
same api.

The design would involve one thread being dedicated to calling the aw functions
and a second thread being dedicated to accepting input from the keyboard. There
would be one common command buffer that both threads read and a lock to protect
that buffer.

So your program would start up and kick off a seperate thread to do all the aw
init, start, enter and wait(10) stuff while the first thread blocked on the gets()
function. Now the aw thread would be able to continue running even though the
gets() was blocked because it is running in a seperate thread.

In the aw thread, each time the aw_wait drops out it would check the command lock,
if it is unlocked then it would lock it, check the command buffer and act on what
ever it found before unlocking the lock.

In the gets thread, each time the enter key is pressed the lock is checked, if
unlocked then it must be locked and the new command copied into the shared command
buffer, before the lock is unlocked again.

This is a polling solution so is not as cpu efficient as the sdk change but would
work.

Good luck everyone.

Edward Sumerfield, esumerfd at poboxes.com

[View Quote] > Ive seen it done. im guessing you do it somewhere in "while (!aw_wait (-1))
> !newline! ;", but i cant get it to work
>
[View Quote]

jan-willem de bleser

Sep 21, 1998, 1:16pm
This is a multi-part message in MIME format.
--------------C426617553BF7CC92BCA379B
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit



[View Quote] > You don't need windows unless you want to make the interface pretty. A command
> line interface, like the dos prompt, is possible with a console app and is much
> easier to implement if you haven't done much programming.

I know

>
>
> Your problem is the architectural design of the sdk. It is event driven so while
> your program is in aw_wait it is waiting for a message from the server. It is not
> able to wait for a keystroke at the same time.

ah. thats the problem

>
>
> An extension needs to be made to the sdk for adding user events (Roland?), such as
> keyboard events. For example, aw_add_event(int, function); This would cause the aw
> sdk to wait on your event as well as its own and call your function when it is
> fired.

ill ask roland about that

>
>
> In the mean time you can use polling but it is not ideal. For example call
> aw_wait(10) so it will wait for 10 milliseconds for an sdk event to occur then
> drop back into your program. Then in your console app you can use the standard C
> function gets() which would allow you to enter a string and press enter. You can
> then do what you like based on the command entered.
>
> The problem is that this is a blocking call. Once you have called gets it will not
> return to your program until you press enter. While it is waiting for you, your
> avatar will not be able to react to events.
>
> If you want to get into some more serious programing them you can design a
> multi-threaded solution which would be a little more realistic. Bare in mind that
> the aw sdk is not thread safe so do not allow two different threads to call the
> same api.

How?

>
>
> The design would involve one thread being dedicated to calling the aw functions
> and a second thread being dedicated to accepting input from the keyboard. There
> would be one common command buffer that both threads read and a lock to protect
> that buffer.
>
> So your program would start up and kick off a seperate thread to do all the aw
> init, start, enter and wait(10) stuff while the first thread blocked on the gets()
> function. Now the aw thread would be able to continue running even though the
> gets() was blocked because it is running in a seperate thread.
>
> In the aw thread, each time the aw_wait drops out it would check the command lock,
> if it is unlocked then it would lock it, check the command buffer and act on what
> ever it found before unlocking the lock.
>
> In the gets thread, each time the enter key is pressed the lock is checked, if
> unlocked then it must be locked and the new command copied into the shared command
> buffer, before the lock is unlocked again.
>
> This is a polling solution so is not as cpu efficient as the sdk change but would
> work.
>
> Good luck everyone.
>
> Edward Sumerfield, esumerfd at poboxes.com
>
[View Quote]

--------------C426617553BF7CC92BCA379B
Content-Type: text/x-vcard; charset=us-ascii; name="vcard.vcf"
Content-Transfer-Encoding: 7bit
Content-Description: Card for Jan-willem De Bleser
Content-Disposition: attachment; filename="vcard.vcf"

begin: vcard
fn: Jan-willem De Bleser
n: De Bleser;Jan-willem
org: High school
email;internet: debleser at mediaone.net
x-mozilla-cpt: ;0
x-mozilla-html: FALSE
version: 2.1
end: vcard


--------------C426617553BF7CC92BCA379B--

esumerfd

Sep 21, 1998, 1:53pm
I am not going to be able to answer you in specific terms just yet. I don't have a C
compiler that conforms to the aw.lib object format.

It will be a while before I get a chance to do the programming myself. Find a book that
teaches you about writing threading programs and how to use locks, sometimes called
semephors.

[View Quote] [View Quote]

roland vilett

Sep 21, 1998, 7:59pm
A multi-threaded solution isn't absolutely necessary here...if you are
developing a Windows console app then you can use the call _kbhit() to
determine if a key has been pressed in the console window to avoid blocking
in a call to getch(). Something like this:

/* main event loop */
for (;;) {
/* check for AW events */
if (aw_wait(100))
/* fatal error */
break;
if (_kbhit()) {
/* process keystroke here... */
}
}

Check out the Windows SDK docs for more info on _kbhit()...you may want to
adjust the timeout parameter to aw_wait() but 100 milliseconds means you are
checking for keyboard input 10 times per second which should be adequate
response time.

-Roland

>You don't need windows unless you want to make the interface pretty. A
command
>line interface, like the dos prompt, is possible with a console app and is
much
>easier to implement if you haven't done much programming.
>
>Your problem is the architectural design of the sdk. It is event driven so
while
>your program is in aw_wait it is waiting for a message from the server. It
is not
>able to wait for a keystroke at the same time.
>
>An extension needs to be made to the sdk for adding user events (Roland?),
such as
>keyboard events. For example, aw_add_event(int, function); This would cause
the aw
>sdk to wait on your event as well as its own and call your function when it
is
>fired.
>
>In the mean time you can use polling but it is not ideal. For example call
>aw_wait(10) so it will wait for 10 milliseconds for an sdk event to occur
then
>drop back into your program. Then in your console app you can use the
standard C
>function gets() which would allow you to enter a string and press enter.
You can
>then do what you like based on the command entered.
>
>The problem is that this is a blocking call. Once you have called gets it
will not
>return to your program until you press enter. While it is waiting for you,
your
>avatar will not be able to react to events.
>
>If you want to get into some more serious programing them you can design a
>multi-threaded solution which would be a little more realistic. Bare in
mind that
>the aw sdk is not thread safe so do not allow two different threads to call
the
>same api.
>
>The design would involve one thread being dedicated to calling the aw
functions
>and a second thread being dedicated to accepting input from the keyboard.
There
>would be one common command buffer that both threads read and a lock to
protect
>that buffer.
>
>So your program would start up and kick off a seperate thread to do all the
aw
>init, start, enter and wait(10) stuff while the first thread blocked on the
gets()
>function. Now the aw thread would be able to continue running even though
the
>gets() was blocked because it is running in a seperate thread.
>
>In the aw thread, each time the aw_wait drops out it would check the
command lock,
>if it is unlocked then it would lock it, check the command buffer and act
on what
>ever it found before unlocking the lock.
>
>In the gets thread, each time the enter key is pressed the lock is checked,
if
>unlocked then it must be locked and the new command copied into the shared
command
>buffer, before the lock is unlocked again.
>
>This is a polling solution so is not as cpu efficient as the sdk change but
would
>work.
>
>Good luck everyone.
>
>Edward Sumerfield, esumerfd at poboxes.com
>
[View Quote]

esumerfd

Sep 21, 1998, 8:16pm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
That is true enough Roland. Still a polling architecture but simpler than
writing threaded apps.
<P>So, you haven't commented on the idea of adding a aw_add_event(int ,
function) funtion to the sdk yet?
<P>You mentioned in the thread about the GNU compiler that your preference
is to port to Sun/Unix machines before GNU because of your belief that
high performance bots will run on that type of machine. If performance
is important to you then why is it that you are not addressing this inefficient
polling architecture?
<P>I would even go as far as saying that a threaded API is much high priority
than having to worry about porting high powered servers.
<P>What is the reletive hardware mix of your customers at the moment? Windows/Unix/Linix?
What percentage of each would you say?
<P>Edward Sumerfield
[View Quote]

roland vilett

Sep 21, 1998, 9:00pm
This is a multi-part message in MIME format.

------=_NextPart_000_000B_01BDE579.04EBAEC0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Okay look, I'll be the first to admit that the SDK architecture is not =
perfect for all possible applications. At this point I don't want to =
get into an argument about which features are more important than =
others. The SDK is what I could come up with in the time available. =
Future considerations like Java support, GNU support, multi-threading =
support, etc. are all great ideas and no doubt would make the SDK even =
better. But that's what they are: future considerations. Once again, =
the goal was to get something, anything, out there for people to be able =
to use. As with all aspects of the Active Worlds architecture, the SDK =
is going to be a continually evolving work in progress. As time goes =
by, it will be improved and extended along with all other aspects of the =
platform. The current goal is to simply stabilize and test the current =
SDK more or less as is in order to release it for general use. Then we =
can start thinking about the next version.

That said, I'm not sure I even understand the aw_add_event() =
suggestion...I don't know how you would add in external =
application-defined events into the SDK, because the SDK would need to =
know how to check for them. How would the programmer tell the SDK to =
check for his/her custom event, keeping in mind that the only event loop =
that the SDK has is a call to select()?

I don't have any hard numbers on the hardware mix of our customers. =
Obviously since AW is a Windows-based platform just about everyone has a =
Windows machine. But on the server side lately we've been seeing a lot =
of interest in Linux, for example. I'm not even sure yet what platforms =
most people will be running their bots on.
I'm assuming that, in the long term, SDK apps are going to more or less =
parallel world servers in terms of platform of choice, since most SDK =
apps will presumably be applications left running 24 hours/day.

-Roland

[View Quote] You mentioned in the thread about the GNU compiler that your =
preference is to port to Sun/Unix machines before GNU because of your =
belief that high performance bots will run on that type of machine. If =
performance is important to you then why is it that you are not =
addressing this inefficient polling architecture?=20

I would even go as far as saying that a threaded API is much high =
priority than having to worry about porting high powered servers.=20

What is the reletive hardware mix of your customers at the moment? =
Windows/Unix/Linix? What percentage of each would you say?=20

Edward Sumerfield=20

[View Quote] A multi-threaded solution isn't absolutely necessary here...if =
you are=20
developing a Windows console app then you can use the call =
_kbhit() to=20
determine if a key has been pressed in the console window to =
avoid blocking=20
in a call to getch(). Something like this:=20
/* main event loop */=20
for (;;) {=20
/* check for AW events */=20
if (aw_wait(100))=20
/* fatal error */=20
break;=20
if (_kbhit()) {=20
/* process keystroke here... */=20
}=20
}=20

Check out the Windows SDK docs for more info on _kbhit()...you =
may want to=20
adjust the timeout parameter to aw_wait() but 100 milliseconds =
means you are=20
checking for keyboard input 10 times per second which should be =
adequate=20
response time.=20

-Roland=20

>You don't need windows unless you want to make the interface =
pretty. A=20
command=20
>line interface, like the dos prompt, is possible with a console =
app and is=20
much=20
>easier to implement if you haven't done much programming.=20
>=20
>Your problem is the architectural design of the sdk. It is =
event driven so=20
while=20
>your program is in aw_wait it is waiting for a message from the =
server. It=20
is not=20
>able to wait for a keystroke at the same time.=20
>=20
>An extension needs to be made to the sdk for adding user events =
(Roland?),=20
such as=20
>keyboard events. For example, aw_add_event(int, function); This =
would cause=20
the aw=20
>sdk to wait on your event as well as its own and call your =
function when it=20
is=20
>fired.=20
>=20
>In the mean time you can use polling but it is not ideal. For =
example call=20
>aw_wait(10) so it will wait for 10 milliseconds for an sdk =
event to occur=20
then=20
>drop back into your program. Then in your console app you can =
use the=20
standard C=20
>function gets() which would allow you to enter a string and =
press enter.=20
You can=20
>then do what you like based on the command entered.=20
>=20
>The problem is that this is a blocking call. Once you have =
called gets it=20
will not=20
>return to your program until you press enter. While it is =
waiting for you,=20
your=20
>avatar will not be able to react to events.=20
>=20
>If you want to get into some more serious programing them you =
can design a=20
>multi-threaded solution which would be a little more realistic. =
Bare in=20
mind that=20
>the aw sdk is not thread safe so do not allow two different =
threads to call=20
the=20
>same api.=20
>=20
>The design would involve one thread being dedicated to calling =
the aw=20
functions=20
>and a second thread being dedicated to accepting input from the =
keyboard.=20
There=20
>would be one common command buffer that both threads read and a =
lock to=20
protect=20
>that buffer.=20
>=20
>So your program would start up and kick off a seperate thread =
to do all the=20
aw=20
>init, start, enter and wait(10) stuff while the first thread =
blocked on the=20
gets()=20
>function. Now the aw thread would be able to continue running =
even though=20
the=20
>gets() was blocked because it is running in a seperate thread.=20
>=20
>In the aw thread, each time the aw_wait drops out it would =
check the=20
command lock,=20
>if it is unlocked then it would lock it, check the command =
buffer and act=20
on what=20
>ever it found before unlocking the lock.=20
>=20
>In the gets thread, each time the enter key is pressed the lock =
is checked,=20
if=20
>unlocked then it must be locked and the new command copied into =
the shared=20
command=20
>buffer, before the lock is unlocked again.=20
>=20
>This is a polling solution so is not as cpu efficient as the =
sdk change but=20
would=20
>work.=20
>=20
>Good luck everyone.=20
>=20
>Edward Sumerfield, esumerfd at poboxes.com=20
>=20
[View Quote] */=20
rc);=20
Application #1");=20
aw_string=20

(AW_OBJECT_MODEL));=20
aw_string=20
(AW_AVATAR_NAME));=20
>=20



------=_NextPart_000_000B_01BDE579.04EBAEC0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML>
<HEAD>

<META content=3Dtext/html;charset=3Diso-8859-1 =
http-equiv=3DContent-Type><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 =
Transitional//EN">
<META content=3D'"MSHTML 4.72.2106.6"' name=3DGENERATOR>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT color=3D#000000 size=3D2>Okay look, I'll be the first to =
admit that the=20
SDK architecture is not perfect for all possible applications.&nbsp; At =
this=20
point I don't want to get into an argument about which features are more =

important than others.&nbsp; The SDK is what I could come up with in the =
time=20
available.&nbsp; Future considerations like Java support, GNU support,=20
multi-threading support, etc. are all great ideas and no doubt would =
make the=20
SDK even better.&nbsp; But that's what they are: future =
considerations.&nbsp;=20
Once again, the goal was to get something, anything, out there for =
people to be=20
able to use.&nbsp; As with all aspects of the Active Worlds =
architecture, the=20
SDK is going to be a continually evolving work in progress.&nbsp; As =
time goes=20
by, it will be improved and extended along with all other aspects of the =

platform.&nbsp; The current goal is to simply stabilize and test the =
current SDK=20
more or less as is in order to release it for general use.&nbsp; Then we =
can=20
start thinking about the next version.</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>That said, I'm not sure I even understand the =
aw_add_event()=20
suggestion...I don't know how you would add in external =
application-defined=20
events into the SDK, because the SDK would need to know how to check for =

them.&nbsp; How would the programmer tell the SDK to check for his/her =
custom=20
event, keeping in mind that the only event loop that the SDK has is a =
call to=20
select()?</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#000000 size=3D2>I don't have any hard numbers on the =
hardware=20
mix of our customers.&nbsp; Obviously since AW is a Windows-based =
platform just=20
about everyone has a Windows machine.&nbsp; But on the server side =
lately we've=20
been seeing a lot of interest in Linux, for example.&nbsp; I'm not even =
sure yet=20
what platforms most people will be running their bots on.</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT><FONT size=3D2>I'm assuming =
that, in the=20
long term, SDK apps are going to more or less parallel world servers in =
terms of=20
platform of choice, since most SDK apps will presumably be applications =
left=20
running 24 hours/day.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>-Roland</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
[View Quote] important to you then why is it that you are not addressing this =
inefficient=20
polling architecture?=20
<P>I would even go as far as saying that a threaded API is much high =

priority than having to worry about porting high powered servers.=20
<P>What is the reletive hardware mix of your customers at the =
moment?=20
Windows/Unix/Linix? What percentage of each would you say?=20
<P>Edward Sumerfield=20
[View Quote] necessary here...if you are <BR>developing a Windows console app =
then=20
you can use the call _kbhit() to <BR>determine if a key has been =
pressed=20
in the console window to avoid blocking <BR>in a call to =
getch().&nbsp;=20
Something like this:=20
<P>/* main event loop */ <BR>for (;;) { <BR>&nbsp; /* check for =
AW=20
events */ <BR>&nbsp; if (aw_wait(100)) <BR>&nbsp;&nbsp;&nbsp; /* =
fatal=20
error */ <BR>&nbsp;&nbsp;&nbsp; break; <BR>&nbsp; if (_kbhit()) =
{=20
<BR>&nbsp;&nbsp;&nbsp; /* process keystroke here... */ =
<BR>&nbsp; }=20
<BR>}=20
<P>Check out the Windows SDK docs for more info on =
_kbhit()...you may=20
want to <BR>adjust the timeout parameter to aw_wait() but 100=20
milliseconds means you are <BR>checking for keyboard input 10 =
times per=20
second which should be adequate <BR>response time.=20
<P>-Roland=20
<P>&gt;You don't need windows unless you want to make the =
interface=20
pretty. A <BR>command <BR>&gt;line interface, like the dos =
prompt, is=20
possible with a console app and is <BR>much <BR>&gt;easier to =
implement=20
if you haven't done much programming. <BR>&gt; <BR>&gt;Your =
problem is=20
the architectural design of the sdk. It is event driven so =
<BR>while=20
<BR>&gt;your program is in aw_wait it is waiting for a message =
from the=20
server. It <BR>is not <BR>&gt;able to wait for a keystroke at =
the same=20
time. <BR>&gt; <BR>&gt;An extension needs to be made to the sdk =
for=20
adding user events (Roland?), <BR>such as <BR>&gt;keyboard =
events. For=20
example, aw_add_event(int, function); This would cause <BR>the =
aw=20
<BR>&gt;sdk to wait on your event as well as its own and call =
your=20
function when it <BR>is <BR>&gt;fired. <BR>&gt; <BR>&gt;In the =
mean time=20
you can use polling but it is not ideal. For example call=20
<BR>&gt;aw_wait(10) so it will wait for 10 milliseconds for an =
sdk event=20
to occur <BR>then <BR>&gt;drop back into your program. Then in =
your=20
console app you can use the <BR>standard C <BR>&gt;function =
gets() which=20
would allow you to enter a string and press enter. <BR>You can=20
<BR>&gt;then do what you like based on the command entered. =
<BR>&gt;=20
<BR>&gt;The problem is that this is a blocking call. Once you =
have=20
called gets it <BR>will not <BR>&gt;return to your program until =
you=20
press enter. While it is waiting for you, <BR>your =
<BR>&gt;avatar will=20
not be able to react to events. <BR>&gt; <BR>&gt;If you want to =
get into=20
some more serious programing them you can design a=20
<BR>&gt;multi-threaded solution which would be a little more =
realistic.=20
Bare in <BR>mind that <BR>&gt;the aw sdk is not thread safe so =
do not=20
allow two different threads to call <BR>the <BR>&gt;same api. =
<BR>&gt;=20
<BR>&gt;The design would involve one thread being dedicated to =
calling=20
the aw <BR>functions <BR>&gt;and a second thread being dedicated =
to=20
accepting input from the keyboard. <BR>There <BR>&gt;would be =
one common=20
command buffer that both threads read and a lock to <BR>protect=20
<BR>&gt;that buffer. <BR>&gt; <BR>&gt;So your program would =
start up and=20
kick off a seperate thread to do all the <BR>aw <BR>&gt;init, =
start,=20
enter and wait(10) stuff while the first thread blocked on the=20
<BR>gets() <BR>&gt;function. Now the aw thread would be able to =
continue=20
running even though <BR>the <BR>&gt;gets() was blocked because =
it is=20
running in a seperate thread. <BR>&gt; <BR>&gt;In the aw thread, =
each=20
time the aw_wait drops out it would check the <BR>command lock,=20
<BR>&gt;if it is unlocked then it would lock it, check the =
command=20
buffer and act <BR>on what <BR>&gt;ever it found before =
unlocking the=20
lock. <BR>&gt; <BR>&gt;In the gets thread, each time the enter =
key is=20
pressed the lock is checked, <BR>if <BR>&gt;unlocked then it =
must be=20
locked and the new command copied into the shared <BR>command=20
<BR>&gt;buffer, before the lock is unlocked again. <BR>&gt; =
<BR>&gt;This=20
is a polling solution so is not as cpu efficient as the sdk =
change but=20
<BR>would <BR>&gt;work. <BR>&gt; <BR>&gt;Good luck everyone. =
<BR>&gt;=20
<BR>&gt;Edward Sumerfield, esumerfd at poboxes.com <BR>&gt;=20
[View Quote] <BR>&gt;&gt; &gt; &gt;&nbsp; aw_string_set =
(AW_LOGIN_APPLICATION,=20
&quot;SDK Sample Application #1&quot;); <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
aw_string_set (AW_LOGIN_NAME, &quot;Bot of Zasz&quot;); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; if (rc =3D aw_login ()) { <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to login (reason=20
%d)\n&quot;, rc); <BR>&gt;&gt; &gt; &gt; printf (&quot;Press any =
key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk); =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; exit (1); <BR>&gt;&gt; &gt; &gt;&nbsp; }=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; /* log bot =
into the=20
world called &quot;beta&quot; */ <BR>&gt;&gt; &gt; &gt;&nbsp; if =
(rc =3D=20
aw_enter (&quot;Beta&quot;, 0)) { <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to enter world =
(reason=20
%d)\n&quot;, rc); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; =
printf=20
(&quot;Press any key to continue&quot;); <BR>&gt;&gt; &gt; &gt; =
gets=20
(junk); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; =
&gt;&nbsp; /*=20
announce our position in the world */ <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
aw_int_set (AW_MY_X, 1000); /* 1W */ <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
aw_int_set (AW_MY_Z, 1000); /* 1N */ <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
aw_int_set (AW_MY_YAW, 2250); /* face towards GZ */ <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; if (rc =3D aw_state_change ()) { <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to change state =
(reason=20
%d)\n&quot;, rc); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; =
printf=20
(&quot;Press any key to continue&quot;); <BR>&gt;&gt; &gt; &gt; =
gets=20
(junk); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; =
&gt;&nbsp; /*=20
main event loop */ <BR>&gt;&gt; &gt; &gt;&nbsp; char req, =
command[81];=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; while =
(!aw_wait=20
(-1)) <BR>&gt;&gt; &gt; &gt; ; <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp; /* close everything down */ <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
aw_destroy (); <BR>&gt;&gt; &gt; &gt;&nbsp; aw_term (); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; return 0; <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt; &gt;}=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;void =
handle_avatar_add=20
(void) <BR>&gt;&gt; &gt; &gt;{ <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp; char message[100]; <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp; sprintf (message, &quot;Hello %s. Welcome to =
Beta.&quot;,=20
aw_string <BR>&gt;&gt; &gt; &gt;(AW_AVATAR_NAME)); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_say (message); <BR>&gt;&gt; &gt; &gt;&nbsp; /* log =
the=20
event to the console */ <BR>&gt;&gt; &gt; &gt;&nbsp; printf=20
(&quot;avatar_add: %s\n&quot;, aw_string (AW_AVATAR_NAME)); =
<BR>&gt;&gt;=20
&gt; &gt; <BR>&gt;&gt; &gt; &gt;} <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt;=20
&gt; &gt;void object_add (void) <BR>&gt;&gt; &gt; &gt;{ =
<BR>&gt;&gt;=20
&gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; printf (&quot;Someone has =
added a=20
%s nearby&quot;, aw_string <BR>(AW_OBJECT_MODEL)); <BR>&gt;&gt; =
&gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;} <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;void avatar_delete (void) <BR>&gt;&gt; &gt; &gt;{ =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; char message[100]; =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; sprintf (message, &quot;%s has =
left=20
the building\n&quot;, aw_string <BR>&gt;&gt; &gt; =
&gt;(AW_AVATAR_NAME));=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_say (message); <BR>&gt;&gt; &gt; =

&gt;&nbsp; printf (&quot;avatar_delete: %s\n&quot;, aw_string=20
(AW_AVATAR_NAME)); <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; =
&gt;}=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; <BR>&gt;=20
<BR></P></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML>

------=_NextPart_000_000B_01BDE579.04EBAEC0--

esumerfd

Sep 22, 1998, 2:11pm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<BODY BGCOLOR="#FFFFFF">
My apologies Roland, I must have seemed too pushy. I am a 12 year veteran
in the computer consulting field and understand totally what you are going
though. We customers can be very annoying at times. Especially what we
think we know what we are talking about. You are doing an excellent job.
Don't let us get to you.
<P>You are making the right move in solidifying the release you have and
when I get a darn C compiler I can use I will be right in there with you
trying to use your API.
<P>I would like to think that the comments we are making will contribute
to the next version of the API and so I would like to continue these conversations
if you have the time.
<P>Let me explain a little more about aw_add_event().
<P>Currently your code calls the socket() and connect() functions to create
connections to the universe and world servers. The socket call returns
file descriptors that you are adding to an array of file descriptors for
passing to the select() call. Each time data becomes available on one of
these file descriptors the select statement drops out and your code checks
the file descriptor returned to see if the event came from the universe
connection or the world connection.
<P>&nbsp;&nbsp;&nbsp; socket()
<BR>&nbsp;&nbsp;&nbsp; connect( universe )
<BR>&nbsp;&nbsp;&nbsp; socket()
<BR>&nbsp;&nbsp;&nbsp; connect( world )
<P>&nbsp;&nbsp;&nbsp; array = { universe, world }
<P>&nbsp;&nbsp;&nbsp; while (1) {
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; event = select (array)
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (event = universe) {
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Read
data from universe file descriptor
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Read
data from the world file descriptor
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<BR>&nbsp;&nbsp;&nbsp; }
<P>OK, now we have a requirement to allow user applications to create their
own files, sockets or timers and they have to have a way to use your select
statement to do it.
<P>You can create the following function
<P>&nbsp;&nbsp;&nbsp; aw_add_event (file descriptor, function pointer)
{
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; append file descriptor to
end of array.
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; store function pointer into
another array indexed by the file descriptor.
<BR>&nbsp;&nbsp;&nbsp; }
<P>Now change your select function as follows:
<P>&nbsp;&nbsp;&nbsp; array = { universe, world }
<P>&nbsp;&nbsp;&nbsp; while (1) {
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; event = select (array)
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (event = universe) {
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Read
data from universe file descriptor
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (event == world)
{
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Read
data from the world file descriptor
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; look
up function pointer using file descriptor
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
call users function;
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
<BR>&nbsp;&nbsp;&nbsp; }
<P>Now you have a way for the application to add its own file descriptors
to your sdks select loop. Applications can now implement their own timer
based bot functions, dynamically receive weather information from a weather
server and have their bots tell people, read random quotes from a file.
All without impacting the performance of the application. Also, when bots
get more sophisticated they will not be needlessly chewing up CPU time
while polling the event queue, instead, your thousands of deer grazing
in a distant meadow will only use CPU time when they need to be moving.
<P>I have writing a number of there types of applications before and would
be happy to add my experience to future developments. Please don't hesitate
to ask.
<P>Edward Sumerfield,
<BR>Pesky user.
[View Quote] </BODY>
</HTML>

roland vilett

Sep 22, 1998, 4:08pm
This is a multi-part message in MIME format.

------=_NextPart_000_0022_01BDE619.53EC2E00
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Okay I understand better now. You simply want to provide extra =
descriptors to the SDK to select() on for you. Would the assumption be =
that all descriptors passed to the SDK would be checked for READ-ability =
only? Or would the aw_add_event() call need to be extended to support =
checking for WRITE-ability as well?

I wonder though, can all types of events that an app wants to check for =
be reduced to reading from a descriptor? It seems like a different =
mechanism would be required if, for example, the user wanted to be =
notified whenever a message was pending in the application Window's =
message queue. Also I'm not sure how you would implement a timer via a =
descriptor...well for that matter, if all you want is a timer, you can =
just pass that value into aw_wait(). For example if you want your app =
to do something once per second, just call aw_wait(1000) and then do =
whatever it is when aw_wait() returns. See my example further below.

I do want to point out that in practice, if you write a "polling" style =
application this does not necessarily mean that you are being horribly =
inefficient. It's true that you are being less efficient than you could =
theoretically be, but I suspect that, for example, if you actually wrote =
that code I suggested earlier where you called aw_wait(100) and then =
_kbhit() to see if a key had a been pressed, that program would use less =
than 1% of the available CPU on a P100.

Let's think a bit about how you would implement the "deer" bot program =
you suggested, using the SDK as it is currently implemented. Let's say =
what we wanted was a program that created ten deer, scattered them =
around a meadow, and then had them randomly move around, stop, chew =
grass, then periodically move again. The only other thing they would do =
is run away when another avatar approaches, so the only events they =
would want to respond to is AVATAR_ADD and AVATAR_CHANGE. Hmmm, the =
more I think about this, the more this is sounding like a great SDK =
sample application. :)

Anyway, here's how I would do it. I would say that when left alone, a =
deer would not decide to move along to a different patch of grass more =
than once per second. That means we can use a 1-second resolution on =
the event poll. So your code would look something like this:

for (;;) {
if (aw_wait (1000))
break;
for (i =3D 0; i < NUM_DEAR; i++)
if (!(aw_random() % 60)) { /* let's say that deer move to a new spot =
on average once per minute */
/* move dear[i] here */
}
}

This program would spend the vast majority of its time simply sitting in =
select() waiting for humans to show up. Again I suspect that with 10 =
dear, or even 100 dear, you would see CPU utilization of less than 5%, =
probably more like 1%.

-Roland
[View Quote] I would like to think that the comments we are making will =
contribute to the next version of the API and so I would like to =
continue these conversations if you have the time.=20

Let me explain a little more about aw_add_event().=20

Currently your code calls the socket() and connect() functions to =
create connections to the universe and world servers. The socket call =
returns file descriptors that you are adding to an array of file =
descriptors for passing to the select() call. Each time data becomes =
available on one of these file descriptors the select statement drops =
out and your code checks the file descriptor returned to see if the =
event came from the universe connection or the world connection.=20

socket()=20
connect( universe )=20
socket()=20
connect( world )=20

array =3D { universe, world }=20

while (1) {=20

event =3D select (array)=20
if (event =3D universe) {=20

Read data from universe file descriptor=20
}=20
else {=20

Read data from the world file descriptor=20
}=20
}=20

OK, now we have a requirement to allow user applications to create =
their own files, sockets or timers and they have to have a way to use =
your select statement to do it.=20

You can create the following function=20

aw_add_event (file descriptor, function pointer) {=20

append file descriptor to end of array.=20
store function pointer into another array indexed by the =
file descriptor.=20
}=20

Now change your select function as follows:=20

array =3D { universe, world }=20

while (1) {=20

event =3D select (array)=20
if (event =3D universe) {=20

Read data from universe file descriptor=20
}=20
else if (event =3D=3D world) {=20

Read data from the world file descriptor=20
}=20
else {=20

look up function pointer using file descriptor=20
call users function;=20
}=20
}=20

Now you have a way for the application to add its own file =
descriptors to your sdks select loop. Applications can now implement =
their own timer based bot functions, dynamically receive weather =
information from a weather server and have their bots tell people, read =
random quotes from a file. All without impacting the performance of the =
application. Also, when bots get more sophisticated they will not be =
needlessly chewing up CPU time while polling the event queue, instead, =
your thousands of deer grazing in a distant meadow will only use CPU =
time when they need to be moving.=20

I have writing a number of there types of applications before and =
would be happy to add my experience to future developments. Please don't =
hesitate to ask.=20

Edward Sumerfield,=20
Pesky user.=20

[View Quote] Okay look, I'll be the first to admit that the SDK architecture =
is not perfect for all possible applications. At this point I don't =
want to get into an argument about which features are more important =
than others. The SDK is what I could come up with in the time =
available. Future considerations like Java support, GNU support, =
multi-threading support, etc. are all great ideas and no doubt would =
make the SDK even better. But that's what they are: future =
considerations. Once again, the goal was to get something, anything, =
out there for people to be able to use. As with all aspects of the =
Active Worlds architecture, the SDK is going to be a continually =
evolving work in progress. As time goes by, it will be improved and =
extended along with all other aspects of the platform. The current goal =
is to simply stabilize and test the current SDK more or less as is in =
order to release it for general use. Then we can start thinking about =
the next version. That said, I'm not sure I even understand the =
aw_add_event() suggestion...I don't know how you would add in external =
application-defined events into the SDK, because the SDK would need to =
know how to check for them. How would the programmer tell the SDK to =
check for his/her custom event, keeping in mind that the only event loop =
that the SDK has is a call to select()? I don't have any hard numbers on =
the hardware mix of our customers. Obviously since AW is a =
Windows-based platform just about everyone has a Windows machine. But =
on the server side lately we've been seeing a lot of interest in Linux, =
for example. I'm not even sure yet what platforms most people will be =
running their bots on.I'm assuming that, in the long term, SDK apps are =
going to more or less parallel world servers in terms of platform of =
choice, since most SDK apps will presumably be applications left running =
[View Quote] You mentioned in the thread about the GNU compiler that your =
preference is to port to Sun/Unix machines before GNU because of your =
belief that high performance bots will run on that type of machine. If =
performance is important to you then why is it that you are not =
addressing this inefficient polling architecture?=20

I would even go as far as saying that a threaded API is much =
high priority than having to worry about porting high powered servers.=20

What is the reletive hardware mix of your customers at the =
moment? Windows/Unix/Linix? What percentage of each would you say?=20

Edward Sumerfield=20

[View Quote] A multi-threaded solution isn't absolutely necessary =
here...if you are=20
developing a Windows console app then you can use the =
call _kbhit() to=20
determine if a key has been pressed in the console =
window to avoid blocking=20
in a call to getch(). Something like this:=20
/* main event loop */=20
for (;;) {=20
/* check for AW events */=20
if (aw_wait(100))=20
/* fatal error */=20
break;=20
if (_kbhit()) {=20
/* process keystroke here... */=20
}=20
}=20

Check out the Windows SDK docs for more info on =
_kbhit()...you may want to=20
adjust the timeout parameter to aw_wait() but 100 =
milliseconds means you are=20
checking for keyboard input 10 times per second which =
should be adequate=20
response time.=20

-Roland=20

>You don't need windows unless you want to make the =
interface pretty. A=20
command=20
>line interface, like the dos prompt, is possible with a =
console app and is=20
much=20
>easier to implement if you haven't done much =
programming.=20
>=20
>Your problem is the architectural design of the sdk. It =
is event driven so=20
while=20
>your program is in aw_wait it is waiting for a message =
from the server. It=20
is not=20
>able to wait for a keystroke at the same time.=20
>=20
>An extension needs to be made to the sdk for adding =
user events (Roland?),=20
such as=20
>keyboard events. For example, aw_add_event(int, =
function); This would cause=20
the aw=20
>sdk to wait on your event as well as its own and call =
your function when it=20
is=20
>fired.=20
>=20
>In the mean time you can use polling but it is not =
ideal. For example call=20
>aw_wait(10) so it will wait for 10 milliseconds for an =
sdk event to occur=20
then=20
>drop back into your program. Then in your console app =
you can use the=20
standard C=20
>function gets() which would allow you to enter a string =
and press enter.=20
You can=20
>then do what you like based on the command entered.=20
>=20
>The problem is that this is a blocking call. Once you =
have called gets it=20
will not=20
>return to your program until you press enter. While it =
is waiting for you,=20
your=20
>avatar will not be able to react to events.=20
>=20
>If you want to get into some more serious programing =
them you can design a=20
>multi-threaded solution which would be a little more =
realistic. Bare in=20
mind that=20
>the aw sdk is not thread safe so do not allow two =
different threads to call=20
the=20
>same api.=20
>=20
>The design would involve one thread being dedicated to =
calling the aw=20
functions=20
>and a second thread being dedicated to accepting input =
from the keyboard.=20
There=20
>would be one common command buffer that both threads =
read and a lock to=20
protect=20
>that buffer.=20
>=20
>So your program would start up and kick off a seperate =
thread to do all the=20
aw=20
>init, start, enter and wait(10) stuff while the first =
thread blocked on the=20
gets()=20
>function. Now the aw thread would be able to continue =
running even though=20
the=20
>gets() was blocked because it is running in a seperate =
thread.=20
>=20
>In the aw thread, each time the aw_wait drops out it =
would check the=20
command lock,=20
>if it is unlocked then it would lock it, check the =
command buffer and act=20
on what=20
>ever it found before unlocking the lock.=20
>=20
>In the gets thread, each time the enter key is pressed =
the lock is checked,=20
if=20
>unlocked then it must be locked and the new command =
copied into the shared=20
command=20
>buffer, before the lock is unlocked again.=20
>=20
>This is a polling solution so is not as cpu efficient =
as the sdk change but=20
would=20
>work.=20
>=20
>Good luck everyone.=20
>=20
>Edward Sumerfield, esumerfd at poboxes.com=20
>=20
[View Quote]

------=_NextPart_000_0022_01BDE619.53EC2E00
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML>
<HEAD>

<META content=3Dtext/html;charset=3Diso-8859-1 =
http-equiv=3DContent-Type><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 =
Transitional//EN">
<META content=3D'"MSHTML 4.72.2106.6"' name=3DGENERATOR>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT color=3D#000000 size=3D2>Okay I understand better now.&nbsp; =
You simply=20
want to provide extra descriptors to the SDK to select() on for =
you.&nbsp; Would=20
the assumption be that all descriptors passed to the SDK would be =
checked for=20
READ-ability only?&nbsp; Or would the aw_add_event() call need to be =
extended to=20
support checking for WRITE-ability as well?</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>I wonder though, can all types of events that an app =
wants to=20
check for be reduced to reading from a descriptor?&nbsp; It seems like a =

different mechanism would be required if, for example, the user wanted =
to be=20
notified whenever a message was pending in the application Window's =
message=20
queue.&nbsp; Also I'm not sure how you would implement a timer via a=20
descriptor...well for that matter, if all you want is a timer, you can =
just pass=20
that value into aw_wait().&nbsp; For example if you want your app to do=20
something once per second, just call aw_wait(1000) and then do whatever =
it is=20
when aw_wait() returns.&nbsp; See my example further below.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>I do want to point out that in practice, if you =
write a=20
&quot;polling&quot; style application this does not necessarily mean =
that you=20
are being horribly inefficient.&nbsp; It's true that you are being less=20
efficient than you could theoretically be, but I suspect that, for =
example, if=20
you actually wrote that code I suggested earlier where you called =
aw_wait(100)=20
and then _kbhit() to see if a key had a been pressed, that program would =
use=20
less than 1% of the available CPU on a P100.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Let's think a bit about how you would implement the=20
&quot;deer&quot; bot program you suggested, using the SDK as it is =
currently=20
implemented.&nbsp; Let's say what we wanted was a program that created =
ten deer,=20
scattered them around a meadow, and then had them randomly move around, =
stop,=20
chew grass, then periodically move again.&nbsp; The only other thing =
they would=20
do is run away when another avatar approaches, so the only events they =
would=20
want to respond to is AVATAR_ADD and AVATAR_CHANGE.&nbsp; Hmmm, the more =
I think=20
about this, the more this is sounding like a great SDK sample =
application.=20
:)</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Anyway, here's how I would do it.&nbsp; I would say =
that when=20
left alone, a deer would not decide to move along to a different patch =
of grass=20
more than once per second.&nbsp; That means we can use a 1-second =
resolution on=20
the event poll.&nbsp; So your code would look something like =
this:</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>for (;;) {</FONT></DIV>
<DIV><FONT size=3D2>&nbsp; if (aw_wait (1000))</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; break;</FONT></DIV>
<DIV><FONT size=3D2>&nbsp; for (i =3D 0; i &lt; NUM_DEAR; =
i++)</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; if (!(aw_random() % 60)) { /* =
let's say=20
that deer move to a new spot on average once per minute */</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp;&nbsp; /* move dear[i] here =
*/</FONT></DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;&nbsp; }</FONT></DIV>
<DIV><FONT size=3D2>}</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>This program would spend the vast majority of its =
time simply=20
sitting in select() waiting for humans to show up.&nbsp; Again I suspect =
that=20
with 10 dear, or even 100 dear, you would see CPU utilization of less =
than 5%,=20
probably more like 1%.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#000000 size=3D2>-Roland</FONT></DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: =
5px">
[View Quote] machine.&nbsp; But on the server side lately we've been seeing a =
lot of=20
interest in Linux, for example.&nbsp; I'm not even sure yet what =

platforms most people will be running their bots =
on.</FONT></FONT><FONT=20
size=3D-1>I'm assuming that, in the long term, SDK apps are =
going to more=20
or less parallel world servers in terms of platform of choice, =
since=20
most SDK apps will presumably be applications left running 24=20
hours/day.</FONT>&nbsp;<FONT=20
size=3D-1>-Roland</FONT>&nbsp;esumerfd<ESUMERFD at POBOXES.COM> =
wrote in=20
message &lt;<A=20
=
href=3D"mailto:3606D037.57F62323 at poboxes.com">3606D037.57F62323 at poboxes.c=
om</A>&gt;...=20
=20
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; =
PADDING-LEFT: 5px">That=20
is true enough Roland. Still a polling architecture but =
simpler than=20
writing threaded apps.=20
<P>So, you haven't commented on the idea of adding a=20
aw_add_event(int , function) funtion to the sdk yet?=20
<P>You mentioned in the thread about the GNU compiler that =
your=20
preference is to port to Sun/Unix machines before GNU =
because of=20
your belief that high performance bots will run on that type =
of=20
machine. If performance is important to you then why is it =
that you=20
are not addressing this inefficient polling architecture?=20
<P>I would even go as far as saying that a threaded API is =
much high=20
priority than having to worry about porting high powered =
servers.=20
<P>What is the reletive hardware mix of your customers at =
the=20
moment? Windows/Unix/Linix? What percentage of each would =
you say?=20
<P>Edward Sumerfield=20
[View Quote] blocking <BR>in a call to getch().&nbsp; Something like =
this:=20
<P>/* main event loop */ <BR>for (;;) { <BR>&nbsp; /* =
check for=20
AW events */ <BR>&nbsp; if (aw_wait(100)) =
<BR>&nbsp;&nbsp;&nbsp;=20
/* fatal error */ <BR>&nbsp;&nbsp;&nbsp; break; =
<BR>&nbsp; if=20
(_kbhit()) { <BR>&nbsp;&nbsp;&nbsp; /* process keystroke =
here...=20
*/ <BR>&nbsp; } <BR>}=20
<P>Check out the Windows SDK docs for more info on=20
_kbhit()...you may want to <BR>adjust the timeout =
parameter to=20
aw_wait() but 100 milliseconds means you are =
<BR>checking for=20
keyboard input 10 times per second which should be =
adequate=20
<BR>response time.=20
<P>-Roland=20
<P>&gt;You don't need windows unless you want to make =
the=20
interface pretty. A <BR>command <BR>&gt;line interface, =
like the=20
dos prompt, is possible with a console app and is =
<BR>much=20
<BR>&gt;easier to implement if you haven't done much=20
programming. <BR>&gt; <BR>&gt;Your problem is the =
architectural=20
design of the sdk. It is event driven so <BR>while =
<BR>&gt;your=20
program is in aw_wait it is waiting for a message from =
the=20
server. It <BR>is not <BR>&gt;able to wait for a =
keystroke at=20
the same time. <BR>&gt; <BR>&gt;An extension needs to be =
made to=20
the sdk for adding user events (Roland?), <BR>such as=20
<BR>&gt;keyboard events. For example, aw_add_event(int,=20
function); This would cause <BR>the aw <BR>&gt;sdk to =
wait on=20
your event as well as its own and call your function =
when it=20
<BR>is <BR>&gt;fired. <BR>&gt; <BR>&gt;In the mean time =
you can=20
use polling but it is not ideal. For example call=20
<BR>&gt;aw_wait(10) so it will wait for 10 milliseconds =
for an=20
sdk event to occur <BR>then <BR>&gt;drop back into your =
program.=20
Then in your console app you can use the <BR>standard C=20
<BR>&gt;function gets() which would allow you to enter a =
string=20
and press enter. <BR>You can <BR>&gt;then do what you =
like based=20
on the command entered. <BR>&gt; <BR>&gt;The problem is =
that=20
this is a blocking call. Once you have called gets it =
<BR>will=20
not <BR>&gt;return to your program until you press =
enter. While=20
it is waiting for you, <BR>your <BR>&gt;avatar will not =
be able=20
to react to events. <BR>&gt; <BR>&gt;If you want to get =
into=20
some more serious programing them you can design a=20
<BR>&gt;multi-threaded solution which would be a little =
more=20
realistic. Bare in <BR>mind that <BR>&gt;the aw sdk is =
not=20
thread safe so do not allow two different threads to =
call=20
<BR>the <BR>&gt;same api. <BR>&gt; <BR>&gt;The design =
would=20
involve one thread being dedicated to calling the aw=20
<BR>functions <BR>&gt;and a second thread being =
dedicated to=20
accepting input from the keyboard. <BR>There =
<BR>&gt;would be=20
one common command buffer that both threads read and a =
lock to=20
<BR>protect <BR>&gt;that buffer. <BR>&gt; <BR>&gt;So =
your=20
program would start up and kick off a seperate thread to =
do all=20
the <BR>aw <BR>&gt;init, start, enter and wait(10) stuff =
while=20
the first thread blocked on the <BR>gets() =
<BR>&gt;function. Now=20
the aw thread would be able to continue running even =
though=20
<BR>the <BR>&gt;gets() was blocked because it is running =
in a=20
seperate thread. <BR>&gt; <BR>&gt;In the aw thread, each =
time=20
the aw_wait drops out it would check the <BR>command =
lock,=20
<BR>&gt;if it is unlocked then it would lock it, check =
the=20
command buffer and act <BR>on what <BR>&gt;ever it found =
before=20
unlocking the lock. <BR>&gt; <BR>&gt;In the gets thread, =
each=20
time the enter key is pressed the lock is checked, =
<BR>if=20
<BR>&gt;unlocked then it must be locked and the new =
command=20
copied into the shared <BR>command <BR>&gt;buffer, =
before the=20
lock is unlocked again. <BR>&gt; <BR>&gt;This is a =
polling=20
solution so is not as cpu efficient as the sdk change =
but=20
<BR>would <BR>&gt;work. <BR>&gt; <BR>&gt;Good luck =
everyone.=20
<BR>&gt; <BR>&gt;Edward Sumerfield, esumerfd at poboxes.com =

[View Quote] <BR>&gt;&gt; &gt; wizardry at home.com <BR>&gt;&gt; &gt; <A =

=
href=3D"http://pcwizard.ml.org">http://pcwizard.ml.org</A>=20
<BR>&gt;&gt; &gt; <BR>&gt;&gt; &gt; Jan-willem De Bleser =
wrote=20
in message <BR>&lt;360300C7.4AD61B6B at mediaone.net&gt;... =

<BR>&gt;&gt; &gt; &gt;I have the following program =
(derived from=20
sample #1) which is a <BR>&gt;&gt; &gt; &gt;greetbot. It =
runs as=20
a console application in dos or windows. Im <BR>trying=20
<BR>&gt;&gt; &gt; &gt;to get it to accept commands at =
the=20
console so i can make the bot move <BR>&gt;&gt; &gt; =
&gt;and=20
talk at my command. how would i do that? <BR>&gt;&gt; =
&gt; &gt;=20
<BR>&gt;&gt; &gt; &gt;the program: <BR>&gt;&gt; &gt;=20
&gt;#include &lt;aw.h&gt;&nbsp; //i added the library =
and header=20
to my program <BR>&gt;&gt; &gt; &gt;directories. unless =
you have=20
done <BR>&gt;&gt; &gt;=20
=
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
//that, use &quot;aw.h&quot; <BR>&gt;&gt; &gt; =
&gt;#include=20
&lt;stdio.h&gt; <BR>&gt;&gt; &gt; &gt;#include =
&lt;stdlib.h&gt;=20
<BR>&gt;&gt; &gt; &gt;#include &lt;conio.h&gt; =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;void handle_avatar_add =
(void);=20
<BR>&gt;&gt; &gt; &gt;void object_add (void); =
<BR>&gt;&gt; &gt;=20
&gt;void avatar_delete (void); <BR>&gt;&gt; &gt; =
&gt;void=20
input(char command[100]); <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt;=20
&gt; &gt;main (int argc, char *argv[]) <BR>&gt;&gt; &gt; =
&gt;{=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; int =
rc;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; char junk[1]; <BR>&gt;&gt; =
&gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; /* check command line =
*/=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (argc &lt; 3) { =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp;&nbsp;&nbsp; printf (&quot;Usage: %s =
number=20
password\n&quot;, argv[0]); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* initialize Active Worlds API */ =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp; if (rc =3D aw_init (AW_BUILD)) { <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to =
initialize API=20
(reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* install handler for avatar_add and =
object_add=20
event */ <BR>&gt;&gt; &gt; &gt;&nbsp; aw_event_set=20
(AW_EVENT_AVATAR_ADD, handle_avatar_add); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_event_set (AW_EVENT_OBJECT_ADD, =
object_add);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_event_set=20
(AW_EVENT_AVATAR_DELETE, avatar_delete); <BR>&gt;&gt; =
&gt; &gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* create bot instance */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =3D aw_create (0, 0, =
0)) {=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Unable to=20
create bot instance (reason %d)\n&quot;, rc); =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* log bot into the universe */ <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_int_set (AW_LOGIN_OWNER, atoi (argv[1]));=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_string_set=20
(AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_string_set (AW_LOGIN_APPLICATION, =
&quot;SDK Sample=20
Application #1&quot;); <BR>&gt;&gt; &gt; &gt;&nbsp;=20
aw_string_set (AW_LOGIN_NAME, &quot;Bot of Zasz&quot;);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =3D aw_login ()) {=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Unable to=20
login (reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt; &gt; =
printf=20
(&quot;Press any key to continue&quot;); <BR>&gt;&gt; =
&gt; &gt;=20
gets (junk); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; =
exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* log bot into the world =
called=20
&quot;beta&quot; */ <BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =
=3D=20
aw_enter (&quot;Beta&quot;, 0)) { <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to enter =
world=20
(reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* announce our position in the world */ =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; aw_int_set (AW_MY_X, 1000); /* 1W */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_int_set (AW_MY_Z, 1000); =
/* 1N=20
*/ <BR>&gt;&gt; &gt; &gt;&nbsp; aw_int_set (AW_MY_YAW, =
2250); /*=20
face towards GZ */ <BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =
=3D=20
aw_state_change ()) { <BR>&gt;&gt; &gt; =
&gt;&nbsp;&nbsp;&nbsp;=20
printf (&quot;Unable to change state (reason =
%d)\n&quot;, rc);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Press any=20
key to continue&quot;); <BR>&gt;&gt; &gt; &gt; gets =
(junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* main event loop */ <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
char req, command[81]; <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp; while (!aw_wait (-1)) <BR>&gt;&gt; &gt; &gt; =
;=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; /* =
close=20
everything down */ <BR>&gt;&gt; &gt; &gt;&nbsp; =
aw_destroy ();=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_term (); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; return 0; <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;} <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;void=20
handle_avatar_add (void) <BR>&gt;&gt; &gt; &gt;{ =
<BR>&gt;&gt;=20
&gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; char =
message[100];=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; =
sprintf=20
(message, &quot;Hello %s. Welcome to Beta.&quot;, =
aw_string=20
<BR>&gt;&gt; &gt; &gt;(AW_AVATAR_NAME)); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_say (message); <BR>&gt;&gt; &gt; =
&gt;&nbsp; /* log=20
the event to the console */ <BR>&gt;&gt; &gt; &gt;&nbsp; =
printf=20
(&quot;avatar_add: %s\n&quot;, aw_string =
(AW_AVATAR_NAME));=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;} =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;void object_add (void) =
<BR>&gt;&gt;=20
&gt; &gt;{ <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
printf (&quot;Someone has added a %s nearby&quot;, =
aw_string=20
<BR>(AW_OBJECT_MODEL)); <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;} <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;void=20
avatar_delete (void) <BR>&gt;&gt; &gt; &gt;{ =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; char message[100];=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; =
sprintf=20
(message, &quot;%s has left the building\n&quot;, =
aw_string=20
<BR>&gt;&gt; &gt; &gt;(AW_AVATAR_NAME)); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_say (message); <BR>&gt;&gt; &gt; =
&gt;&nbsp; printf=20
(&quot;avatar_delete: %s\n&quot;, aw_string =
(AW_AVATAR_NAME));=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;} =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; <BR>&gt;=20
<BR></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML=
>

------=_NextPart_000_0022_01BDE619.53EC2E00--

walter knupe

Oct 10, 1998, 3:59pm
This is a multi-part message in MIME format.

------=_NextPart_000_017E_01BDF488.7A98B640
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

The windows world is not POSIX :)

and therefore the select interface differs too. Under windows, it can =
check for SOCKETS only, and windows SOCKETs are not file descriptors.

therefore user-defined events which are not sockets can not be checked =
for this way.

Under windows, events coming in as Windows-Message to a window are much =
more likely...

Walter



esumerfd schrieb in Nachricht <3607CC15.6F2F8AE8 at poboxes.com>...
My apologies Roland, I must have seemed too pushy. I am a 12 year =
veteran in the computer consulting field and understand totally what you =
are going though. We customers can be very annoying at times. Especially =
what we think we know what we are talking about. You are doing an =
excellent job. Don't let us get to you.=20
You are making the right move in solidifying the release you have =
and when I get a darn C compiler I can use I will be right in there with =
you trying to use your API.=20

I would like to think that the comments we are making will =
contribute to the next version of the API and so I would like to =
continue these conversations if you have the time.=20

Let me explain a little more about aw_add_event().=20

Currently your code calls the socket() and connect() functions to =
create connections to the universe and world servers. The socket call =
returns file descriptors that you are adding to an array of file =
descriptors for passing to the select() call. Each time data becomes =
available on one of these file descriptors the select statement drops =
out and your code checks the file descriptor returned to see if the =
event came from the universe connection or the world connection.=20

OK, now we have a requirement to allow user applications to create =
their own files, sockets or timers and they have to have a way to use =
your select statement to do it.=20

You can create the following function=20

aw_add_event (file descriptor, function pointer) {=20

append file descriptor to end of array.=20
store function pointer into another array indexed by the =
file descriptor.=20
}=20

Now change your select function as follows:=20

array =3D { universe, world }=20

while (1) {=20

event =3D select (array)=20
if (event =3D universe) {=20

Read data from universe file descriptor=20
}=20
else if (event =3D=3D world) {=20

Read data from the world file descriptor=20
}=20
else {=20

look up function pointer using file descriptor=20
call users function;=20
}=20
}=20

Now you have a way for the application to add its own file =
descriptors to your sdks select loop. Applications can now implement =
their own timer based bot functions, dynamically receive weather =
information from a weather server and have their bots tell people, read =
random quotes from a file. All without impacting the performance of the =
application. Also, when bots get more sophisticated they will not be =
needlessly chewing up CPU time while polling the event queue, instead, =
your thousands of deer grazing in a distant meadow will only use CPU =
time when they need to be moving.=20

I have writing a number of there types of applications before and =
would be happy to add my experience to future developments. Please don't =
hesitate to ask.=20

Edward Sumerfield,=20
Pesky user.=20

[View Quote] Okay look, I'll be the first to admit that the SDK architecture =
is not perfect for all possible applications. At this point I don't =
want to get into an argument about which features are more important =
than others. The SDK is what I could come up with in the time =
available. Future considerations like Java support, GNU support, =
multi-threading support, etc. are all great ideas and no doubt would =
make the SDK even better. But that's what they are: future =
considerations. Once again, the goal was to get something, anything, =
out there for people to be able to use. As with all aspects of the =
Active Worlds architecture, the SDK is going to be a continually =
evolving work in progress. As time goes by, it will be improved and =
extended along with all other aspects of the platform. The current goal =
is to simply stabilize and test the current SDK more or less as is in =
order to release it for general use. Then we can start thinking about =
the next version. That said, I'm not sure I even understand the =
aw_add_event() suggestion...I don't know how you would add in external =
application-defined events into the SDK, because the SDK would need to =
know how to check for them. How would the programmer tell the SDK to =
check for his/her custom event, keeping in mind that the only event loop =
that the SDK has is a call to select()? I don't have any hard numbers on =
the hardware mix of our customers. Obviously since AW is a =
Windows-based platform just about everyone has a Windows machine. But =
on the server side lately we've been seeing a lot of interest in Linux, =
for example. I'm not even sure yet what platforms most people will be =
running their bots on.I'm assuming that, in the long term, SDK apps are =
going to more or less parallel world servers in terms of platform of =
choice, since most SDK apps will presumably be applications left running =
[View Quote] You mentioned in the thread about the GNU compiler that your =
preference is to port to Sun/Unix machines before GNU because of your =
belief that high performance bots will run on that type of machine. If =
performance is important to you then why is it that you are not =
addressing this inefficient polling architecture?=20

I would even go as far as saying that a threaded API is much =
high priority than having to worry about porting high powered servers.=20

What is the reletive hardware mix of your customers at the =
moment? Windows/Unix/Linix? What percentage of each would you say?=20

Edward Sumerfield=20

[View Quote] A multi-threaded solution isn't absolutely necessary =
here...if you are=20
developing a Windows console app then you can use the =
call _kbhit() to=20
determine if a key has been pressed in the console =
window to avoid blocking=20
in a call to getch(). Something like this:=20
/* main event loop */=20
for (;;) {=20
/* check for AW events */=20
if (aw_wait(100))=20
/* fatal error */=20
break;=20
if (_kbhit()) {=20
/* process keystroke here... */=20
}=20
}=20

Check out the Windows SDK docs for more info on =
_kbhit()...you may want to=20
adjust the timeout parameter to aw_wait() but 100 =
milliseconds means you are=20
checking for keyboard input 10 times per second which =
should be adequate=20
response time.=20

-Roland=20

>You don't need windows unless you want to make the =
interface pretty. A=20
command=20
>line interface, like the dos prompt, is possible with a =
console app and is=20
much=20
>easier to implement if you haven't done much =
programming.=20
>=20
>Your problem is the architectural design of the sdk. It =
is event driven so=20
while=20
>your program is in aw_wait it is waiting for a message =
from the server. It=20
is not=20
>able to wait for a keystroke at the same time.=20
>=20
>An extension needs to be made to the sdk for adding =
user events (Roland?),=20
such as=20
>keyboard events. For example, aw_add_event(int, =
function); This would cause=20
the aw=20
>sdk to wait on your event as well as its own and call =
your function when it=20
is=20
>fired.=20
>=20
>In the mean time you can use polling but it is not =
ideal. For example call=20
>aw_wait(10) so it will wait for 10 milliseconds for an =
sdk event to occur=20
then=20
>drop back into your program. Then in your console app =
you can use the=20
standard C=20
>function gets() which would allow you to enter a string =
and press enter.=20
You can=20
>then do what you like based on the command entered.=20
>=20
>The problem is that this is a blocking call. Once you =
have called gets it=20
will not=20
>return to your program until you press enter. While it =
is waiting for you,=20
your=20
>avatar will not be able to react to events.=20
>=20
>If you want to get into some more serious programing =
them you can design a=20
>multi-threaded solution which would be a little more =
realistic. Bare in=20
mind that=20
>the aw sdk is not thread safe so do not allow two =
different threads to call=20
the=20
>same api.=20
>=20
>The design would involve one thread being dedicated to =
calling the aw=20
functions=20
>and a second thread being dedicated to accepting input =
from the keyboard.=20
There=20
>would be one common command buffer that both threads =
read and a lock to=20
protect=20
>that buffer.=20
>=20
>So your program would start up and kick off a seperate =
thread to do all the=20
aw=20
>init, start, enter and wait(10) stuff while the first =
thread blocked on the=20
gets()=20
>function. Now the aw thread would be able to continue =
running even though=20
the=20
>gets() was blocked because it is running in a seperate =
thread.=20
>=20
>In the aw thread, each time the aw_wait drops out it =
would check the=20
command lock,=20
>if it is unlocked then it would lock it, check the =
command buffer and act=20
on what=20
>ever it found before unlocking the lock.=20
>=20
>In the gets thread, each time the enter key is pressed =
the lock is checked,=20
if=20
>unlocked then it must be locked and the new command =
copied into the shared=20
command=20
>buffer, before the lock is unlocked again.=20
>=20
>This is a polling solution so is not as cpu efficient =
as the sdk change but=20
would=20
>work.=20
>=20
>Good luck everyone.=20
>=20
>Edward Sumerfield, esumerfd at poboxes.com=20
>=20
[View Quote]

------=_NextPart_000_017E_01BDF488.7A98B640
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML>
<HEAD>

<META content=3Dtext/html;charset=3Diso-8859-1 =
http-equiv=3DContent-Type><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 =
Transitional//EN">
<META content=3D'"MSHTML 4.72.3110.7"' name=3DGENERATOR>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT color=3D#000000 size=3D2>The windows world is not POSIX =
:)</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>and therefore the select interface differs too. =
Under windows,=20
it can check for SOCKETS only, and windows SOCKETs are not file=20
descriptors.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>therefore user-defined events which are not sockets =
can not be=20
checked for this way.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Under windows, events coming in as Windows-Message =
to a window=20
are much more likely...</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Walter</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: =
5px">
<DIV>esumerfd<ESUMERFD at POBOXES.COM> schrieb in Nachricht &lt;<A=20
=
href=3D"mailto:3607CC15.6F2F8AE8 at poboxes.com">3607CC15.6F2F8AE8 at poboxes.c=
om</A>&gt;...</DIV>My=20
apologies Roland, I must have seemed too pushy. I am a 12 year =
veteran in=20
the computer consulting field and understand totally what you are =
going=20
though. We customers can be very annoying at times. Especially what =
we think=20
we know what we are talking about. You are doing an excellent job. =
Don't let=20
us get to you.=20
<P>You are making the right move in solidifying the release you have =
and=20
when I get a darn C compiler I can use I will be right in there with =
you=20
trying to use your API.=20
<P>I would like to think that the comments we are making will =
contribute to=20
the next version of the API and so I would like to continue these=20
conversations if you have the time.=20
<P>Let me explain a little more about aw_add_event().=20
<P>Currently your code calls the socket() and connect() functions to =
create=20
connections to the universe and world servers. The socket call =
returns file=20
descriptors that you are adding to an array of file descriptors for =
passing=20
to the select() call. Each time data becomes available on one of =
these file=20
descriptors the select statement drops out and your code checks the =
file=20
descriptor returned to see if the event came from the universe =
connection or=20
the world connection.=20
<P>OK, now we have a requirement to allow user applications to =
create their=20
own files, sockets or timers and they have to have a way to use your =
select=20
statement to do it.=20
<P>You can create the following function=20
<P>&nbsp;&nbsp;&nbsp; aw_add_event (file descriptor, function =
pointer) {=20
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; append file descriptor =
to end=20
of array. <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; store =
function=20
pointer into another array indexed by the file descriptor.=20
<BR>&nbsp;&nbsp;&nbsp; }=20
<P>Now change your select function as follows:=20
<P>&nbsp;&nbsp;&nbsp; array =3D { universe, world }=20
<P>&nbsp;&nbsp;&nbsp; while (1) {=20
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; event =3D select =
(array)=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (event =3D =
universe) {=20
=
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
Read=20
data from universe file descriptor=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (event =3D=3D =
world) {=20
=
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
Read=20
data from the world file descriptor=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {=20
=
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
look=20
up function pointer using file descriptor=20
=
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
call=20
users function; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }=20
<BR>&nbsp;&nbsp;&nbsp; }=20
<P>Now you have a way for the application to add its own file =
descriptors to=20
your sdks select loop. Applications can now implement their own =
timer based=20
bot functions, dynamically receive weather information from a =
weather server=20
and have their bots tell people, read random quotes from a file. All =
without=20
impacting the performance of the application. Also, when bots get =
more=20
sophisticated they will not be needlessly chewing up CPU time while =
polling=20
the event queue, instead, your thousands of deer grazing in a =
distant meadow=20
will only use CPU time when they need to be moving.=20
<P>I have writing a number of there types of applications before and =
would=20
be happy to add my experience to future developments. Please don't =
hesitate=20
to ask.=20
<P>Edward Sumerfield, <BR>Pesky user.=20
[View Quote] machine.&nbsp; But on the server side lately we've been seeing a =
lot of=20
interest in Linux, for example.&nbsp; I'm not even sure yet what =

platforms most people will be running their bots =
on.</FONT></FONT><FONT=20
size=3D-1>I'm assuming that, in the long term, SDK apps are =
going to more=20
or less parallel world servers in terms of platform of choice, =
since=20
most SDK apps will presumably be applications left running 24=20
hours/day.</FONT>&nbsp;<FONT=20
size=3D-1>-Roland</FONT>&nbsp;esumerfd<ESUMERFD at POBOXES.COM> =
wrote in=20
message &lt;<A=20
=
href=3D"mailto:3606D037.57F62323 at poboxes.com">3606D037.57F62323 at poboxes.c=
om</A>&gt;...=20
=20
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; =
PADDING-LEFT: 5px">That=20
is true enough Roland. Still a polling architecture but =
simpler than=20
writing threaded apps.=20
<P>So, you haven't commented on the idea of adding a=20
aw_add_event(int , function) funtion to the sdk yet?=20
<P>You mentioned in the thread about the GNU compiler that =
your=20
preference is to port to Sun/Unix machines before GNU =
because of=20
your belief that high performance bots will run on that type =
of=20
machine. If performance is important to you then why is it =
that you=20
are not addressing this inefficient polling architecture?=20
<P>I would even go as far as saying that a threaded API is =
much high=20
priority than having to worry about porting high powered =
servers.=20
<P>What is the reletive hardware mix of your customers at =
the=20
moment? Windows/Unix/Linix? What percentage of each would =
you say?=20
<P>Edward Sumerfield=20
[View Quote] blocking <BR>in a call to getch().&nbsp; Something like =
this:=20
<P>/* main event loop */ <BR>for (;;) { <BR>&nbsp; /* =
check for=20
AW events */ <BR>&nbsp; if (aw_wait(100)) =
<BR>&nbsp;&nbsp;&nbsp;=20
/* fatal error */ <BR>&nbsp;&nbsp;&nbsp; break; =
<BR>&nbsp; if=20
(_kbhit()) { <BR>&nbsp;&nbsp;&nbsp; /* process keystroke =
here...=20
*/ <BR>&nbsp; } <BR>}=20
<P>Check out the Windows SDK docs for more info on=20
_kbhit()...you may want to <BR>adjust the timeout =
parameter to=20
aw_wait() but 100 milliseconds means you are =
<BR>checking for=20
keyboard input 10 times per second which should be =
adequate=20
<BR>response time.=20
<P>-Roland=20
<P>&gt;You don't need windows unless you want to make =
the=20
interface pretty. A <BR>command <BR>&gt;line interface, =
like the=20
dos prompt, is possible with a console app and is =
<BR>much=20
<BR>&gt;easier to implement if you haven't done much=20
programming. <BR>&gt; <BR>&gt;Your problem is the =
architectural=20
design of the sdk. It is event driven so <BR>while =
<BR>&gt;your=20
program is in aw_wait it is waiting for a message from =
the=20
server. It <BR>is not <BR>&gt;able to wait for a =
keystroke at=20
the same time. <BR>&gt; <BR>&gt;An extension needs to be =
made to=20
the sdk for adding user events (Roland?), <BR>such as=20
<BR>&gt;keyboard events. For example, aw_add_event(int,=20
function); This would cause <BR>the aw <BR>&gt;sdk to =
wait on=20
your event as well as its own and call your function =
when it=20
<BR>is <BR>&gt;fired. <BR>&gt; <BR>&gt;In the mean time =
you can=20
use polling but it is not ideal. For example call=20
<BR>&gt;aw_wait(10) so it will wait for 10 milliseconds =
for an=20
sdk event to occur <BR>then <BR>&gt;drop back into your =
program.=20
Then in your console app you can use the <BR>standard C=20
<BR>&gt;function gets() which would allow you to enter a =
string=20
and press enter. <BR>You can <BR>&gt;then do what you =
like based=20
on the command entered. <BR>&gt; <BR>&gt;The problem is =
that=20
this is a blocking call. Once you have called gets it =
<BR>will=20
not <BR>&gt;return to your program until you press =
enter. While=20
it is waiting for you, <BR>your <BR>&gt;avatar will not =
be able=20
to react to events. <BR>&gt; <BR>&gt;If you want to get =
into=20
some more serious programing them you can design a=20
<BR>&gt;multi-threaded solution which would be a little =
more=20
realistic. Bare in <BR>mind that <BR>&gt;the aw sdk is =
not=20
thread safe so do not allow two different threads to =
call=20
<BR>the <BR>&gt;same api. <BR>&gt; <BR>&gt;The design =
would=20
involve one thread being dedicated to calling the aw=20
<BR>functions <BR>&gt;and a second thread being =
dedicated to=20
accepting input from the keyboard. <BR>There =
<BR>&gt;would be=20
one common command buffer that both threads read and a =
lock to=20
<BR>protect <BR>&gt;that buffer. <BR>&gt; <BR>&gt;So =
your=20
program would start up and kick off a seperate thread to =
do all=20
the <BR>aw <BR>&gt;init, start, enter and wait(10) stuff =
while=20
the first thread blocked on the <BR>gets() =
<BR>&gt;function. Now=20
the aw thread would be able to continue running even =
though=20
<BR>the <BR>&gt;gets() was blocked because it is running =
in a=20
seperate thread. <BR>&gt; <BR>&gt;In the aw thread, each =
time=20
the aw_wait drops out it would check the <BR>command =
lock,=20
<BR>&gt;if it is unlocked then it would lock it, check =
the=20
command buffer and act <BR>on what <BR>&gt;ever it found =
before=20
unlocking the lock. <BR>&gt; <BR>&gt;In the gets thread, =
each=20
time the enter key is pressed the lock is checked, =
<BR>if=20
<BR>&gt;unlocked then it must be locked and the new =
command=20
copied into the shared <BR>command <BR>&gt;buffer, =
before the=20
lock is unlocked again. <BR>&gt; <BR>&gt;This is a =
polling=20
solution so is not as cpu efficient as the sdk change =
but=20
<BR>would <BR>&gt;work. <BR>&gt; <BR>&gt;Good luck =
everyone.=20
<BR>&gt; <BR>&gt;Edward Sumerfield, esumerfd at poboxes.com =

[View Quote] <BR>&gt;&gt; &gt; wizardry at home.com <BR>&gt;&gt; &gt; <A =

=
href=3D"http://pcwizard.ml.org">http://pcwizard.ml.org</A>=20
<BR>&gt;&gt; &gt; <BR>&gt;&gt; &gt; Jan-willem De Bleser =
wrote=20
in message <BR>&lt;360300C7.4AD61B6B at mediaone.net&gt;... =

<BR>&gt;&gt; &gt; &gt;I have the following program =
(derived from=20
sample #1) which is a <BR>&gt;&gt; &gt; &gt;greetbot. It =
runs as=20
a console application in dos or windows. Im <BR>trying=20
<BR>&gt;&gt; &gt; &gt;to get it to accept commands at =
the=20
console so i can make the bot move <BR>&gt;&gt; &gt; =
&gt;and=20
talk at my command. how would i do that? <BR>&gt;&gt; =
&gt; &gt;=20
<BR>&gt;&gt; &gt; &gt;the program: <BR>&gt;&gt; &gt;=20
&gt;#include &lt;aw.h&gt;&nbsp; //i added the library =
and header=20
to my program <BR>&gt;&gt; &gt; &gt;directories. unless =
you have=20
done <BR>&gt;&gt; &gt;=20
=
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
//that, use &quot;aw.h&quot; <BR>&gt;&gt; &gt; =
&gt;#include=20
&lt;stdio.h&gt; <BR>&gt;&gt; &gt; &gt;#include =
&lt;stdlib.h&gt;=20
<BR>&gt;&gt; &gt; &gt;#include &lt;conio.h&gt; =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;void handle_avatar_add =
(void);=20
<BR>&gt;&gt; &gt; &gt;void object_add (void); =
<BR>&gt;&gt; &gt;=20
&gt;void avatar_delete (void); <BR>&gt;&gt; &gt; =
&gt;void=20
input(char command[100]); <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt;=20
&gt; &gt;main (int argc, char *argv[]) <BR>&gt;&gt; &gt; =
&gt;{=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; int =
rc;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; char junk[1]; <BR>&gt;&gt; =
&gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; /* check command line =
*/=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (argc &lt; 3) { =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp;&nbsp;&nbsp; printf (&quot;Usage: %s =
number=20
password\n&quot;, argv[0]); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* initialize Active Worlds API */ =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp; if (rc =3D aw_init (AW_BUILD)) { <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to =
initialize API=20
(reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* install handler for avatar_add and =
object_add=20
event */ <BR>&gt;&gt; &gt; &gt;&nbsp; aw_event_set=20
(AW_EVENT_AVATAR_ADD, handle_avatar_add); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_event_set (AW_EVENT_OBJECT_ADD, =
object_add);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_event_set=20
(AW_EVENT_AVATAR_DELETE, avatar_delete); <BR>&gt;&gt; =
&gt; &gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* create bot instance */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =3D aw_create (0, 0, =
0)) {=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Unable to=20
create bot instance (reason %d)\n&quot;, rc); =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* log bot into the universe */ <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_int_set (AW_LOGIN_OWNER, atoi (argv[1]));=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_string_set=20
(AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_string_set (AW_LOGIN_APPLICATION, =
&quot;SDK Sample=20
Application #1&quot;); <BR>&gt;&gt; &gt; &gt;&nbsp;=20
aw_string_set (AW_LOGIN_NAME, &quot;Bot of Zasz&quot;);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =3D aw_login ()) {=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Unable to=20
login (reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt; &gt; =
printf=20
(&quot;Press any key to continue&quot;); <BR>&gt;&gt; =
&gt; &gt;=20
gets (junk); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; =
exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* log bot into the world =
called=20
&quot;beta&quot; */ <BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =
=3D=20
aw_enter (&quot;Beta&quot;, 0)) { <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to enter =
world=20
(reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* announce our position in the world */ =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; aw_int_set (AW_MY_X, 1000); /* 1W */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_int_set (AW_MY_Z, 1000); =
/* 1N=20
*/ <BR>&gt;&gt; &gt; &gt;&nbsp; aw_int_set (AW_MY_YAW, =
2250); /*=20
face towards GZ */ <BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =
=3D=20
aw_state_change ()) { <BR>&gt;&gt; &gt; =
&gt;&nbsp;&nbsp;&nbsp;=20
printf (&quot;Unable to change state (reason =
%d)\n&quot;, rc);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Press any=20
key to continue&quot;); <BR>&gt;&gt; &gt; &gt; gets =
(junk);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* main event loop */ <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
char req, command[81]; <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp; while (!aw_wait (-1)) <BR>&gt;&gt; &gt; &gt; =
;=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; /* =
close=20
everything down */ <BR>&gt;&gt; &gt; &gt;&nbsp; =
aw_destroy ();=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_term (); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; return 0; <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;} <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;void=20
handle_avatar_add (void) <BR>&gt;&gt; &gt; &gt;{ =
<BR>&gt;&gt;=20
&gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; char =
message[100];=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; =
sprintf=20
(message, &quot;Hello %s. Welcome to Beta.&quot;, =
aw_string=20
<BR>&gt;&gt; &gt; &gt;(AW_AVATAR_NAME)); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_say (message); <BR>&gt;&gt; &gt; =
&gt;&nbsp; /* log=20
the event to the console */ <BR>&gt;&gt; &gt; &gt;&nbsp; =
printf=20
(&quot;avatar_add: %s\n&quot;, aw_string =
(AW_AVATAR_NAME));=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;} =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;void object_add (void) =
<BR>&gt;&gt;=20
&gt; &gt;{ <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
printf (&quot;Someone has added a %s nearby&quot;, =
aw_string=20
<BR>(AW_OBJECT_MODEL)); <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;} <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;void=20
avatar_delete (void) <BR>&gt;&gt; &gt; &gt;{ =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; char message[100];=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; =
sprintf=20
(message, &quot;%s has left the building\n&quot;, =
aw_string=20
<BR>&gt;&gt; &gt; &gt;(AW_AVATAR_NAME)); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_say (message); <BR>&gt;&gt; &gt; =
&gt;&nbsp; printf=20
(&quot;avatar_delete: %s\n&quot;, aw_string =
(AW_AVATAR_NAME));=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;} =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; <BR>&gt;=20
<BR></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML=
>

------=_NextPart_000_017E_01BDF488.7A98B640--

edward sumerfield

Oct 10, 1998, 5:13pm
This is a multi-part message in MIME format.

------=_NextPart_000_0104_01BDF460.92880F30
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Interesting. Walkter, I hope you keep contributing to this newsgroup. =
You keep teaching me things.=20

So does windows sockets not being file descriptors give us a problem =
with this new aw_add_event design? If can we just pass these non FD to =
the same function?

If the windows select only listens for sockets how would you architect a =
program that listens for windows messages and sockets?

Edward Sumerfield
[View Quote] I would like to think that the comments we are making will =
contribute to the next version of the API and so I would like to =
continue these conversations if you have the time.=20

Let me explain a little more about aw_add_event().=20

Currently your code calls the socket() and connect() functions =
to create connections to the universe and world servers. The socket call =
returns file descriptors that you are adding to an array of file =
descriptors for passing to the select() call. Each time data becomes =
available on one of these file descriptors the select statement drops =
out and your code checks the file descriptor returned to see if the =
event came from the universe connection or the world connection.=20

OK, now we have a requirement to allow user applications to =
create their own files, sockets or timers and they have to have a way to =
use your select statement to do it.=20

You can create the following function=20

aw_add_event (file descriptor, function pointer) {=20

append file descriptor to end of array.=20
store function pointer into another array indexed by the =
file descriptor.=20
}=20

Now change your select function as follows:=20

array =3D { universe, world }=20

while (1) {=20

event =3D select (array)=20
if (event =3D universe) {=20

Read data from universe file descriptor=20
}=20
else if (event =3D=3D world) {=20

Read data from the world file descriptor=20
}=20
else {=20

look up function pointer using file descriptor=20
call users function;=20
}=20
}=20

Now you have a way for the application to add its own file =
descriptors to your sdks select loop. Applications can now implement =
their own timer based bot functions, dynamically receive weather =
information from a weather server and have their bots tell people, read =
random quotes from a file. All without impacting the performance of the =
application. Also, when bots get more sophisticated they will not be =
needlessly chewing up CPU time while polling the event queue, instead, =
your thousands of deer grazing in a distant meadow will only use CPU =
time when they need to be moving.=20

I have writing a number of there types of applications before =
and would be happy to add my experience to future developments. Please =
don't hesitate to ask.=20

Edward Sumerfield,=20
Pesky user.=20

[View Quote] Okay look, I'll be the first to admit that the SDK =
architecture is not perfect for all possible applications. At this =
point I don't want to get into an argument about which features are more =
important than others. The SDK is what I could come up with in the time =
available. Future considerations like Java support, GNU support, =
multi-threading support, etc. are all great ideas and no doubt would =
make the SDK even better. But that's what they are: future =
considerations. Once again, the goal was to get something, anything, =
out there for people to be able to use. As with all aspects of the =
Active Worlds architecture, the SDK is going to be a continually =
evolving work in progress. As time goes by, it will be improved and =
extended along with all other aspects of the platform. The current goal =
is to simply stabilize and test the current SDK more or less as is in =
order to release it for general use. Then we can start thinking about =
the next version. That said, I'm not sure I even understand the =
aw_add_event() suggestion...I don't know how you would add in external =
application-defined events into the SDK, because the SDK would need to =
know how to check for them. How would the programmer tell the SDK to =
check for his/her custom event, keeping in mind that the only event loop =
that the SDK has is a call to select()? I don't have any hard numbers on =
the hardware mix of our customers. Obviously since AW is a =
Windows-based platform just about everyone has a Windows machine. But =
on the server side lately we've been seeing a lot of interest in Linux, =
for example. I'm not even sure yet what platforms most people will be =
running their bots on.I'm assuming that, in the long term, SDK apps are =
going to more or less parallel world servers in terms of platform of =
choice, since most SDK apps will presumably be applications left running =
[View Quote] You mentioned in the thread about the GNU compiler that =
your preference is to port to Sun/Unix machines before GNU because of =
your belief that high performance bots will run on that type of machine. =
If performance is important to you then why is it that you are not =
addressing this inefficient polling architecture?=20

I would even go as far as saying that a threaded API is =
much high priority than having to worry about porting high powered =
servers.=20

What is the reletive hardware mix of your customers at =
the moment? Windows/Unix/Linix? What percentage of each would you say?=20

Edward Sumerfield=20

[View Quote] A multi-threaded solution isn't absolutely necessary =
here...if you are=20
developing a Windows console app then you can use =
the call _kbhit() to=20
determine if a key has been pressed in the console =
window to avoid blocking=20
in a call to getch(). Something like this:=20
/* main event loop */=20
for (;;) {=20
/* check for AW events */=20
if (aw_wait(100))=20
/* fatal error */=20
break;=20
if (_kbhit()) {=20
/* process keystroke here... */=20
}=20
}=20

Check out the Windows SDK docs for more info on =
_kbhit()...you may want to=20
adjust the timeout parameter to aw_wait() but 100 =
milliseconds means you are=20
checking for keyboard input 10 times per second =
which should be adequate=20
response time.=20

-Roland=20

>You don't need windows unless you want to make the =
interface pretty. A=20
command=20
>line interface, like the dos prompt, is possible =
with a console app and is=20
much=20
>easier to implement if you haven't done much =
programming.=20
>=20
>Your problem is the architectural design of the =
sdk. It is event driven so=20
while=20
>your program is in aw_wait it is waiting for a =
message from the server. It=20
is not=20
>able to wait for a keystroke at the same time.=20
>=20
>An extension needs to be made to the sdk for adding =
user events (Roland?),=20
such as=20
>keyboard events. For example, aw_add_event(int, =
function); This would cause=20
the aw=20
>sdk to wait on your event as well as its own and =
call your function when it=20
is=20
>fired.=20
>=20
>In the mean time you can use polling but it is not =
ideal. For example call=20
>aw_wait(10) so it will wait for 10 milliseconds for =
an sdk event to occur=20
then=20
>drop back into your program. Then in your console =
app you can use the=20
standard C=20
>function gets() which would allow you to enter a =
string and press enter.=20
You can=20
>then do what you like based on the command entered. =

>=20
>The problem is that this is a blocking call. Once =
you have called gets it=20
will not=20
>return to your program until you press enter. While =
it is waiting for you,=20
your=20
>avatar will not be able to react to events.=20
>=20
>If you want to get into some more serious =
programing them you can design a=20
>multi-threaded solution which would be a little =
more realistic. Bare in=20
mind that=20
>the aw sdk is not thread safe so do not allow two =
different threads to call=20
the=20
>same api.=20
>=20
>The design would involve one thread being dedicated =
to calling the aw=20
functions=20
>and a second thread being dedicated to accepting =
input from the keyboard.=20
There=20
>would be one common command buffer that both =
threads read and a lock to=20
protect=20
>that buffer.=20
>=20
>So your program would start up and kick off a =
seperate thread to do all the=20
aw=20
>init, start, enter and wait(10) stuff while the =
first thread blocked on the=20
gets()=20
>function. Now the aw thread would be able to =
continue running even though=20
the=20
>gets() was blocked because it is running in a =
seperate thread.=20
>=20
>In the aw thread, each time the aw_wait drops out =
it would check the=20
command lock,=20
>if it is unlocked then it would lock it, check the =
command buffer and act=20
on what=20
>ever it found before unlocking the lock.=20
>=20
>In the gets thread, each time the enter key is =
pressed the lock is checked,=20
if=20
>unlocked then it must be locked and the new command =
copied into the shared=20
command=20
>buffer, before the lock is unlocked again.=20
>=20
>This is a polling solution so is not as cpu =
efficient as the sdk change but=20
would=20
>work.=20
>=20
>Good luck everyone.=20
>=20
>Edward Sumerfield, esumerfd at poboxes.com=20
>=20
[View Quote] argv[2]);=20
Sample Application #1");=20
Zasz");=20
rc);=20
%d)\n", rc);=20
towards GZ */=20
%d)\n", rc);=20
Beta.", aw_string=20
(AW_AVATAR_NAME));=20
aw_string=20
(AW_OBJECT_MODEL));=20
building\n", aw_string=20
(AW_AVATAR_NAME));=20
>=20



------=_NextPart_000_0104_01BDF460.92880F30
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML>
<HEAD>

<META content=3Dtext/html;charset=3Diso-8859-1 =
http-equiv=3DContent-Type><!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 =
HTML//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<META content=3D'"MSHTML 4.72.2106.6"' name=3DGENERATOR>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT color=3D#000000 size=3D2>Interesting. Walkter, I hope you =
keep=20
contributing to this newsgroup. You keep teaching me things. =
</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#000000 size=3D2>So does windows sockets not being =
file=20
descriptors give us a problem with this new aw_add_event design? If can =
we just=20
pass these non FD to the same function?</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>If the windows select only listens for sockets how =
would you=20
architect a program that listens for windows messages and =
sockets?</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Edward Sumerfield</FONT></DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: =
5px">
[View Quote] descriptors for passing to the select() call. Each time data =
becomes=20
available on one of these file descriptors the select statement =
drops=20
out and your code checks the file descriptor returned to see if =
the=20
event came from the universe connection or the world connection. =

<P>OK, now we have a requirement to allow user applications to =
create=20
their own files, sockets or timers and they have to have a way =
to use=20
your select statement to do it.=20
<P>You can create the following function=20
<P>&nbsp;&nbsp;&nbsp; aw_add_event (file descriptor, function =
pointer) {=20
=20
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; append file =
descriptor to=20
end of array. <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
store=20
function pointer into another array indexed by the file =
descriptor.=20
<BR>&nbsp;&nbsp;&nbsp; }=20
<P>Now change your select function as follows:=20
<P>&nbsp;&nbsp;&nbsp; array =3D { universe, world }=20
<P>&nbsp;&nbsp;&nbsp; while (1) {=20
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; event =3D select =
(array)=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (event =3D =
universe) {=20
=
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
Read data from universe file descriptor=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if (event =
=3D=3D world)=20
{=20
=
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
Read data from the world file descriptor=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }=20
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else {=20
=
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
look up function pointer using file descriptor=20
=
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
call users function; =
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }=20
<BR>&nbsp;&nbsp;&nbsp; }=20
<P>Now you have a way for the application to add its own file=20
descriptors to your sdks select loop. Applications can now =
implement=20
their own timer based bot functions, dynamically receive weather =

information from a weather server and have their bots tell =
people, read=20
random quotes from a file. All without impacting the performance =
of the=20
application. Also, when bots get more sophisticated they will =
not be=20
needlessly chewing up CPU time while polling the event queue, =
instead,=20
your thousands of deer grazing in a distant meadow will only use =
CPU=20
time when they need to be moving.=20
<P>I have writing a number of there types of applications before =
and=20
would be happy to add my experience to future developments. =
Please don't=20
hesitate to ask.=20
<P>Edward Sumerfield, <BR>Pesky user.=20
[View Quote] stabilize and test the current SDK more or less as is in =
order to=20
release it for general use.&nbsp; Then we can start thinking =
about=20
the next version.</FONT></FONT>&nbsp;<FONT size=3D-1>That =
said, I'm=20
not sure I even understand the aw_add_event() suggestion...I =
don't=20
know how you would add in external application-defined =
events into=20
the SDK, because the SDK would need to know how to check for =

them.&nbsp; How would the programmer tell the SDK to check =
for=20
his/her custom event, keeping in mind that the only event =
loop that=20
the SDK has is a call to select()?</FONT>&nbsp;<FONT=20
color=3D#000000><FONT size=3D-1>I don't have any hard =
numbers on the=20
hardware mix of our customers.&nbsp; Obviously since AW is a =

Windows-based platform just about everyone has a Windows=20
machine.&nbsp; But on the server side lately we've been =
seeing a lot=20
of interest in Linux, for example.&nbsp; I'm not even sure =
yet what=20
platforms most people will be running their bots=20
on.</FONT></FONT><FONT size=3D-1>I'm assuming that, in the =
long term,=20
SDK apps are going to more or less parallel world servers in =
terms=20
of platform of choice, since most SDK apps will presumably =
be=20
applications left running 24 hours/day.</FONT>&nbsp;<FONT=20
size=3D-1>-Roland</FONT>&nbsp;esumerfd<ESUMERFD at POBOXES.COM> =
wrote in=20
message &lt;<A=20
=
href=3D"mailto:3606D037.57F62323 at poboxes.com">3606D037.57F62323 at poboxes.c=
om</A>&gt;...=20
=20
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; =
PADDING-LEFT: 5px">That=20
is true enough Roland. Still a polling architecture but =
simpler=20
than writing threaded apps.=20
<P>So, you haven't commented on the idea of adding a=20
aw_add_event(int , function) funtion to the sdk yet?=20
<P>You mentioned in the thread about the GNU compiler =
that your=20
preference is to port to Sun/Unix machines before GNU =
because of=20
your belief that high performance bots will run on that =
type of=20
machine. If performance is important to you then why is =
it that=20
you are not addressing this inefficient polling =
architecture?=20
<P>I would even go as far as saying that a threaded API =
is much=20
high priority than having to worry about porting high =
powered=20
servers.=20
<P>What is the reletive hardware mix of your customers =
at the=20
moment? Windows/Unix/Linix? What percentage of each =
would you=20
say?=20
<P>Edward Sumerfield=20
[View Quote] continue running even though <BR>the <BR>&gt;gets() =
was=20
blocked because it is running in a seperate thread. =
<BR>&gt;=20
<BR>&gt;In the aw thread, each time the aw_wait =
drops out it=20
would check the <BR>command lock, <BR>&gt;if it is =
unlocked=20
then it would lock it, check the command buffer and =
act=20
<BR>on what <BR>&gt;ever it found before unlocking =
the lock.=20
<BR>&gt; <BR>&gt;In the gets thread, each time the =
enter key=20
is pressed the lock is checked, <BR>if =
<BR>&gt;unlocked then=20
it must be locked and the new command copied into =
the shared=20
<BR>command <BR>&gt;buffer, before the lock is =
unlocked=20
again. <BR>&gt; <BR>&gt;This is a polling solution =
so is not=20
as cpu efficient as the sdk change but <BR>would=20
<BR>&gt;work. <BR>&gt; <BR>&gt;Good luck everyone. =
<BR>&gt;=20
<BR>&gt;Edward Sumerfield, esumerfd at poboxes.com =
<BR>&gt;=20
[View Quote] &quot;while (!aw_wait <BR>(-1)) <BR>&gt;&gt; =
!newline!&nbsp;=20
;&quot;, but i cant get it to work <BR>&gt;&gt; =
<BR>&gt;&gt;=20
[View Quote] <BR>&gt;&gt; &gt; &gt;to get it to accept commands =
at the=20
console so i can make the bot move <BR>&gt;&gt; &gt; =
&gt;and=20
talk at my command. how would i do that? =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;the program: <BR>&gt;&gt; =
&gt;=20
&gt;#include &lt;aw.h&gt;&nbsp; //i added the =
library and=20
header to my program <BR>&gt;&gt; &gt; =
&gt;directories.=20
unless you have done <BR>&gt;&gt; &gt;=20
=
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
//that, use &quot;aw.h&quot; <BR>&gt;&gt; &gt; =
&gt;#include=20
&lt;stdio.h&gt; <BR>&gt;&gt; &gt; &gt;#include=20
&lt;stdlib.h&gt; <BR>&gt;&gt; &gt; &gt;#include=20
&lt;conio.h&gt; <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;void handle_avatar_add (void); <BR>&gt;&gt; &gt; =

&gt;void object_add (void); <BR>&gt;&gt; &gt; =
&gt;void=20
avatar_delete (void); <BR>&gt;&gt; &gt; &gt;void =
input(char=20
command[100]); <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;main (int argc, char *argv[]) <BR>&gt;&gt; &gt; =
&gt;{=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; =
int rc;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; char junk[1]; =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; /* check command =
line */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (argc &lt; 3) { =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp;&nbsp;&nbsp; printf (&quot;Usage: %s =
number=20
password\n&quot;, argv[0]); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key =
to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk); =

<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; =
&gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* initialize Active =
Worlds API=20
*/ <BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =3D aw_init =
(AW_BUILD))=20
{ <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf=20
(&quot;Unable to initialize API (reason %d)\n&quot;, =
rc);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Press=20
any key to continue&quot;); <BR>&gt;&gt; &gt; &gt; =
gets=20
(junk); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; =
exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; =
&gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* install handler for=20
avatar_add and object_add event */ <BR>&gt;&gt; &gt; =

&gt;&nbsp; aw_event_set (AW_EVENT_AVATAR_ADD,=20
handle_avatar_add); <BR>&gt;&gt; &gt; &gt;&nbsp;=20
aw_event_set (AW_EVENT_OBJECT_ADD, object_add); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; aw_event_set =
(AW_EVENT_AVATAR_DELETE,=20
avatar_delete); <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; /* create bot instance */ <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; if (rc =3D aw_create (0, 0, 0)) { =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to =
create bot=20
instance (reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt; =

&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key =
to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk); =

<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; =
&gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* log bot into the =
universe */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; aw_int_set =
(AW_LOGIN_OWNER,=20
atoi (argv[1])); <BR>&gt;&gt; &gt; &gt;&nbsp; =
aw_string_set=20
(AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]); <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; aw_string_set (AW_LOGIN_APPLICATION, =
&quot;SDK=20
Sample Application #1&quot;); <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
aw_string_set (AW_LOGIN_NAME, &quot;Bot of =
Zasz&quot;);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =3D aw_login ()) =
{=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf=20
(&quot;Unable to login (reason %d)\n&quot;, rc);=20
<BR>&gt;&gt; &gt; &gt; printf (&quot;Press any key =
to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk); =

<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; =
&gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* log bot into the =
world=20
called &quot;beta&quot; */ <BR>&gt;&gt; &gt; =
&gt;&nbsp; if=20
(rc =3D aw_enter (&quot;Beta&quot;, 0)) { =
<BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Unable to enter =
world=20
(reason %d)\n&quot;, rc); <BR>&gt;&gt; &gt;=20
&gt;&nbsp;&nbsp;&nbsp; printf (&quot;Press any key =
to=20
continue&quot;); <BR>&gt;&gt; &gt; &gt; gets (junk); =

<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; =
&gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* announce our =
position in the=20
world */ <BR>&gt;&gt; &gt; &gt;&nbsp; aw_int_set =
(AW_MY_X,=20
1000); /* 1W */ <BR>&gt;&gt; &gt; &gt;&nbsp; =
aw_int_set=20
(AW_MY_Z, 1000); /* 1N */ <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
aw_int_set (AW_MY_YAW, 2250); /* face towards GZ */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; if (rc =3D =
aw_state_change ()) {=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf=20
(&quot;Unable to change state (reason %d)\n&quot;, =
rc);=20
<BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; printf =
(&quot;Press=20
any key to continue&quot;); <BR>&gt;&gt; &gt; &gt; =
gets=20
(junk); <BR>&gt;&gt; &gt; &gt;&nbsp;&nbsp;&nbsp; =
exit (1);=20
<BR>&gt;&gt; &gt; &gt;&nbsp; } <BR>&gt;&gt; &gt; =
&gt;=20
<BR>&gt;&gt; &gt; &gt;&nbsp; /* main event loop */=20
<BR>&gt;&gt; &gt; &gt;&nbsp; char req, command[81];=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; =
while=20
(!aw_wait (-1)) <BR>&gt;&gt; &gt; &gt; ; =
<BR>&gt;&gt; &gt;=20
&gt; <BR>&gt;&gt; &gt; &gt;&nbsp; /* close =
everything down=20
*/ <BR>&gt;&gt; &gt; &gt;&nbsp; aw_destroy (); =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; aw_term (); <BR>&gt;&gt; &gt; =
&gt;&nbsp;=20
return 0; <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; =
&gt;}=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;void=20
handle_avatar_add (void) <BR>&gt;&gt; &gt; &gt;{=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;&nbsp; =
char=20
message[100]; <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; =
&gt;=20
&gt;&nbsp; sprintf (message, &quot;Hello %s. Welcome =
to=20
Beta.&quot;, aw_string <BR>&gt;&gt; &gt;=20
&gt;(AW_AVATAR_NAME)); <BR>&gt;&gt; &gt; &gt;&nbsp; =
aw_say=20
(message); <BR>&gt;&gt; &gt; &gt;&nbsp; /* log the =
event to=20
the console */ <BR>&gt;&gt; &gt; &gt;&nbsp; printf=20
(&quot;avatar_add: %s\n&quot;, aw_string =
(AW_AVATAR_NAME));=20
<BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt; &gt;} =
<BR>&gt;&gt;=20
&gt; &gt; <BR>&gt;&gt; &gt; &gt;void object_add =
(void)=20
<BR>&gt;&gt; &gt; &gt;{ <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt;=20
&gt; &gt;&nbsp; printf (&quot;Someone has added a %s =

nearby&quot;, aw_string <BR>(AW_OBJECT_MODEL)); =
<BR>&gt;&gt;=20
&gt; &gt; <BR>&gt;&gt; &gt; &gt;} <BR>&gt;&gt; &gt; =
&gt;=20
<BR>&gt;&gt; &gt; &gt;void avatar_delete (void) =
<BR>&gt;&gt;=20
&gt; &gt;{ <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; &gt;=20
&gt;&nbsp; char message[100]; <BR>&gt;&gt; &gt; &gt; =

<BR>&gt;&gt; &gt; &gt;&nbsp; sprintf (message, =
&quot;%s has=20
left the building\n&quot;, aw_string <BR>&gt;&gt; =
&gt;=20
&gt;(AW_AVATAR_NAME)); <BR>&gt;&gt; &gt; &gt;&nbsp; =
aw_say=20
(message); <BR>&gt;&gt; &gt; &gt;&nbsp; printf=20
(&quot;avatar_delete: %s\n&quot;, aw_string=20
(AW_AVATAR_NAME)); <BR>&gt;&gt; &gt; &gt; =
<BR>&gt;&gt; &gt;=20
&gt;} <BR>&gt;&gt; &gt; &gt; <BR>&gt;&gt; <BR>&gt;=20
=
<BR></P></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE></BLOCKQUOTE>=
</BODY></HTML>

------=_NextPart_000_0104_01BDF460.92880F30--

walter knupe

Oct 11, 1998, 1:27am
This is a multi-part message in MIME format.

------=_NextPart_000_002D_01BDF4D7.C72245E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

Well, Microsoft has given an example on how to architekt that for quite =
some time now..
=20
the listen(), select() and connect() calls have all an asynchronous =
equivalent, which expects a window handle to send a message to
on completion.
=20
the aw.dll would have to use that instead, open a hidden receive window =
for the socket function and have the calling programm have
a proper windows message loop. this is the usualy way and can be =
expected since almost no windows programm can live without that.

and the MFC class library does it exactly that way (although the =
documentation doesn't mention it :) ).
=20
Windows is called Windows because every programm has to use windows, =
regardless of if the users needs them or not :)
=20
that approach would have the advantage that it would work in any =
programm that has a message loop (including other languages), and that =
other events would not be handled or passed-through by aw.dll at all. =
aw.dll could use windows messages as well to deliver events.
=20
Walter

Edward Sumerfield schrieb in Nachricht <361fb171.0 at homer>...
Interesting. Walkter, I hope you keep contributing to this =
newsgroup. You keep teaching me things.=20
=20
So does windows sockets not being file descriptors give us a problem =
with this new aw_add_event design? If can we just pass these non FD to =
the same function?
=20
If the windows select only listens for sockets how would you =
architect a program that listens for windows messages and sockets?
=20
Edward Sumerfield

------=_NextPart_000_002D_01BDF4D7.C72245E0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML>
<HEAD>

<META content=3Dtext/html;charset=3Diso-8859-1 =
http-equiv=3DContent-Type><!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 =
HTML//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN"><!DOCTYPE HTML =
PUBLIC "-//W3C//DTD W3 HTML//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML =
4.0 Transitional//EN">
<META content=3D'"MSHTML 4.72.3110.7"' name=3DGENERATOR>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT size=3D2>Well, Microsoft has given an example on how to =
architekt that=20
for quite some time now..</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>the listen(), select() and connect() calls have all =
an=20
asynchronous equivalent, which expects a window handle to send a message =

to</FONT></DIV>
<DIV><FONT size=3D2>on completion.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>the aw.dll would have to use that instead, open a =
hidden=20
receive window for the socket function and have the calling programm=20
have</FONT></DIV>
<DIV><FONT size=3D2>a proper windows message loop. this is the usualy =
way and can=20
be expected since almost no windows programm can live without =
that.</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>and the MFC class library does it exactly that way =
(although=20
the documentation doesn't mention it :) ).</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Windows is called Windows because every programm has =
to use=20
windows, regardless of if the users needs them or not :)</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>that approach would have the advantage that it would =
work in=20
any programm that has a message loop (including other languages), and =
that other=20
events would not be handled or passed-through by aw.dll at =
all.&nbsp;&nbsp;=20
aw.dll could use windows messages as well to deliver =
events.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Walter</FONT></DIV>
<DIV>&nbsp;</DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: =
5px">
<DIV>Edward Sumerfield<ESUMERFD at NOSPAM.POBOXES.COM> schrieb in =
Nachricht=20
&lt;361fb171.0 at homer&gt;...</DIV>
<DIV><FONT color=3D#000000 size=3D2>Interesting. Walkter, I hope you =
keep=20
contributing to this newsgroup. You keep teaching me things. =
</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#000000 size=3D2>So does windows sockets not =
being file=20
descriptors give us a problem with this new aw_add_event design? If =
can we=20
just pass these non FD to the same function?</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>If the windows select only listens for sockets =
how would=20
you architect a program that listens for windows messages and=20
sockets?</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Edward =
Sumerfield</FONT></DIV></BLOCKQUOTE></BODY></HTML>

------=_NextPart_000_002D_01BDF4D7.C72245E0--

walter knupe

Oct 11, 1998, 1:41am
This is a multi-part message in MIME format.

------=_NextPart_000_0060_01BDF4D9.BA636A80
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

I must add that if you use windows messages, you follow the microsoft =
way of polluting standards and be stuck on the
windows platform :)

to avoid polling i am quite sure you have to choose different paths for =
unix and windows.

under unix, it would be best to signal events and have handler functions =
act on them.

the best windows way is explained below :)

the bot i wrote uses a aw_wait(10); polling and that works quite well. =
its a c++ written bot, running up to 3 bot at once, and each class does =
it own state keeping. just do not multithread that since =
aw_instance_set() and following aw_say() is not atomic anymore then. :)
but i am getting off topic here...

Walter

Walter Knupe schrieb in Nachricht <3620261e.0 at homer>...
Well, Microsoft has given an example on how to architekt that for =
quite some time now..
=20
the listen(), select() and connect() calls have all an asynchronous =
equivalent, which expects a window handle to send a message to
on completion.
=20
the aw.dll would have to use that instead, open a hidden receive =
window for the socket function and have the calling programm have
a proper windows message loop. this is the usualy way and can be =
expected since almost no windows programm can live without that.
=20
and the MFC class library does it exactly that way (although the =
documentation doesn't mention it :) ).
=20
Windows is called Windows because every programm has to use windows, =
regardless of if the users needs them or not :)
=20
that approach would have the advantage that it would work in any =
programm that has a message loop (including other languages), and that =
other events would not be handled or passed-through by aw.dll at all. =
aw.dll could use windows messages as well to deliver events.
=20
Walter
=20
Edward Sumerfield schrieb in Nachricht <361fb171.0 at homer>...
Interesting. Walkter, I hope you keep contributing to this =
newsgroup. You keep teaching me things.=20
=20
So does windows sockets not being file descriptors give us a =
problem with this new aw_add_event design? If can we just pass these non =
FD to the same function?
=20
If the windows select only listens for sockets how would you =
architect a program that listens for windows messages and sockets?
=20
Edward Sumerfield

------=_NextPart_000_0060_01BDF4D9.BA636A80
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
<HTML>
<HEAD>

<META content=3Dtext/html;charset=3Diso-8859-1 =
http-equiv=3DContent-Type><!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 =
HTML//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN"><!DOCTYPE HTML =
PUBLIC "-//W3C//DTD W3 HTML//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 =
HTML//EN"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<META content=3D'"MSHTML 4.72.3110.7"' name=3DGENERATOR>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT color=3D#000000 size=3D2>I must add that if you use windows =
messages, you=20
follow the microsoft way of polluting standards and be stuck on =
the</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT><FONT size=3D2>windows =
platform=20
:)</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>to avoid polling i am quite sure you have to choose =
different=20
paths for unix and windows.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>under unix, it would be best to signal events and =
have handler=20
functions act on them.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>the best windows way is explained below =
:)</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT color=3D#000000 size=3D2>the bot i wrote uses a aw_wait(10); =
polling and=20
that works quite well. its a c++ written bot, running up to 3 bot at =
once, and=20
each class does it own state keeping. just do not multithread that since =

aw_instance_set()&nbsp; and following aw_say() is not atomic anymore =
then.=20
:)</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT><FONT size=3D2>but i am =
getting off topic=20
here...</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>Walter</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: =
5px">
<DIV>Walter Knupe<WAK at FABER.PING.DE> schrieb in Nachricht=20
&lt;3620261e.0 at homer&gt;...</DIV>
<DIV><FONT size=3D2>Well, Microsoft has given an example on how to =
architekt=20
that for quite some time now..</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>the listen(), select() and connect() calls have =
all an=20
asynchronous equivalent, which expects a window handle to send a =
message=20
to</FONT></DIV>
<DIV><FONT size=3D2>on completion.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>the aw.dll would have to use that instead, open =
a hidden=20
receive window for the socket function and have the calling programm =

have</FONT></DIV>
<DIV><FONT size=3D2>a proper windows message loop. this is the =
usualy way and=20
can be expected since almost no windows programm can live without=20
that.</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>and the MFC class library does it exactly that =
way=20
(although the documentation doesn't mention it :) ).</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Windows is called Windows because every programm =
has to=20
use windows, regardless of if the users needs them or not =
:)</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>that approach would have the advantage that it =
would work=20
in any programm that has a message loop (including other languages), =
and=20
that other events would not be handled or passed-through by aw.dll =
at=20
all.&nbsp;&nbsp; aw.dll could use windows messages as well to =
deliver=20
events.</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Walter</FONT></DIV>
<DIV>&nbsp;</DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; =
PADDING-LEFT: 5px">
<DIV>Edward Sumerfield<ESUMERFD at NOSPAM.POBOXES.COM> schrieb in =
Nachricht=20
&lt;361fb171.0 at homer&gt;...</DIV>
<DIV><FONT color=3D#000000 size=3D2>Interesting. Walkter, I hope =
you keep=20
contributing to this newsgroup. You keep teaching me things.=20
</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT color=3D#000000 size=3D2>So does windows sockets not =
being file=20
descriptors give us a problem with this new aw_add_event design? =
If can=20
we just pass these non FD to the same function?</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>If the windows select only listens for =
sockets how=20
would you architect a program that listens for windows messages =
and=20
sockets?</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>Edward=20
Sumerfield</FONT></DIV></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML>

------=_NextPart_000_0060_01BDF4D9.BA636A80--

1  |  
Awportals.com is a privately held community resource website dedicated to Active Worlds.
Copyright (c) Mark Randall 2006 - 2024. All Rights Reserved.
Awportals.com   ·   ProLibraries Live   ·   Twitter   ·   LinkedIn