roland vilett // User Search

roland vilett // User Search

1  2  3  4  5  6  |  

Re: Welcome to the SDK newsgroup

Sep 1, 1998, 2:40am
This is a multi-part message in MIME format.

------=_NextPart_000_0015_01BDD528.0636BA60
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

I'll have all the details when the SDK beta is available, but at this =
point I'm planning to make the beta available for download by anyone who =
wants to test it, so there is no sign-up list.

-Roland
[View Quote]
------=_NextPart_000_0015_01BDD528.0636BA60
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">
<META content=3D'"MSHTML 4.72.2106.6"' name=3DGENERATOR>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV><FONT color=3D#000000 size=3D2>I'll have all the details when the =
SDK beta is=20
available, but at this point I'm planning to make the beta available for =

download by anyone who wants to test it, so there is no sign-up=20
list.</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>-Roland</FONT></DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: =
5px">
[View Quote] ------=_NextPart_000_0015_01BDD528.0636BA60--

SDK beta version now available

Sep 8, 1998, 11:20pm
Hi folks,

okay, here we go! A first cut of the Active Worlds SDK is now available for
beta testing. Please download it from the SDK site at
www.activeworlds.com/sdk. Click on the "download" link and be sure to read
over the SDK license to make sure you are familiar with the terms of usage.
Then review the documentation on that site for instructions on how to use
the SDK with your applications.

Please note that the SDK docs are not yet complete and will most likely be
subject to substantial revision before the SDK is released. However, there
should definitely be enough information available in the docs now to get you
started.

Have fun!

-Roland

ps. one final note: the SDK will only function within COF's Active Worlds
universe during the initial beta testing period.

SDK beta version now available

Sep 10, 1998, 4:07am
There aren't currently any SDK bots running 24 hours a day, but we should
start seeing some set up within the next few weeks.

-Roland

[View Quote]

Help? :)

Sep 10, 1998, 4:05am
What compiler are you using? I suppose I should have mentioned that so far
the SDK has only been tested with Visual C++.

-Roland

[View Quote]

Help? :)

Sep 10, 1998, 10:40pm
I'm not sure but I *think* this is a problem with the aw.lib file being in a
format that Borland doesn't like. I used Borland once upon a time long ago
and I vaguely recall this being an issue - Microsoft and Borland .lib files
are in different formats. If anyone happens to know how to make a Borland
..lib file without actually having to purchase Borland, please let me know.
:)

-Roland

[View Quote]

Help? :)

Sep 11, 1998, 1:32am
main() isn't used or referenced anywhere in the SDK files, so I'm not sure
why doing a #define main _main is changing the way the linker looks for the
SDK entry points. How about instead of doing a #define, just declare the
routine as _main() instead of main().

That's a useful page though, I'll keep it bookmarked for future reference.

-Roland

[View Quote]

Important note about the SDK

Sep 10, 1998, 4:09am
I also should have mentioned that during the beta testing period of the SDK,
SDK apps will only function within the main COF universe. The SDK requires
version 2.1 of the universe server, which is not yet available.

-Roland

Important note about the SDK

Nov 14, 1998, 1:00am
No, I was referring to the universe server, not the world server. You can
run SDK apps inside 2.0 or 2.1 worlds.

-Roland

[View Quote]

can´t get the thing to work

Sep 10, 1998, 7:49pm
Yes I've already noticed from the server logs that several people have made
the same mistake: specifying their *login* passwords for the bot instead of
their *privilege* passwords. Bots are designed to acquire their owner's
privileges via the privilege password. They don't want or need their
owner's login password.

Sorry, that's probably not made very clear in the documentation...

-Roland

[View Quote]

Not multithreaded?

Sep 10, 1998, 7:51pm
Yes that is correct the SDK is not multi-threaded. We evaluated making it
thread-safe and decided that the additional design requirements that would
impose would delay the SDK's release significantly when most developers will
not even need it to be thread-safe.

If demand for a thread-safe SDK is sufficient we'll consider adding that in
a future release. Right now the goal is to get something, ANYTHING, out
there for people to use. :)

-Roland

[View Quote]

Not multithreaded?

Sep 11, 1998, 4:50pm
>In particular, multithreading would be very important if we want
>to try to interface the SDK with java.

But not required. If a Java class were created to encapsualate the current
SDK, the SDK wrapper methods could just be declared as synchronized. If the
SDK is used in asynchronous mode (i.e. with callbacks installed) all SDK
methods return immediately so opportunities for one thread to block others
while in the SDK would be minimal

>(which appear to me as a better language for developing bots because
>of the multithreading, the garbage collection, etc.).


I think the "better" language for bot development is whatever language you
the programmer happen to be comfortable and familiar with.

>Note: Encapsulation of the SDK into java shouldn't be too difficult.
>Anyone interested by the idea ?


A couple of months ago when we first announced work on a C-level API into
Active Words, several people almost immediately offered to implement a Java
wrapper. I don't remember who they were though - are you guys still around,
and if so, are you still interested? :)

-Roland

Not multithreaded?

Sep 11, 1998, 5:01pm
>Certainly we can encapsulate C function calls into Java methods but you
will
>stumble on the aw_wait function because it is supposed to call your java
methods
>and it will not be able to.


Is it not possible at all to have C code call Java routines? Not even in
some kludgey way? Sorry I'm not that familiar with the details of
interfacing Java and C.

If not, it may turn out that a native Java implementation of the SDK is the
only viable long-term solution for Java developers...

>You know, the more I write, the more interesting this sounds. Wait, it will
not
>work, because the sdk took control of the "select" function in the aw_wait
>function we couldn't even trap our own socket events.

Just because aw_wait() calls select() on its sockets doesn't mean that your
code couldn't also call select() on your socket, right? Or am I missing
something. Also, if you call aw_wait (0) it doesn't call select() at all,
it just checks each instance's sockets individually for incoming traffic.
This is to work around some nasty performance problems I've encountered with
the Windows select() call under certain versions of Winsock.

-Roland

Not multithreaded?

Sep 11, 1998, 8:47pm
>You said you are not calling select. The alternative is read poll the
sockets
>with a very short, or zero time out. This is very inefficient especially in
a
>system requiring short response times because the polling interval has to
be so
>short to guarantee the short response time.


Well I said I'm only not calling select in the case where you call aw_wait()
with a timeout of zero. In this case each read socket is polled once. If
you call aw_wait() with a positive timeout value, it uses select(). The
reason for this is that I've had a problem where the select on some PCs
blocks for 500 milliseconds when the select timeout is specified to be 0
milliseconds. If you pass in a zero timeout select() it is supposed to
return immediately, so as far as I can tell there is a very serious bug out
there in some versions of Winsock.

>In my unix (AIX) background I seem to remember an alternative to select
called
>"poll". It performed the same functionality but was a great deal more
efficient.
>I think it was POSIX compliant but I have no clue if this is relevant in a
>windows world.


I'm not aware of a "poll" equivalent under Windows.

>I am still in theory mode here. Its time I found a C compiler and started
>implementing the sdk. I imagine the GNU compiler will work wont it?


In theory it should, although again so far I've only tested the SDK using
Visual C++. If any problems arise I expect they would be at the link stage,
as came up with Borland, because of the different way the exports in aw.lib
are handled.

-Roland

Build 4 of SDK now available

Sep 10, 1998, 10:49pm
I just posted an update of the SDK. Anyone who has downloaded the SDK
already should download it again. You will need to recompile/relink any
applications with the new aw.h and aw.lib in order to use the latest aw.dll.

This update fixes a problem in aw_wait() where it did not process all
pending messages on each call. This was most obvious when using the SDK
with Hambot, where typically the bot would take longer and longer to respond
to chat messages.

-Roland

Build 5 now available

Sep 11, 1998, 11:48pm
Build 5 of the SDK available is now available. You can download it from the
usual place:

http://www.activeworlds.com/sdk/download.htm

Build 5 addresses a problem that many people were running into. The problem
is that in order to conserve bandwidth, the world server only sends the name
of a user to the client once, when their avatar first appears in the scene.
Thus, the attribute AW_AVATAR_NAME was only valid during the
AW_EVENT_AVATAR_ADD event. Most people were assuming that AW_AVATAR_NAME
was also valid during AW_EVENT_AVATAR_DELETE and other events, when in fact
it was not. It was up to the programmer to remember the name that was sent
as part of the AVATAR_ADD event, and use the session id number in subsequent
events in order to look up the name.

Enough people were running into this problem that I went ahead and added
code to the SDK to remember the name and look it up for you automatically.
So with build 5 the AW_AVATAR_NAME attribute should now properly be defined
during the events AW_EVENT_AVATAR_CHANGE, AW_EVENT_AVATAR_DELETE, and
AW_EVENT_CHAT.

Hope that helps!

-Roland

if statement help.....

Sep 13, 1998, 6:17pm
I can't say for sure without seeing your code but I'd guess that if the
compiler doesn't like the strstr call it's because you need to include the
string.h header file, like this:

#include <string.h>

If you are brand new to C or C++ programming, I strongly recommend either
taking an introductory programming class or buying a teach-yourself-C kind
of book. It's certainly possible to figure it all out on your own, but I
think most people will have much better luck getting up to speed on C by
following some kind of structured tutorial, especially if you are new to
programming in general.

I should mention that the snippets of sample code spread throughout the API
docs are generally not intended to compile on their own. They are there
simply to illustrate in as few lines as possible how a certain method or
concept is used. The only place where you will find sample code that is
complete and compilable without modification is in the separate sample
program section.

By the way, one thing to remember while playing with the aw_world_eject()
method is that eject works by IP address. So if you try to test your bot by
running it on your PC and then going in and swearing at it, it will not only
eject you but it will eject itself as well. :)

-Roland

[View Quote]

me again, with an sdk question :)

Sep 14, 1998, 5:53pm
For this you should use the C library function strcmp() instead of strstr().
strstr() searches for any occurrence of the substring in the source, so
that's why the tourist name "PC Wizard" still matches. Also you'll need to
change it to be if (!strcmp (aw_string (AW_AVATAR_NAME), bot_owner)))
(notice the !) because strcmp returns 0 if the strings match.

The AW_CITIZEN_NUMBER is an integer, not a string, which is presumably why
you got an illegal op if you tried to pass it into strstr(). Also,
AW_CITIZEN_NUMBER is not defined during the various AVATAR_* events. To get
a citizen number you would have to take the avatar name and use
aw_citizen_attributes_by_name().

-Roland

[View Quote]

objects database

Sep 14, 1998, 5:56pm
Yes using aw_query() is somewhat complicated because the underlying protocol
for querying and changing property is complex, and right now the SDK pretty
much only provides a direct API to the underlying protocol.

I plan to have a sample program up soon on the SDK sample application page
that illustrates how to use aw_query() to carry out some simple property
operations.

-Roland

[View Quote]

SDK and Java

Sep 14, 1998, 6:07pm
>(I do not want here to enter into a debate about which
>are the language that are good, and which are the language that are bad).


I'm glad, because such debates are always unproductive and time consuming
and in the end never resolve anything...it's like the perennial Mac. vs. PC
debate, some people will always prefer Macs and will back up their
preference with endless evidence of why Macs are superior, and others will
prefer PCs with the same extensive library of reasons why PCs are
better...and no one will ever change their opinion and nothing ever gets
resolved, year after year after year...

Just to make the point clear, I never meant to say C is better than Java or
anything else. Java is a great language, no doubt about it. The simple
truth was that I could produce a C-based Active Worlds SDK in the shortest
amount of time since the rest of Active Worlds is written in C/C++, and by
implementing the SDK in C I could reuse large amounts of the code in the SDK
without having to port it to another language first.

-Roland

SDK and Java

Sep 14, 1998, 6:33pm
Probably not, the SDK is 32-bit code and as such requires a C compiler that
can generate 32-bit applications. Presumably an old DOS C compiler would
not be able to do this...

-Roland

[View Quote]

Alternative documentation format

Sep 15, 1998, 6:09pm
Possibly sometime after the SDK is out of beta and released this might be
available. Currently the docs are incomplete and also the existing pages
are still being modified as changes are made. I update the SDK docs as soon
as any changes are made and right now I don't want anyone to get stuck on an
offline copy that doesn't reflect the latest changes.

-Roland

[View Quote]

GNU compiler

Sep 21, 1998, 2:17pm
A GNU version of the AW SDK is a possibility at some point in the future.
At this early stage I just don't have the time yet to begin porting the SDK
to any other tools/platforms. For that matter, a Unix (Sun and Linux) port
of the SDK is currently a higher priority for me than a Win32 GNU port,
since I believe ultimately that Unix will be a better platform than Windows
for running sophisticated "bot servers" (i.e. applications that manage
hundreds or even thousands of bots at once).

-Roland


[View Quote]

GNU compiler

Sep 30, 1998, 5:17am
It looks like the LoadLibrary/GetProcAddress solution is a good one for
people who don't have access to Visual C++. As soon as I have a spare
moment, I'll create a generic file that will provide access to the AW API
transparently using this mechanism, and include it in subsequent
distributions of the SDK so anyone who runs into this problem in the future
will have an easy solution available. My goal will be to create the file so
that the same code will compile without modification whether you use the
aw.lib mechanism or the LoadLibrary() mechanism.

-Roland


[View Quote]

GNU compiler

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

------=_NextPart_000_0007_01BDEC8F.6E7546E0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

I was also planning to write a C++ class to encapsulate the API at some =
point...I wasn't personally planning to break the API down in to =
multiple different classes. It seems like a single class would be =
sufficient to encapsulate the entire interface, and people who wanted =
specific applications could derive their own classes from it. Of =
course, I'm not the worlds greatest OO programmer so I might not be =
looking at it the right way...you're correct in pointing out that the =
big payoff is that the management of the instance handle could be =
completely encapsulated within the class and the developer would no =
longer have to worry about it.

I'm not sure I like the class names "Citizen" or "Robot"...Citizen would =
be a misnomer since SDK applications are not citizens...maybe call it =
"Owner" instead? And "Robot" is perhaps too restrictive a concept, since =
SDK apps can be things other than bots roaming around in a world talking =
to people...anyway, just a thought. You're of course welcome to create =
any classes you like. :)

-Roland

[View Quote] My first thoughts came up with the following classes:=20

o ActiveWorld=20

Static class responsible for concept wide information. Will do =
the aw_init and contain any constants that may be necesssary.=20

o Universe=20

Responsible for aw_login.=20

o World=20

Responsible for aw_enter=20

o Citizen=20

To encapsulate all information necessary to define a user.=20

o Robot=20

Responsible for defining a bot. Will use the aw_create, aw_say, =
aw_int_set (???) and aw_string_set(???) functions necessary to set bot =
position, avatar, etc.=20

Well very rough ideas at the moment. I am thinking that you could =
end up with a program that looks like this.=20

ActiveWorlds.init();=20
Universe u =3D new Universe();=20
Citizen c =3D new Citizen(user id, priv password);=20
u.login(c);=20

World w =3D new World("Beta");=20
Robot r =3D new Robot("Name", "Application name");=20
r.setPosition(xN, yW, zA);=20
w.enter(r);=20
r.say("Hello World");=20

One of the nicest paybacks for doing this is not having to keep =
track of the robot instance. the Robot class will keep track of that for =
me and set it every time a method is called.=20

The callback interface is going to be interesting. Much rarther do =
it in Java but any way C++ does have abstract functions so I am thinking =
of a single abstract callback class that will force the programmer to =
inherit each function from it and implement whatever is needed.=20

I am not planning on putting in the semaphors to make it thread safe =
in this phase. Maybe down the road.=20

Edward Sumerfield.=20

[View Quote] It looks like the LoadLibrary/GetProcAddress solution is a good =
one for=20
people who don't have access to Visual C++. As soon as I have a =
spare=20
moment, I'll create a generic file that will provide access to =
the AW API=20
transparently using this mechanism, and include it in subsequent =

distributions of the SDK so anyone who runs into this problem in =
the future=20
will have an easy solution available. My goal will be to create =
the file so=20
that the same code will compile without modification whether you =
use the=20
aw.lib mechanism or the LoadLibrary() mechanism.=20
-Roland=20

[View Quote]

------=_NextPart_000_0007_01BDEC8F.6E7546E0
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>I was also planning to write a C++ =
class to=20
encapsulate the API at some point...I wasn't personally planning to =
break the=20
API down in to multiple different classes.&nbsp; It seems like a single =
class=20
would be sufficient to encapsulate the entire interface, and people who =
wanted=20
specific applications could derive their own classes from it.&nbsp; Of =
course,=20
I'm not the worlds greatest OO programmer so I might not be looking at =
it the=20
right way...you're correct in pointing out that the big payoff is that =
the=20
management of the instance handle could be completely encapsulated =
within the=20
class and the developer would no longer have to worry about =
it.</FONT></DIV>
<DIV><FONT color=3D#000000 size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>I'm not sure I like the class names =
&quot;Citizen&quot; or=20
&quot;Robot&quot;...Citizen would be a misnomer since SDK applications =
are not=20
citizens...maybe call it &quot;Owner&quot; instead? And =
&quot;Robot&quot; is=20
perhaps too restrictive a concept, since SDK apps can be things other =
than bots=20
roaming around in a world talking to people...anyway, just a =
thought.&nbsp;=20
You're of course welcome to create any classes you like. :)</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<DIV><FONT size=3D2>-Roland</FONT></DIV>
<DIV><FONT size=3D2></FONT>&nbsp;</DIV>
<BLOCKQUOTE=20
style=3D"BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: =
5px">
[View Quote] <P>My next goal was to wrap the sdk in a C++ wrapper and try to =
extrapolate=20
some class from it. I am not quite sure how to break it down yet.=20
<P>My first thoughts came up with the following classes:=20
<P>o&nbsp;&nbsp;&nbsp; ActiveWorld=20
<P>&nbsp;&nbsp;&nbsp; Static class responsible for concept wide =
information.=20
Will do the aw_init and contain any constants that may be =
necesssary.=20
<P>o&nbsp;&nbsp;&nbsp; Universe=20
<P>&nbsp;&nbsp;&nbsp; Responsible for aw_login.=20
<P>o&nbsp;&nbsp;&nbsp; World=20
<P>&nbsp;&nbsp;&nbsp; Responsible for aw_enter=20
<P>o&nbsp;&nbsp;&nbsp; Citizen=20
<P>&nbsp;&nbsp;&nbsp; To encapsulate all information necessary to =
define a=20
user.=20
<P>o&nbsp;&nbsp;&nbsp; Robot=20
<P>&nbsp;&nbsp;&nbsp; Responsible for defining a bot. Will use the=20
aw_create, aw_say, aw_int_set (???) and aw_string_set(???) functions =

necessary to set bot position, avatar, etc.=20
<P>Well very rough ideas at the moment. I am thinking that you could =
end up=20
with a program that looks like this.=20
<P>&nbsp;&nbsp;&nbsp; ActiveWorlds.init(); <BR>&nbsp;&nbsp;&nbsp; =
Universe u=20
=3D new Universe(); <BR>&nbsp;&nbsp;&nbsp; Citizen c =3D new =
Citizen(user id,=20
priv password); <BR>&nbsp;&nbsp;&nbsp; u.login(c);=20
<P>&nbsp;&nbsp;&nbsp; World w =3D new World(&quot;Beta&quot;);=20
<BR>&nbsp;&nbsp;&nbsp; Robot r =3D new Robot(&quot;Name&quot;,=20
&quot;Application name&quot;); <BR>&nbsp;&nbsp;&nbsp; =
r.setPosition(xN, yW,=20
zA); <BR>&nbsp;&nbsp;&nbsp; w.enter(r); <BR>&nbsp;&nbsp;&nbsp;=20
r.say(&quot;Hello World&quot;);=20
<P>One of the nicest paybacks for doing this is not having to keep =
track of=20
the robot instance. the Robot class will keep track of that for me =
and set=20
it every time a method is called.=20
<P>The callback interface is going to be interesting. Much rarther =
do it in=20
Java but any way C++ does have abstract functions so I am thinking =
of a=20
single abstract callback class that will force the programmer to =
inherit=20
each function from it and implement whatever is needed.=20
<P>I am not planning on putting in the semaphors to make it thread =
safe in=20
this phase. Maybe down the road.=20
<P>Edward Sumerfield.=20
[View Quote] <BR>&gt;&gt;&gt;Joy! <BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt;Got the =
GreeterBot=20
working with GNU C! <BR>&gt;&gt;&gt; <BR>&gt;&gt;&gt;Edward, I =
didn't=20
have any problem with LoadLibrary/GetProcAddress, so I=20
<BR>&gt;&gt;&gt;don't know what to tell you. I'm using the GNU =
compiler=20
distributed by <BR>&gt;&gt;&gt;<A=20
href=3D"http://www.cygnus.com/">http://www.cygnus.com/</A> ...if =
you're=20
not, that could have something to do <BR>&gt;&gt;&gt;with it =
(djgpp is a=20
pretty different setup, I gather). <BR>&gt; <BR>&gt; <BR>&gt; =
<BR>&gt;=20
<BR></P></BLOCKQUOTE></BLOCKQUOTE></BODY></HTML>

------=_NextPart_000_0007_01BDEC8F.6E7546E0--

GNU compiler

Oct 10, 1998, 9:27pm
>Roland, the sdk i downloaded carried only aw.h, aw.lib and aw.dll. is there
>a way to tell what version it is or could
>you provide a version.txt with the archive to give that information ?
>thanks :)


Look for the "#define AW_BUILD" in aw.h. It is defined as the current SDK
build number for that distribution.

-Roland

AW_EVENT_CHAT vs. AW_EVENT_AVATAR_ADD woes...

Sep 21, 1998, 9:35pm
[View Quote]
The session number in AW_AVATAR_SESSION during the AVATAR_ADD event is the
same as the session number in AW_CHAT_SESSION during an AVATAR_CHAT event
for that avatar . I guess the confusing part is that the two different
events use two different attributes to convey the session number.

>3. Build 5 now lets you access variables such as AW_AVATAR_NAME directly
>from AW_CHAT and other event handlers, but the name provided is only
current
>in AW_AVATAR_ADD. As a result, when I access AW_AVATAR_NAME from AW_CHAT,
it
>gives me the name of the last avatar to be added, not the avatar that was
>speaking. The same is true about AW_AVATAR_SESSION. This means that
>AW_CHAT_SESSION is the only thing that can be linked with AW_AVATAR_NAME.
>However, AW_CHAT_SESSION is not assigned in AW_AVATAR_ADD to my knowledge.


The behavior you describe here sounds like a pre-build 5 version of the SDK.
If you are using the DLL from build 5, then the AW_AVATAR_NAME attribute
should be correctly defined for the events AW_EVENT_AVATAR_DELETE,
AW_EVENT_AVATAR_CHANGE, and AW_EVENT_CHAT.

-Roland

Special avs

Sep 21, 1998, 9:19pm
For obscure historical reasons, the special avatars actually start at 251.
Special avs 1 through 5 correspond to types 251, 252, 253, 254, and 255 (the
avatar type cannot exceed 255).

-Roland

[View Quote]

A little help with a program

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]

A little help with a program

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

A little help with a program

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

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