|
esumerfd // User Search
esumerfd // User Search
Sep 10, 1998, 1:28pm
With your design of using the aw_instance_set method it appears as
though your API is not thread safe. Is there a reason for this?
I would imagine that in a high volume world, with lots of bots, each bot
would start reacting slower to stimulus. You could not take advantage of
multi cpu hardware so there would be no hardware rampup available.
I am sure with small greeter bots this will not be a problem but when
you start getting into your conversation bots that apply some AI
technology to make the conversation seem real you are going to see a
long delay in each event function. During this time all other bots are
lifeless, a kind of temporary bot death I guess.
An alternate design would be to pass the instance handle to each
function so that context can be managed appropriately by the API and
each event function gets passed the bots context from which it gets the
relevent bot information.
Edward Sumerfield, esumerfd at poboxes.com
http://members.xoom.com/esumerfd
Sep 11, 1998, 4:37pm
I like the Java idea but I fear it is a great deal more difficult that you are
assuming.
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.
One thing you might be able to do is use the sdk to write a generic server that
would export the sdk to a socket interface. Then you can write java clients to
drive it.
Each java thread would have to talk to a different generic server to get around
the threading problem. Unless you want to build a single generic server that
serialized all parallel requests to a single aw sdk thread, you know, queued up
the requests and processed them one at a time.
It would be quite a lot of work to correctly model the AW interface but once that
was done it shouldn't take long to implement the client side.
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.
It would be really cool to implement a few interfaces to get all the events that
are generated. Instantiate an Avatar class with a login name and priv password to
login. Call its enterWorld method to send it somewhere. Then instantiate a sign
object and call its setText method. Pass the sign object to the avatar so it can
write messages on it. That would require a standard AwTextIF for the Avatar class
to implement. Am I getting carried away yet. OO rocks. Especially Javas' interface
models.
I think I am dreaming too much. Sorry if I wasted your time.
Edward Sumerfield, esumerfd at poboxes.com
http://members.xoom.com/esumerfd
[View Quote]
> Hello,
>
> I personally considere multithreading very important.
>
> For the reasons mentioned by esumerfd.
>
> In particular, multithreading would be very important if we want
> to try to interface the SDK with java.
> (which appear to me as a better language for developing bots because
> of the multithreading, the garbage collection, etc.).
>
> Note: Encapsulation of the SDK into java shouldn't be too difficult.
> Anyone interested by the idea ?
>
> Thierry Nabeth
> Research Fellow,
> INSEAD CALT (the Centre for Advanced Learning Technologies).
> http://www.insead.fr/CALT/
>
> PS:
> Any plan to have a java version of the SDK ?
>
[View Quote]> Roland Vilett wrote:
>
>
|
Sep 11, 1998, 6:57pm
[View Quote]
> will
> methods
>
> 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...
>
Your problem is that you are not calling a java method, instead what you really
have to do is call the java interpreter and tell it to go run the appropriate
method. I have never done this so I can say that it is impossible.
I imagine the issues of managing context across multiple calls to a jam are
substantial. It would have to have a way to reenter the same jam multiple times.
Its time to post a question to comp.lang.java.programming.
> not
>
> 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.
In a single threaded world you can only have one call to "select" at a time
because it is a blocking call that waits for a list of events. If some boot code
also called select with a different list of events the then it would block there
and you could not receive AU events.
In a perfect request, response world on a single socket you can use two selects
because you know whether you are about to receive a request or a response, but
with multiple sockets and the AU protocol has a number of unsolicited messages
that are sent to the client, it is not going to work. Note that I am making some
assumptions here based on my knowledge of the AU browser protocol. I assume you
haven't re-engineered this too much.
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.
Maybe I am missing something. Do you see continuous of frequent CPU usage from
the boot processes?
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 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?
>
>
>
> -Roland
>
Edward Sumerfield, esumerfd at poboxes.com
http://members.xoom.com/esumerfd
Sep 11, 1998, 7:14pm
[View Quote]
>
> 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
>
This isn't exactly true because it is the callback functions that must be
synchronied not the aw functions. Your problem is that you are protecting the
time from when a bot calls aw_instance_set and the next time that function is
called. I know you have a global in there, called aw_current_bot of something,
just waiting to be changed by another thread.
It is possible for a bot to trap an event, call aw_instance_set and then spend
lots of time saying things, changing objects, yadda yadda yadda, and no other
thread can get a look in just in case they call aw_instance_set as well.
With this architecture a good bot architect will have to implement a state
machine to track what has been said so that each time an event goes off it can
say the next thing. Though without a user event machanism this isn't going to
work either.
I should have written this in my last reponse but there is a solution to the
"waiting on AW sockets and user sockets" problem and it will allow the creation
of state machine driven bots. You must write an aw_add_event(event, function)
function that a bot can use to pass their own events to your sdk. Then you can
just wait on all of them and call the appropriate function when they are
notified.
>
>
>
> -Roland
>
Edward Sumerfield, esumerfd at poboxes.com
http://members.xoom.com/esumerfd
Sep 14, 1998, 1:10pm
Well, it appears that I was wrong. There is a way to call java methods from
a native function
http://java.sun.com/products/jdk/1.2/docs/guide/jni/spec/design.doc.html and
look at the "Access Fields and Methods" section.
So to implement the wrapper we will need to go through the following
development steps.
1. Create AW.java with method wrappers that call all the aw C functions.
2. Create AWCallBack.c with handler functions that are called by aw_wait
and intern call java methods. One of these functions must be
aw_set_callback_object( Java object ). It sets up a global object that
contains the java callback methods.
3. Create AWCallBacks.java as a standard store for all the events objects
that need to get notified. Of coarse all the callbacks are implemented as
interface to allow flexability of implementation for the developer.
So the pseudo code might look something like this:
Java:
// AW wrapper class.
class AW {
// Simple C function wrapper.
aw_init(){ call aw_init C funtion }
aw_create() { call aw_create C function }
aw_wait() { call aw_wait C function }
and so on.
set_callback_object( awcb ) {
// assign the global java callback object in the C callback
wrapper
aw_set_callback_object( awcb );
}
}
class myBotProgram {
public static void main(String args[]) {
AW aw = new AW();
aw.init()
AWCallBacks awcb = new AWCallBacks();
awcb.setAvatarAdd( new myAvatarAdd() );
awcb.setAvatarChange( new myAvatarChange() );
aw.set_callback_object( awcb );
aw.create(...)
aw.login(...)
aw.enter(...)
aw.wait()
aw.destroy(...)
aw.term(...)
}
class AWCallBacks() {
AvatarAddIF avatar_add;
AvatarChangeIF avatar_change;
AvatarDeleteIF avatar_delete;
setAvatarAdd( AvatarAddIF avatar ) {
this.avatar_add = avatar_add;
}
setAvatarChaneg and so on.
}
interface AvatarAddIF {
void AvatarAdd();
}
class myAvatarAdd implements AvatarAddIF, AvatarChangeIF ... as
necessary {
void avatarAdd() {
// do something
}
void avatarChange() {
// do something
}
}
C:
global java object;
void aw_set_callback_object( java object ) {
object = java object;
aw_event_set ( AW_EVENT_AVATAR_ADD, callback_avatar_add);
aw_event_set ( AW_EVENT_AVATAR_CHANGE, callback_avatar_change);
aw_event_set ( AW_EVENT_AVATAR_DELETE, callback_avatar_delete);
}
void callback_avatar_add(void) {
// Call the java method via the global object and the interface
pointer.
java object -> avatar_add -> AvatarAdd();
}
Edward Sumerfield, esumerfd at poboxes.com
[View Quote]
> Hello,
>
> I prefer to start a new thread to address this question about
> interfacing
> SDK and Java.
>
> However, this message is an answer to a previous message
> "Re: multithreaded would be usefull if we want to interface it with
> java"
>
> language you
>
> I do not fully agree with you, even if when there is some equivalence
> beteween different languages, you can do with another language
> all you you can do with another one.
> For me a "better" language will allow you to implement an idea more
> easily
> than with a bad one. (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).
> Practically, a "good" language will allow you to represent the system in
> a
> way that reflect in a high level way your ideas, and does not impose you
>
> to enter into (irrelevant) details.
>
> For instance, if multi-threading is not mandatory, on the other hand, it
> can
> make the implementation of different objects having concurent activities
>
> (such as bots) much easier.
> The difference will be reflected by the complexity of the architecture,
> and
> therefore its capacity to evolve before becoming a maintenance
> nightmare.
>
> Anyway I did not post this message to open a "religious" debate, but to
> contribute
> to the following:
>
> into
> Active Words, several people almost immediately offered to implement a
> Java
> wrapper.
>
> I personnaly do not have the time right now to do this wrapping.
> (when I will have more time, I will see if I can do something).
> Besides, I do not have right now a C compiler.
>
> On the other hand, I had the time to look a little bit at the difficulty
>
> to do this wrapping, and my first impression is that it should really
> not be too complicate to do for a programmer having already use JNI
> (Java Native Interface).
>
> The main documentation of Jana Native Interface can be found at:
> http://java.sun.com/products/jdk/1.2/docs/guide/jni/index.html
>
> Here is the idea:
> ----------------------------
> The idea of JNI is to create a Java class with some function are tag
> as Native.
> such as:
> public native void myNativeFunction(Object[] args);
>
> Once the *.java file is compiled (javac), you have to run javah
> (http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html)
> on the *.class file to generate C stub.
>
> You then implement the C functions (in the case of AW SDK you call the
> API),
> compile them, and create a dll.
> ------------------------------
>
> Another possiblility that could appear to be even easier to implement,
> is to use the Shared Stubs Example.
> http://java.sun.com/products/jdk/faq/jnifaq.html
>
> The idea in this example is to generate dynamically the function
> that call the C-code.
> ----- example: call of the sin() function in java ----
> /* Caculate C's sin(2.0) with Math.sin(2.0). */
> CFunc sin = new CFunc(libm, "sin");
> double dres = sin.callDouble(new Object[]{new Double(2.0) });
> System.out.println("\nC's sin(2.0) = " + dres);
> System.out.println("Math.sin(2.0) = " + Math.sin(2.0));
> ----------------------
> This code is extracted from the example. (jnistb10.zip )
>
> Note:
> You still need to do a little bit of compilation to use this approach,
> but you do not need to wrap all the functions as in the previous
> approach.
>
> Well,
>
> That is all for now.
> (I have to work for the next 2 weeks on a more urgent project).
>
> I have not tried to answer the issues raised by esumerfd.
> Perhaps, the wrapping will not work, but the better is to
> try to do it, and solve the problem later.
>
> I hope that a future release of the library will be reentrant,
> since I still believe this is something very important (even if not
> mandatory).
>
> I also hope that in a not too far future, a complete java version will
> be created.
> (let me dream a little bit).
> Indeed, the advantage of a complete java version would be plateform
> independance
> and for instance the possibility to run some bots on a Unix or Linux
> computer.
>
> Bye,
>
> Thierry Nabeth (calt exec)
> Research Fellow,
> INSEAD CALT (the Centre for Advanced Learning Technologies)
> http://www.insead.fr/CALT/
>
> =====================================================
> Subject:
> Re: multithreaded would be usefull if we want to interface it with java
> Date: Fri, 11 Sep 1998 11:50:46 -0700
> From: "Roland Vilett" <roland at lmi.net>
> Newsgroups: sdk
> References: 1 , 2 , 3
>
>
> 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
>
>
> I think the "better" language for bot development is whatever language
> you
> the programmer happen to be comfortable and familiar with.
>
>
> 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
>
>
>
>
>
>
Sep 15, 1998, 6:40pm
Go to win.files.com and get a product called WebDown. Point it at the sdk
web page and it will download everything you want translating the links
appropriately for local access. This is freeware.
[View Quote]
> Roland:
> Will we be able to have some downloadable version of the AW SDK
> documentation?
> Maybe a Word document, text file, or simply the compressed version of
> the current pages, ready for download and read them offline.
>
Sep 16, 1998, 3:36pm
FYI, the GNU C compiler (GCC) requires a different object format to the
aw.lib so can not be used.
Roland, would it be possible to create a version of the the lib with
this compiler so that we poor people can use it. The best place to get
it is http://www.delorie.com/djgpp/ . The windows package is called
djgpp.
Edward Sumerfield, esumerfd at poboxes.com
Sep 23, 1998, 3:07pm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
Thank you I will give it a try.
<P>Edward Sumerfield.
[View Quote]<P>Netropolis wrote:
<BLOCKQUOTE TYPE=CITE>esumerfd wrote:
<BR>>
<BR>> FYI, the GNU C compiler (GCC) requires a different object format
to
<BR>> the aw.lib so can not be used.
<BR>>
<P>I never used the GNU C compiler, but if it can generate win code, you
<BR>should be able write bots using the sdk dll.
<P>To avoid the problem of the incompatible LIB you can use run-time
<BR>dynamic linking (without linking the aw.lib to your prog). You're
gonna
<BR>have to rewrite the header, use function pointers, and load the dll
<BR>using LoadLibrary. It's tedious, but you won't have to wait for a
<BR>specific version of the lib ;)
<P>I compiled the following code using Borland C++ Builder and it works
<BR>fine. You could try compiling it with GNU C. Of course, you are gonna
<BR>have write the code to make it do something :)))
<P>HTH,
<P>-Netro.
<P>#include <windows.h>
<BR>#include <stdio.h>
<BR>#include <stdlib.h>
<P>#define AW_BUILD 5
<P>typedef int (*pAWInit)(int);
<BR>typedef int (*pAWCreate)(char*, int, void**);
<BR>typedef void (*pAWTerm)(void);
<BR>typedef int (*pAWDestroy)(void);
<BR>typedef int (*pAWWait)(int);
<P>main (void)
<BR>{
<BR> int rc;
<BR> HINSTANCE hAWLib;
<BR> pAWInit AWInit;
<BR> pAWCreate AWCreate;
<BR> pAWTerm AWTerm;
<BR> pAWDestroy AWDestroy;
<BR> pAWWait AWWait;
<P> hAWLib = LoadLibrary("aw.dll");
<P> if (hAWLib != NULL) {
<P> AWInit = (pAWInit) GetProcAddress(hAWLib, "aw_init");
<BR> AWCreate = (pAWCreate) GetProcAddress(hAWLib, "aw_create");
<BR> AWTerm = (pAWTerm) GetProcAddress(hAWLib, "aw_term");
<BR> AWDestroy = (pAWDestroy) GetProcAddress(hAWLib,
"aw_destroy");
<BR> AWWait = (pAWWait) GetProcAddress(hAWLib, "aw_wait");
<P> if (rc = (AWInit)(AW_BUILD)) {
<BR> printf ("Unable to initialize API (reason
%d)\n", rc);
<BR> exit (1);
<BR> }
<P> if (rc = (AWCreate)(0, 0, 0)) {
<BR> printf ("Unable to create bot instance
(reason %d)\n", rc);
<BR> exit (1);
<BR> }
<P> (AWWait)(1000);
<P> (AWDestroy)();
<BR> (AWTerm)();
<P> FreeLibrary(hAWLib);
<BR> }
<P> printf ("seems it worked");
<BR> return 0;
<BR>}
<BR> </BLOCKQUOTE>
</HTML>
|
Sep 30, 1998, 8:02pm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
Sounds great Roland. I could use it in my next project if you hurry. Ha
Ha.
<P>My next goal was to wrap the sdk in a C++ wrapper and try to extrapolate
some class from it. I am not quite sure how to break it down yet.
<P>My first thoughts came up with the following classes:
<P>o ActiveWorld
<P> Static class responsible for concept wide information.
Will do the aw_init and contain any constants that may be necesssary.
<P>o Universe
<P> Responsible for aw_login.
<P>o World
<P> Responsible for aw_enter
<P>o Citizen
<P> To encapsulate all information necessary to define
a user.
<P>o Robot
<P> 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.
<P>Well very rough ideas at the moment. I am thinking that you could end
up with a program that looks like this.
<P> ActiveWorlds.init();
<BR> Universe u = new Universe();
<BR> Citizen c = new Citizen(user id, priv password);
<BR> u.login(c);
<P> World w = new World("Beta");
<BR> Robot r = new Robot("Name", "Application name");
<BR> r.setPosition(xN, yW, zA);
<BR> w.enter(r);
<BR> r.say("Hello World");
<P>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.
<P>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.
<P>I am not planning on putting in the semaphors to make it thread safe
in this phase. Maybe down the road.
<P>Edward Sumerfield.
[View Quote]<P>Roland Vilett wrote:
<BLOCKQUOTE TYPE=CITE>It looks like the LoadLibrary/GetProcAddress solution
is a good one for
<BR>people who don't have access to Visual C++. As soon as I have
a spare
<BR>moment, I'll create a generic file that will provide access to the
AW API
<BR>transparently using this mechanism, and include it in subsequent
<BR>distributions of the SDK so anyone who runs into this problem in the
future
<BR>will have an easy solution available. My goal will be to create
the file so
<BR>that the same code will compile without modification whether you use
the
<BR>aw.lib mechanism or the LoadLibrary() mechanism.
<P>-Roland
<P>Edward Sumerfield wrote in message <36119c83.0 at homer>...
<BR>>Here is the complete version of sample Greeter program using the dll
<BR>instead
<BR>>of the lib all compiled and linked with the Cygnus GNU C++ compiler.
<BR>>
<BR>>I added a readme.txt that describes how I got it all working with
input
<BR>from
<BR>>Netropolis and puptank. Thank you.
<BR>>
<BR>>I hope it is useful to someone.
<BR>>
<BR>>Edward Sumerfield.
<BR>>
<BR>>Edward Sumerfield wrote in message <36102a8a.0 at homer>...
<BR>>>You the man. I am downloading the cygnus version now.
<BR>>>
<BR>>>Edward Sumerfield.
<BR>>>
<BR>>>puptank wrote in message <360e296a.0 at homer>...
<BR>>>>Joy!
<BR>>>>
<BR>>>>Got the GreeterBot working with GNU C!
<BR>>>>
<BR>>>>Edward, I didn't have any problem with LoadLibrary/GetProcAddress,
so I
<BR>>>>don't know what to tell you. I'm using the GNU compiler distributed
by
<BR>>>><A HREF="http://www.cygnus.com/">http://www.cygnus.com/</A> ...if
you're not, that could have something to do
<BR>>>>with it (djgpp is a pretty different setup, I gather).
<BR>>
<BR>>
<BR>>
<BR>>
<BR> </BLOCKQUOTE>
</HTML>
|
Oct 1, 1998, 8:55pm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
[View Quote]DrChandra wrote:
<BLOCKQUOTE TYPE=CITE>My advice is to write the API encapsulation as a
single class, with full
<BR>access to all of the SDK calls as methods. Make the class as transparent
as
<BR>possible, so that the C++ code has exactly the same access to the API
that
<BR>is available to C. Further refinements of the class structure into
"real
<BR>world oriented" classes such as Instance, World, and Citizen can be
<BR>constructed on top of that.</BLOCKQUOTE>
Why? To make a single class that calls C functions doesn't buy you anything.
You can call the C functions from anywhere in C++ so why issolate? If I
was doing this in Java, as you are trying to do, I might take the same
approach as it guarantees there are no variable scope issues but doing
it in C++ makes this irrelevant.
<P>I think normalising the model straight away will save me implementation
time and improve performance by reducing effective stack depth.
<BLOCKQUOTE TYPE=CITE>Aside fromt he API encapsulation, I (and anyone else
who
<BR>has the same itch) can produce a JNI interface to the C++ real world
<BR>oriented objects, and the (almost) exact same object would then be
available
<BR>to Java programmers.</BLOCKQUOTE>
This would be my prefered language so I look forward to working with your
results.
<BLOCKQUOTE TYPE=CITE>What is my goal? An open source, multi-platform version
of the aw client.
<BR>Obviously performance will be an issue once we get to the 3D rendering,
but
<BR>before then, we may be able to produce something which will allow someone
to
<BR>stand at ground zero and chat in text mode. It will run anywhere, too.
Maybe
<BR>even from within a Web page.</BLOCKQUOTE>
I was thinking of a telnet server model were you write a bot that accepts
telnet connections and passes any text IO as a check message to an assigned
bot int he world.
<BLOCKQUOTE TYPE=CITE>What I'm
<BR>wrestling with right now is how to represent the Instance pointers
so that
<BR>multiple Java Instance objects can all be making calls to their own
C
<BR>Instance. That and the callback handlers. Any ideas from the group
would
<BR>save time, and would be appreciated.</BLOCKQUOTE>
If by instance you mean bot instance then you just have to encapsulate
the instance number inside a bot object and set the instance for every
call to its methods. It all has to be sychronized to prevent multi-threading
problems so that shouldn't be hard.
<BLOCKQUOTE TYPE=CITE>DrChandra/PK-37(281646)
<P>--
<BR>Andrew C. Esh <A HREF="mailto:andrew_esh at cnt.com">mailto:andrew_esh at cnt.com</A>
<BR><A HREF="http://www.mtn.org/~andrewes">http://www.mtn.org/~andrewes</A>
- ACE Home Page
<P>Roland Vilett <roland at lmi.net> wrote in message 3612bd35.0 at homer...
<BR>I was also planning to write a C++ class to encapsulate the API at
some
<BR>point...I wasn't personally planning to break the API down in to multiple
<BR>different classes. It seems like a single class would be sufficient
to
<BR>encapsulate the entire interface, and people who wanted specific
<BR>applications could derive their own classes from it. Of course,
I'm not the
<BR>worlds greatest OO programmer so I might not be looking at it the right
<BR>way...you're correct in pointing out that the big payoff is that the
<BR>management of the instance handle could be completely encapsulated
within
<BR>the class and the developer would no longer have to worry about it.
<P>I'm not sure I like the class names "Citizen" or "Robot"...Citizen would
be
<BR>a misnomer since SDK applications are not citizens...maybe call it
"Owner"
<BR>instead? And "Robot" is perhaps too restrictive a concept, since SDK
apps
<BR>can be things other than bots roaming around in a world talking to
<BR>people...anyway, just a thought. You're of course welcome to
create any
<BR>classes you like. :)
<P>-Roland
<P>esumerfd wrote in message <3612AA93.6539E0D6 at poboxes.com>...
<BR>Sounds great Roland. I could use it in my next project if you hurry.
Ha Ha.
<BR>My next goal was to wrap the sdk in a C++ wrapper and try to extrapolate
<BR>some class from it. I am not quite sure how to break it down yet.
<BR>My first thoughts came up with the following classes:
<BR>o ActiveWorld
<BR> Static class responsible for concept wide information.
Will do the
<BR>aw_init and contain any constants that may be necesssary.
<BR>o Universe
<BR> Responsible for aw_login.
<BR>o World
<BR> Responsible for aw_enter
<BR>o Citizen
<BR> To encapsulate all information necessary to define
a user.
<BR>o Robot
<BR> Responsible for defining a bot. Will use the aw_create,
aw_say,
<BR>aw_int_set (???) and aw_string_set(???) functions necessary to set
bot
<BR>position, avatar, etc.
<BR>Well very rough ideas at the moment. I am thinking that you could end
up
<BR>with a program that looks like this.
<BR> ActiveWorlds.init();
<BR> Universe u = new Universe();
<BR> Citizen c = new Citizen(user id, priv password);
<BR> u.login(c);
<BR> World w = new World("Beta");
<BR> Robot r = new Robot("Name", "Application name");
<BR> r.setPosition(xN, yW, zA);
<BR> w.enter(r);
<BR> r.say("Hello World");
<BR>One of the nicest paybacks for doing this is not having to keep track
of the
<BR>robot instance. the Robot class will keep track of that for me and
set it
<BR>every time a method is called.
<BR>The callback interface is going to be interesting. Much rarther do
it in
<BR>Java but any way C++ does have abstract functions so I am thinking
of a
<BR>single abstract callback class that will force the programmer to inherit
<BR>each function from it and implement whatever is needed.
<BR>I am not planning on putting in the semaphors to make it thread safe
in this
<BR>phase. Maybe down the road.
<BR>Edward Sumerfield.
<BR>Roland Vilett wrote:
<BR>It looks like the LoadLibrary/GetProcAddress solution is a good one
for
<BR>people who don't have access to Visual C++. As soon as I have
a spare
<BR>moment, I'll create a generic file that will provide access to the
AW API
<BR>transparently using this mechanism, and include it in subsequent
<BR>distributions of the SDK so anyone who runs into this problem in the
future
<BR>will have an easy solution available. My goal will be to create
the file so
<BR>that the same code will compile without modification whether you use
the
<BR>aw.lib mechanism or the LoadLibrary() mechanism.
<BR>-Roland
<BR>Edward Sumerfield wrote in message <36119c83.0 at homer>...
<BR>>Here is the complete version of sample Greeter program using the dll
<BR>instead
<BR>>of the lib all compiled and linked with the Cygnus GNU C++ compiler.
<BR>>
<BR>>I added a readme.txt that describes how I got it all working with
input
<BR>from
<BR>>Netropolis and puptank. Thank you.
<BR>>
<BR>>I hope it is useful to someone.
<BR>>
<BR>>Edward Sumerfield.
<BR>>
<BR>>Edward Sumerfield wrote in message <36102a8a.0 at homer>...
<BR>>>You the man. I am downloading the cygnus version now.
<BR>>>
<BR>>>Edward Sumerfield.
<BR>>>
<BR>>>puptank wrote in message <360e296a.0 at homer>...
<BR>>>>Joy!
<BR>>>>
<BR>>>>Got the GreeterBot working with GNU C!
<BR>>>>
<BR>>>>Edward, I didn't have any problem with LoadLibrary/GetProcAddress,
so I
<BR>>>>don't know what to tell you. I'm using the GNU compiler distributed
by
<BR>>>><A HREF="http://www.cygnus.com/">http://www.cygnus.com/</A> ...if
you're not, that could have something to do
<BR>>>>with it (djgpp is a pretty different setup, I gather).
<BR>>
<BR>>
<BR>>
<BR>>
<BR>
<BR>
<BR> </BLOCKQUOTE>
</HTML>
|
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]Jan-willem De Bleser wrote:
|
> 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]
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]Jan-willem De Bleser wrote:
|
[View Quote]> esumerfd wrote:
>
>
> I know
>
>
> ah. thats the problem
>
>
> ill ask roland about that
>
>
> How?
>
>
|
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]<P>Roland Vilett wrote:
<BLOCKQUOTE TYPE=CITE>A multi-threaded solution isn't absolutely necessary
here...if you are
<BR>developing a Windows console app then you can use the call _kbhit()
to
<BR>determine if a key has been pressed in the console window to avoid
blocking
<BR>in a call to getch(). Something like this:
<P>/* main event loop */
<BR>for (;;) {
<BR> /* check for AW events */
<BR> if (aw_wait(100))
<BR> /* fatal error */
<BR> break;
<BR> if (_kbhit()) {
<BR> /* process keystroke here... */
<BR> }
<BR>}
<P>Check out the Windows SDK docs for more info on _kbhit()...you may want
to
<BR>adjust the timeout parameter to aw_wait() but 100 milliseconds means
you are
<BR>checking for keyboard input 10 times per second which should be adequate
<BR>response time.
<P>-Roland
<P>>You don't need windows unless you want to make the interface pretty.
A
<BR>command
<BR>>line interface, like the dos prompt, is possible with a console app
and is
<BR>much
<BR>>easier to implement if you haven't done much programming.
<BR>>
<BR>>Your problem is the architectural design of the sdk. It is event driven
so
<BR>while
<BR>>your program is in aw_wait it is waiting for a message from the server.
It
<BR>is not
<BR>>able to wait for a keystroke at the same time.
<BR>>
<BR>>An extension needs to be made to the sdk for adding user events (Roland?),
<BR>such as
<BR>>keyboard events. For example, aw_add_event(int, function); This would
cause
<BR>the aw
<BR>>sdk to wait on your event as well as its own and call your function
when it
<BR>is
<BR>>fired.
<BR>>
<BR>>In the mean time you can use polling but it is not ideal. For example
call
<BR>>aw_wait(10) so it will wait for 10 milliseconds for an sdk event to
occur
<BR>then
<BR>>drop back into your program. Then in your console app you can use
the
<BR>standard C
<BR>>function gets() which would allow you to enter a string and press
enter.
<BR>You can
<BR>>then do what you like based on the command entered.
<BR>>
<BR>>The problem is that this is a blocking call. Once you have called
gets it
<BR>will not
<BR>>return to your program until you press enter. While it is waiting
for you,
<BR>your
<BR>>avatar will not be able to react to events.
<BR>>
<BR>>If you want to get into some more serious programing them you can
design a
<BR>>multi-threaded solution which would be a little more realistic. Bare
in
<BR>mind that
<BR>>the aw sdk is not thread safe so do not allow two different threads
to call
<BR>the
<BR>>same api.
<BR>>
<BR>>The design would involve one thread being dedicated to calling the
aw
<BR>functions
<BR>>and a second thread being dedicated to accepting input from the keyboard.
<BR>There
<BR>>would be one common command buffer that both threads read and a lock
to
<BR>protect
<BR>>that buffer.
<BR>>
<BR>>So your program would start up and kick off a seperate thread to do
all the
<BR>aw
<BR>>init, start, enter and wait(10) stuff while the first thread blocked
on the
<BR>gets()
<BR>>function. Now the aw thread would be able to continue running even
though
<BR>the
<BR>>gets() was blocked because it is running in a seperate thread.
<BR>>
<BR>>In the aw thread, each time the aw_wait drops out it would check the
<BR>command lock,
<BR>>if it is unlocked then it would lock it, check the command buffer
and act
<BR>on what
<BR>>ever it found before unlocking the lock.
<BR>>
<BR>>In the gets thread, each time the enter key is pressed the lock is
checked,
<BR>if
<BR>>unlocked then it must be locked and the new command copied into the
shared
<BR>command
<BR>>buffer, before the lock is unlocked again.
<BR>>
<BR>>This is a polling solution so is not as cpu efficient as the sdk change
but
<BR>would
<BR>>work.
<BR>>
<BR>>Good luck everyone.
<BR>>
<BR>>Edward Sumerfield, esumerfd at poboxes.com
<BR>>
<BR>>Jan-willem De Bleser wrote:
<BR>>
<BR>>> Ive seen it done. im guessing you do it somewhere in "while (!aw_wait
<BR>(-1))
<BR>>> !newline! ;", but i cant get it to work
<BR>>>
<BR>>> PC Wizard wrote:
<BR>>>
<BR>>> > I don't know much about programming (I'm just now learning, while
I'm
<BR>>> > working on my own SDK bot), but I would think that if you wanted
to be
<BR>able
<BR>>> > to type stuff in while the program is running it would have to
have
<BR>some
<BR>>> > sort of windows interface (a dialog box with text field or something),
<BR>maybe
<BR>>> > I don't know enough about console applications or something, but
as far
<BR>as I
<BR>>> > know you can't type stuff in while a console app is running...
If you
<BR>can,
<BR>>> > then I'd like to know how to do that too.
<BR>>> >
<BR>>> > PC Wizard
<BR>>> > ICQ-537376
<BR>>> > wizardry at home.com
<BR>>> > <A HREF="http://pcwizard.ml.org">http://pcwizard.ml.org</A>
<BR>>> >
<BR>>> > Jan-willem De Bleser wrote in message
<BR><360300C7.4AD61B6B at mediaone.net>...
<BR>>> > >I have the following program (derived from sample #1) which is
a
<BR>>> > >greetbot. It runs as a console application in dos or windows.
Im
<BR>trying
<BR>>> > >to get it to accept commands at the console so i can make the
bot move
<BR>>> > >and talk at my command. how would i do that?
<BR>>> > >
<BR>>> > >the program:
<BR>>> > >#include <aw.h> //i added the library and header to
my program
<BR>>> > >directories. unless you have done
<BR>>> > >
//that, use "aw.h"
<BR>>> > >#include <stdio.h>
<BR>>> > >#include <stdlib.h>
<BR>>> > >#include <conio.h>
<BR>>> > >
<BR>>> > >void handle_avatar_add (void);
<BR>>> > >void object_add (void);
<BR>>> > >void avatar_delete (void);
<BR>>> > >void input(char command[100]);
<BR>>> > >
<BR>>> > >main (int argc, char *argv[])
<BR>>> > >{
<BR>>> > >
<BR>>> > > int rc;
<BR>>> > > char junk[1];
<BR>>> > >
<BR>>> > > /* check command line */
<BR>>> > > if (argc < 3) {
<BR>>> > > printf ("Usage: %s number password\n", argv[0]);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* initialize Active Worlds API */
<BR>>> > > if (rc = aw_init (AW_BUILD)) {
<BR>>> > > printf ("Unable to initialize API (reason
%d)\n", rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* install handler for avatar_add and object_add event
*/
<BR>>> > > aw_event_set (AW_EVENT_AVATAR_ADD, handle_avatar_add);
<BR>>> > > aw_event_set (AW_EVENT_OBJECT_ADD, object_add);
<BR>>> > > aw_event_set (AW_EVENT_AVATAR_DELETE, avatar_delete);
<BR>>> > >
<BR>>> > > /* create bot instance */
<BR>>> > > if (rc = aw_create (0, 0, 0)) {
<BR>>> > > printf ("Unable to create bot instance (reason
%d)\n", rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* log bot into the universe */
<BR>>> > > aw_int_set (AW_LOGIN_OWNER, atoi (argv[1]));
<BR>>> > > aw_string_set (AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]);
<BR>>> > > aw_string_set (AW_LOGIN_APPLICATION, "SDK Sample Application
#1");
<BR>>> > > aw_string_set (AW_LOGIN_NAME, "Bot of Zasz");
<BR>>> > > if (rc = aw_login ()) {
<BR>>> > > printf ("Unable to login (reason %d)\n", rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* log bot into the world called "beta" */
<BR>>> > > if (rc = aw_enter ("Beta", 0)) {
<BR>>> > > printf ("Unable to enter world (reason %d)\n",
rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* announce our position in the world */
<BR>>> > > aw_int_set (AW_MY_X, 1000); /* 1W */
<BR>>> > > aw_int_set (AW_MY_Z, 1000); /* 1N */
<BR>>> > > aw_int_set (AW_MY_YAW, 2250); /* face towards GZ */
<BR>>> > > if (rc = aw_state_change ()) {
<BR>>> > > printf ("Unable to change state (reason %d)\n",
rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* main event loop */
<BR>>> > > char req, command[81];
<BR>>> > >
<BR>>> > > while (!aw_wait (-1))
<BR>>> > > ;
<BR>>> > >
<BR>>> > > /* close everything down */
<BR>>> > > aw_destroy ();
<BR>>> > > aw_term ();
<BR>>> > > return 0;
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>> > >void handle_avatar_add (void)
<BR>>> > >{
<BR>>> > >
<BR>>> > > char message[100];
<BR>>> > >
<BR>>> > > sprintf (message, "Hello %s. Welcome to Beta.", aw_string
<BR>>> > >(AW_AVATAR_NAME));
<BR>>> > > aw_say (message);
<BR>>> > > /* log the event to the console */
<BR>>> > > printf ("avatar_add: %s\n", aw_string (AW_AVATAR_NAME));
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>> > >void object_add (void)
<BR>>> > >{
<BR>>> > >
<BR>>> > > printf ("Someone has added a %s nearby", aw_string
<BR>(AW_OBJECT_MODEL));
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>> > >void avatar_delete (void)
<BR>>> > >{
<BR>>> > >
<BR>>> > > char message[100];
<BR>>> > >
<BR>>> > > sprintf (message, "%s has left the building\n", aw_string
<BR>>> > >(AW_AVATAR_NAME));
<BR>>> > > aw_say (message);
<BR>>> > > printf ("avatar_delete: %s\n", aw_string (AW_AVATAR_NAME));
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>>
<BR>>
<BR> </BLOCKQUOTE>
</HTML>
|
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> socket()
<BR> connect( universe )
<BR> socket()
<BR> connect( world )
<P> array = { universe, world }
<P> while (1) {
<P> event = select (array)
<BR> if (event = universe) {
<P> Read
data from universe file descriptor
<BR> }
<BR> else {
<P> Read
data from the world file descriptor
<BR> }
<BR> }
<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> aw_add_event (file descriptor, function pointer)
{
<P> append file descriptor to
end of array.
<BR> store function pointer into
another array indexed by the file descriptor.
<BR> }
<P>Now change your select function as follows:
<P> array = { universe, world }
<P> while (1) {
<P> event = select (array)
<BR> if (event = universe) {
<P> Read
data from universe file descriptor
<BR> }
<BR> else if (event == world)
{
<P> Read
data from the world file descriptor
<BR> }
<BR> else {
<P> look
up function pointer using file descriptor
<BR>
call users function;
<BR> }
<BR> }
<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]<P>Roland Vilett wrote:
<BLOCKQUOTE TYPE=CITE><FONT COLOR="#000000"><FONT SIZE=-1>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.</FONT></FONT> <FONT SIZE=-1>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()?</FONT> <FONT COLOR="#000000"><FONT SIZE=-1>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.</FONT></FONT><FONT SIZE=-1>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.</FONT> <FONT SIZE=-1>-Roland</FONT> esumerfd<ESUMERFD at POBOXES.COM>
wrote in message <<A HREF="mailto:3606D037.57F62323 at poboxes.com">3606D037.57F62323 at poboxes.com</A>>...
<BLOCKQUOTE
style="BORDER-LEFT: #000000 solid 2px; MARGIN-LEFT: 5px; PADDING-LEFT: 5px">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
<P>Roland Vilett wrote:
<BR>
<BLOCKQUOTE TYPE = CITE>A multi-threaded solution isn't absolutely necessary
here...if you are
<BR>developing a Windows console app then you can use the call _kbhit()
to
<BR>determine if a key has been pressed in the console window to avoid
blocking
<BR>in a call to getch(). Something like this:
<P>/* main event loop */
<BR>for (;;) {
<BR> /* check for AW events */
<BR> if (aw_wait(100))
<BR> /* fatal error */
<BR> break;
<BR> if (_kbhit()) {
<BR> /* process keystroke here... */
<BR> }
<BR>}
<P>Check out the Windows SDK docs for more info on _kbhit()...you may want
to
<BR>adjust the timeout parameter to aw_wait() but 100 milliseconds means
you are
<BR>checking for keyboard input 10 times per second which should be adequate
<BR>response time.
<P>-Roland
<P>>You don't need windows unless you want to make the interface pretty.
A
<BR>command
<BR>>line interface, like the dos prompt, is possible with a console app
and is
<BR>much
<BR>>easier to implement if you haven't done much programming.
<BR>>
<BR>>Your problem is the architectural design of the sdk. It is event driven
so
<BR>while
<BR>>your program is in aw_wait it is waiting for a message from the server.
It
<BR>is not
<BR>>able to wait for a keystroke at the same time.
<BR>>
<BR>>An extension needs to be made to the sdk for adding user events (Roland?),
<BR>such as
<BR>>keyboard events. For example, aw_add_event(int, function); This would
cause
<BR>the aw
<BR>>sdk to wait on your event as well as its own and call your function
when it
<BR>is
<BR>>fired.
<BR>>
<BR>>In the mean time you can use polling but it is not ideal. For example
call
<BR>>aw_wait(10) so it will wait for 10 milliseconds for an sdk event to
occur
<BR>then
<BR>>drop back into your program. Then in your console app you can use
the
<BR>standard C
<BR>>function gets() which would allow you to enter a string and press
enter.
<BR>You can
<BR>>then do what you like based on the command entered.
<BR>>
<BR>>The problem is that this is a blocking call. Once you have called
gets it
<BR>will not
<BR>>return to your program until you press enter. While it is waiting
for you,
<BR>your
<BR>>avatar will not be able to react to events.
<BR>>
<BR>>If you want to get into some more serious programing them you can
design a
<BR>>multi-threaded solution which would be a little more realistic. Bare
in
<BR>mind that
<BR>>the aw sdk is not thread safe so do not allow two different threads
to call
<BR>the
<BR>>same api.
<BR>>
<BR>>The design would involve one thread being dedicated to calling the
aw
<BR>functions
<BR>>and a second thread being dedicated to accepting input from the keyboard.
<BR>There
<BR>>would be one common command buffer that both threads read and a lock
to
<BR>protect
<BR>>that buffer.
<BR>>
<BR>>So your program would start up and kick off a seperate thread to do
all the
<BR>aw
<BR>>init, start, enter and wait(10) stuff while the first thread blocked
on the
<BR>gets()
<BR>>function. Now the aw thread would be able to continue running even
though
<BR>the
<BR>>gets() was blocked because it is running in a seperate thread.
<BR>>
<BR>>In the aw thread, each time the aw_wait drops out it would check the
<BR>command lock,
<BR>>if it is unlocked then it would lock it, check the command buffer
and act
<BR>on what
<BR>>ever it found before unlocking the lock.
<BR>>
<BR>>In the gets thread, each time the enter key is pressed the lock is
checked,
<BR>if
<BR>>unlocked then it must be locked and the new command copied into the
shared
<BR>command
<BR>>buffer, before the lock is unlocked again.
<BR>>
<BR>>This is a polling solution so is not as cpu efficient as the sdk change
but
<BR>would
<BR>>work.
<BR>>
<BR>>Good luck everyone.
<BR>>
<BR>>Edward Sumerfield, esumerfd at poboxes.com
<BR>>
<BR>>Jan-willem De Bleser wrote:
<BR>>
<BR>>> Ive seen it done. im guessing you do it somewhere in "while (!aw_wait
<BR>(-1))
<BR>>> !newline! ;", but i cant get it to work
<BR>>>
<BR>>> PC Wizard wrote:
<BR>>>
<BR>>> > I don't know much about programming (I'm just now learning, while
I'm
<BR>>> > working on my own SDK bot), but I would think that if you wanted
to be
<BR>able
<BR>>> > to type stuff in while the program is running it would have to
have
<BR>some
<BR>>> > sort of windows interface (a dialog box with text field or something),
<BR>maybe
<BR>>> > I don't know enough about console applications or something, but
as far
<BR>as I
<BR>>> > know you can't type stuff in while a console app is running...
If you
<BR>can,
<BR>>> > then I'd like to know how to do that too.
<BR>>> >
<BR>>> > PC Wizard
<BR>>> > ICQ-537376
<BR>>> > wizardry at home.com
<BR>>> > <A HREF="http://pcwizard.ml.org">http://pcwizard.ml.org</A>
<BR>>> >
<BR>>> > Jan-willem De Bleser wrote in message
<BR><360300C7.4AD61B6B at mediaone.net>...
<BR>>> > >I have the following program (derived from sample #1) which is
a
<BR>>> > >greetbot. It runs as a console application in dos or windows.
Im
<BR>trying
<BR>>> > >to get it to accept commands at the console so i can make the
bot move
<BR>>> > >and talk at my command. how would i do that?
<BR>>> > >
<BR>>> > >the program:
<BR>>> > >#include <aw.h> //i added the library and header to
my program
<BR>>> > >directories. unless you have done
<BR>>> > >
//that, use "aw.h"
<BR>>> > >#include <stdio.h>
<BR>>> > >#include <stdlib.h>
<BR>>> > >#include <conio.h>
<BR>>> > >
<BR>>> > >void handle_avatar_add (void);
<BR>>> > >void object_add (void);
<BR>>> > >void avatar_delete (void);
<BR>>> > >void input(char command[100]);
<BR>>> > >
<BR>>> > >main (int argc, char *argv[])
<BR>>> > >{
<BR>>> > >
<BR>>> > > int rc;
<BR>>> > > char junk[1];
<BR>>> > >
<BR>>> > > /* check command line */
<BR>>> > > if (argc < 3) {
<BR>>> > > printf ("Usage: %s number password\n", argv[0]);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* initialize Active Worlds API */
<BR>>> > > if (rc = aw_init (AW_BUILD)) {
<BR>>> > > printf ("Unable to initialize API (reason
%d)\n", rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* install handler for avatar_add and object_add event
*/
<BR>>> > > aw_event_set (AW_EVENT_AVATAR_ADD, handle_avatar_add);
<BR>>> > > aw_event_set (AW_EVENT_OBJECT_ADD, object_add);
<BR>>> > > aw_event_set (AW_EVENT_AVATAR_DELETE, avatar_delete);
<BR>>> > >
<BR>>> > > /* create bot instance */
<BR>>> > > if (rc = aw_create (0, 0, 0)) {
<BR>>> > > printf ("Unable to create bot instance (reason
%d)\n", rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* log bot into the universe */
<BR>>> > > aw_int_set (AW_LOGIN_OWNER, atoi (argv[1]));
<BR>>> > > aw_string_set (AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]);
<BR>>> > > aw_string_set (AW_LOGIN_APPLICATION, "SDK Sample Application
#1");
<BR>>> > > aw_string_set (AW_LOGIN_NAME, "Bot of Zasz");
<BR>>> > > if (rc = aw_login ()) {
<BR>>> > > printf ("Unable to login (reason %d)\n", rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* log bot into the world called "beta" */
<BR>>> > > if (rc = aw_enter ("Beta", 0)) {
<BR>>> > > printf ("Unable to enter world (reason %d)\n",
rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* announce our position in the world */
<BR>>> > > aw_int_set (AW_MY_X, 1000); /* 1W */
<BR>>> > > aw_int_set (AW_MY_Z, 1000); /* 1N */
<BR>>> > > aw_int_set (AW_MY_YAW, 2250); /* face towards GZ */
<BR>>> > > if (rc = aw_state_change ()) {
<BR>>> > > printf ("Unable to change state (reason %d)\n",
rc);
<BR>>> > > printf ("Press any key to continue");
<BR>>> > > gets (junk);
<BR>>> > > exit (1);
<BR>>> > > }
<BR>>> > >
<BR>>> > > /* main event loop */
<BR>>> > > char req, command[81];
<BR>>> > >
<BR>>> > > while (!aw_wait (-1))
<BR>>> > > ;
<BR>>> > >
<BR>>> > > /* close everything down */
<BR>>> > > aw_destroy ();
<BR>>> > > aw_term ();
<BR>>> > > return 0;
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>> > >void handle_avatar_add (void)
<BR>>> > >{
<BR>>> > >
<BR>>> > > char message[100];
<BR>>> > >
<BR>>> > > sprintf (message, "Hello %s. Welcome to Beta.", aw_string
<BR>>> > >(AW_AVATAR_NAME));
<BR>>> > > aw_say (message);
<BR>>> > > /* log the event to the console */
<BR>>> > > printf ("avatar_add: %s\n", aw_string (AW_AVATAR_NAME));
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>> > >void object_add (void)
<BR>>> > >{
<BR>>> > >
<BR>>> > > printf ("Someone has added a %s nearby", aw_string
<BR>(AW_OBJECT_MODEL));
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>> > >void avatar_delete (void)
<BR>>> > >{
<BR>>> > >
<BR>>> > > char message[100];
<BR>>> > >
<BR>>> > > sprintf (message, "%s has left the building\n", aw_string
<BR>>> > >(AW_AVATAR_NAME));
<BR>>> > > aw_say (message);
<BR>>> > > printf ("avatar_delete: %s\n", aw_string (AW_AVATAR_NAME));
<BR>>> > >
<BR>>> > >}
<BR>>> > >
<BR>>>
<BR>>
<BR> </BLOCKQUOTE>
</BLOCKQUOTE>
</BLOCKQUOTE>
|
</BODY>
</HTML>
Oct 8, 1998, 10:05am
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
NG = News group.
[View Quote]<P>Jan-willem De Bleser wrote:
<BLOCKQUOTE TYPE=CITE>Edward Sumerfield wrote:
<P>> OK. I copied you code and made the attached h.c file. The following
errors
<P>> existed prior to fixing:
<BR>>
<BR>> gcc -g -I. -I//f/edward/products/awsdk -c h.c -o h.o
<BR>> h.c: In function `console_command':
<BR>> h.c:19: parse error before `int'
<BR>> h.c:20: `count' undeclared (first use this function)
<BR>> h.c:20: (Each undeclared identifier is reported only once
<BR>> h.c:20: for each function it appears in.)
<BR>> h.c:22: `AW_OBJECT_X' undeclared (first use this function)
<BR>> h.c:23: `AW_OBJECT_Y' undeclared (first use this function)
<BR>> h.c:24: `AW_OBJECT_Z' undeclared (first use this function)
<BR>> h.c:25: `AW_OBJECT_MODEL' undeclared (first use this function)
<BR>> h.c:36: parse error before `int'
<BR>> make: *** [h.o] Error 1
<BR>>
<BR>> I dare say you have included the aw.h file, just didn't include it
in the
<BR>> NG.
<P>ng?
<P>> So I added that afterwards.
<BR>>
<BR>> You were missing a } at the end of the function. Again, maybe a cut
and
<BR>> paste error.
<P>theres more of that function
<P>>
<BR>>
<BR>> You can not declare a variable after a line of code in a block. A
block
<BR>> starts with an open curly, {. I moved the int count; up to the top
of the if
<BR>> statement.
<BR>>
<BR>> As you can see I didn't get the same errors as you did. I added a
makefile
<BR>> for you if you don't have one already.
<BR>>
<BR>> I can not complete the link step because I am using the GNU compiler
and the
<BR>> aw.lib object format is different but it should work for you.
<BR>>
<BR>> Good luck.
<BR>>
<BR>> Edward Sumerfield.
<BR>>
<BR>> Jan-willem De Bleser wrote in message <361BDDC4.3FCD822D at mediaone.net>...
<BR>> >problem. i still get errors, but different odd ones that i cant
figure out
<BR>> > Compiling...
<BR>> > roadbuilder.c
<BR>> > C:\Windows\Desktop\Projects\roadbuilder\roadbuilder.c(97)
: error
<BR>> C2143:
<BR>> >syntax error : missing ';' before 'type'
<BR>> > C:\Windows\Desktop\Projects\roadbuilder\roadbuilder.c(98)
: error
<BR>> C2065:
<BR>> >'count' : undeclared identifier
<BR>> > Error executing cl.exe.
<BR>> > roadbuilder.exe - 2 error(s), 0 warning(s)
<BR>> >
<BR>> >heres the code:
<BR>> >void console_command(char input[81])
<BR>> >{
<BR>> > if(strstr(input, "build"))
<BR>> > {
<BR>> > int north, west, length, rc;
<BR>> >
<BR>> > printf("\nNorth?");
<BR>> > scanf("%d", north);
<BR>> >
<BR>> > printf("\nWest?");
<BR>> > scanf("%d", west);
<BR>> >
<BR>> > printf("\nHow long?");
<BR>> > scanf("%d", length);
<BR>> >
<BR>> > int count;
<BR>> > for(count = 0; count < length; count++)
<BR>> > {
<BR>> > aw_int_set (AW_OBJECT_X, west * 1000);
<BR>> > aw_int_set (AW_OBJECT_Y, 0);
<BR>> > aw_int_set (AW_OBJECT_Z, north * 1000);
<BR>> > aw_string_set (AW_OBJECT_MODEL, "street1.rwx");
<BR>> > if (rc = aw_object_add ())
<BR>> > printf ("Unable to add object (reason %d)\n",
rc);
<BR>> > else
<BR>> > puts ("Object added");
<BR>> >
<BR>> > west = west + 500;
<BR>> > north = north + 500;
<BR>> > }
<BR>> > }
<BR>> >
<BR>> >Jan-willem De Bleser wrote:
<BR>> >
<BR>> >> he builds street1.rwx in a straight line. a stripped down robobuilder,
<BR>> that i
<BR>> >> will probablye be allowed to use, because who is gonna cover a
lot with
<BR>> roads?
<BR>> >>
<BR>> >> Edward Sumerfield wrote:
<BR>> >>
<BR>> >> > This error means that the code in roadbuilder.cpp and therefore
the
<BR>> >> > functions from roadbuilder.obj do not exist in the objects that
are
<BR>> being
<BR>> >> > included in the link command.
<BR>> >> >
<BR>> >> > I notice you are using the cpp suffix. This is a C++ suffix
and is
<BR>> therefore
<BR>> >> > compiled a little differently to C code. Look up function name
mangling
<BR>> if
<BR>> >> > you want to learn more.
<BR>> >> >
<BR>> >> > I am not sure what compiler you are using but you might want
to try
<BR>> renaming
<BR>> >> > you code to a .c (lower case "c") file and try again.
<BR>> >> >
<BR>> >> > Make sure that the link step includes the aw.lib file which
is there
<BR>> all
<BR>> >> > these finctions exist.
<BR>> >> >
<BR>> >> > Hey , I guess you are building a road builder, sounds cool.
I hope you
<BR>> are
<BR>> >> > going to add the guestures for pooring tar and driving big rollers
and
<BR>> such.
<BR>> >> > That will be fun to watch.
<BR>> >> >
<BR>> >> > Edward Sumerfield.
<BR>> >> >
<BR>> >> > Jan-willem De Bleser wrote in message
<BR>> <361AC1F0.436F2673 at mediaone.net>...
<BR>> >> > >has anyone actually found out what causes this error?
<BR>> >> > >
<BR>> >> > >--------------------Configuration: roadbuilder - Win32
<BR>> >> > >Debug--------------------
<BR>> >> > >Compiling...
<BR>> >> > >roadbuilder.cpp
<BR>> >> > >Linking...
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_term
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_destroy
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_wait
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_state_change
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_int_set
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_enter
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_login
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_string_set
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_create
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_init
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_object_add
<BR>> >> > >Debug/roadbuilder.exe : fatal error LNK1120: 11 unresolved
externals
<BR>> >> > >Error executing link.exe.
<BR>> >> > >roadbuilder.exe - 12 error(s), 0 warning(s)
<BR>> >> > >
<BR>> >>
<BR>> >> -----------------------------------------------------------------------
<BR>> -
<BR>> >>
<BR>> >> Jan-willem De Bleser <debleser at mediaone.net>
<BR>> >> High school
<BR>> >>
<BR>> >> Jan-willem De Bleser
<BR>> >> High school <debleser at mediaone.net>
<BR>> >>
Netscape Conference Address
<BR>> >>
Netscape Conference DLS Server
<BR>> >> Additional Information:
<BR>> >> Last Name De Bleser
<BR>> >> First Name Jan-willem
<BR>> >> Version 2.1
<BR>> >
<BR>> >
<BR>> >
<BR>>
<BR>>
Name: h.c
<BR>> h.c Type: C
File (application/x-unknown-content-type-c_auto_file)
<BR>> Encoding: x-uuencode
<BR>>
<BR>>
Name: Makefile.dat
<BR>> Makefile.dat
Type: DAT File (application/x-unknown-content-type-dat_auto_file)
<BR>>
Encoding: x-uuencode
<BR> </BLOCKQUOTE>
</HTML>
|
Oct 8, 1998, 10:18am
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
Tell me more about your development environment. When IDE/C compiler are
you using. can you post your Makefile.
<P>Some theory for you.
<P>Source file called aa.c
<P>int aa() {
<BR> printf("In aa function.\n");
<BR>}
<P>Source file called main.c
<P>int aa();
<BR>main() {
<BR> aa();
<BR>}
<P>When you compile you will get main.obj and aa.obj. When you link you
can get main.exe for example.
<P>However, if I linked main.obj without specifying aa.obj I would get
<P>main.obj : error LNK2001: unresolved external symbol aa
<P>The next step is libraries. I can store the aa.obj in a library using
"ar ru aa.lib aa.obj" (unix command). Now when I link I will specify main.obj
and aa.lib. The linker is clever enough to open up .lib files and look
inside to find obj files.
<P>The functions that are failing to link are all stored in the aw.lib
file. So I am assuming that are are not specifying this library when you
link.<BR>
<BR>
<BR>My only confusion is that you still have the __imp__ prefix to the
funcitons. This prefix is usually due to C++ name mangling. This is the
process of taking a function name and attaching a prefix that encodes the
types of the arguments that it is passed. This allows C++ to do function
overloading. You should not be doing this in your C code.
<P>If you are using a C++ compiler maybe it is thinking that this is C++.
You can add code to tell the compiler the type of "linkage spec" to follow.
For example,
<P>extern "C" {
<P> int aa() {
<BR> printf("In aa function.\n");
<BR> }
<BR>}
<P>With the extern "C" around the function a C++ compiler will not mangle
the function name. So I guess you could add this around your code but there
is probably a simpler way. This notation is in the standard header files.
Say I assume you are including <stdio.h> and not <iostream.h>? That
would certainly make a difference.
<P>Edward Sumerfield
[View Quote]<P>Jan-willem De Bleser wrote:
<BLOCKQUOTE TYPE=CITE>i moved the var count and then got these familliar
errors
<BR>--------------------Configuration: roadbuilder - Win32 Debug--------------------
<BR>Compiling...
<BR>roadbuilder.c
<BR>Linking...
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_term
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_destroy
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_wait
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_state_change
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_int_set
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_enter
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_login
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_string_set
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_create
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_init
<BR>roadbuilder.obj : error LNK2001: unresolved external symbol __imp__aw_object_add
<BR>Debug/roadbuilder.exe : fatal error LNK1120: 11 unresolved externals
<BR>Error executing link.exe.
<BR>roadbuilder.exe - 12 error(s), 0 warning(s)
<P>Edward Sumerfield wrote:
<P>> OK. I copied you code and made the attached h.c file. The following
errors
<BR>> existed prior to fixing:
<BR>>
<BR>> gcc -g -I. -I//f/edward/products/awsdk -c h.c -o h.o
<BR>> h.c: In function `console_command':
<BR>> h.c:19: parse error before `int'
<BR>> h.c:20: `count' undeclared (first use this function)
<BR>> h.c:20: (Each undeclared identifier is reported only once
<BR>> h.c:20: for each function it appears in.)
<BR>> h.c:22: `AW_OBJECT_X' undeclared (first use this function)
<BR>> h.c:23: `AW_OBJECT_Y' undeclared (first use this function)
<BR>> h.c:24: `AW_OBJECT_Z' undeclared (first use this function)
<BR>> h.c:25: `AW_OBJECT_MODEL' undeclared (first use this function)
<BR>> h.c:36: parse error before `int'
<BR>> make: *** [h.o] Error 1
<BR>>
<BR>> I dare say you have included the aw.h file, just didn't include it
in the
<BR>> NG. So I added that afterwards.
<BR>>
<BR>> You were missing a } at the end of the function. Again, maybe a cut
and
<BR>> paste error.
<BR>>
<BR>> You can not declare a variable after a line of code in a block. A
block
<BR>> starts with an open curly, {. I moved the int count; up to the top
of the if
<BR>> statement.
<BR>>
<BR>> As you can see I didn't get the same errors as you did. I added a
makefile
<BR>> for you if you don't have one already.
<BR>>
<BR>> I can not complete the link step because I am using the GNU compiler
and the
<BR>> aw.lib object format is different but it should work for you.
<BR>>
<BR>> Good luck.
<BR>>
<BR>> Edward Sumerfield.
<BR>>
<BR>> Jan-willem De Bleser wrote in message <361BDDC4.3FCD822D at mediaone.net>...
<BR>> >problem. i still get errors, but different odd ones that i cant
figure out
<BR>> > Compiling...
<BR>> > roadbuilder.c
<BR>> > C:\Windows\Desktop\Projects\roadbuilder\roadbuilder.c(97)
: error
<BR>> C2143:
<BR>> >syntax error : missing ';' before 'type'
<BR>> > C:\Windows\Desktop\Projects\roadbuilder\roadbuilder.c(98)
: error
<BR>> C2065:
<BR>> >'count' : undeclared identifier
<BR>> > Error executing cl.exe.
<BR>> > roadbuilder.exe - 2 error(s), 0 warning(s)
<BR>> >
<BR>> >heres the code:
<BR>> >void console_command(char input[81])
<BR>> >{
<BR>> > if(strstr(input, "build"))
<BR>> > {
<BR>> > int north, west, length, rc;
<BR>> >
<BR>> > printf("\nNorth?");
<BR>> > scanf("%d", north);
<BR>> >
<BR>> > printf("\nWest?");
<BR>> > scanf("%d", west);
<BR>> >
<BR>> > printf("\nHow long?");
<BR>> > scanf("%d", length);
<BR>> >
<BR>> > int count;
<BR>> > for(count = 0; count < length; count++)
<BR>> > {
<BR>> > aw_int_set (AW_OBJECT_X, west * 1000);
<BR>> > aw_int_set (AW_OBJECT_Y, 0);
<BR>> > aw_int_set (AW_OBJECT_Z, north * 1000);
<BR>> > aw_string_set (AW_OBJECT_MODEL, "street1.rwx");
<BR>> > if (rc = aw_object_add ())
<BR>> > printf ("Unable to add object (reason %d)\n",
rc);
<BR>> > else
<BR>> > puts ("Object added");
<BR>> >
<BR>> > west = west + 500;
<BR>> > north = north + 500;
<BR>> > }
<BR>> > }
<BR>> >
<BR>> >Jan-willem De Bleser wrote:
<BR>> >
<BR>> >> he builds street1.rwx in a straight line. a stripped down robobuilder,
<BR>> that i
<BR>> >> will probablye be allowed to use, because who is gonna cover a
lot with
<BR>> roads?
<BR>> >>
<BR>> >> Edward Sumerfield wrote:
<BR>> >>
<BR>> >> > This error means that the code in roadbuilder.cpp and therefore
the
<BR>> >> > functions from roadbuilder.obj do not exist in the objects that
are
<BR>> being
<BR>> >> > included in the link command.
<BR>> >> >
<BR>> >> > I notice you are using the cpp suffix. This is a C++ suffix
and is
<BR>> therefore
<BR>> >> > compiled a little differently to C code. Look up function name
mangling
<BR>> if
<BR>> >> > you want to learn more.
<BR>> >> >
<BR>> >> > I am not sure what compiler you are using but you might want
to try
<BR>> renaming
<BR>> >> > you code to a .c (lower case "c") file and try again.
<BR>> >> >
<BR>> >> > Make sure that the link step includes the aw.lib file which
is there
<BR>> all
<BR>> >> > these finctions exist.
<BR>> >> >
<BR>> >> > Hey , I guess you are building a road builder, sounds cool.
I hope you
<BR>> are
<BR>> >> > going to add the guestures for pooring tar and driving big rollers
and
<BR>> such.
<BR>> >> > That will be fun to watch.
<BR>> >> >
<BR>> >> > Edward Sumerfield.
<BR>> >> >
<BR>> >> > Jan-willem De Bleser wrote in message
<BR>> <361AC1F0.436F2673 at mediaone.net>...
<BR>> >> > >has anyone actually found out what causes this error?
<BR>> >> > >
<BR>> >> > >--------------------Configuration: roadbuilder - Win32
<BR>> >> > >Debug--------------------
<BR>> >> > >Compiling...
<BR>> >> > >roadbuilder.cpp
<BR>> >> > >Linking...
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_term
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_destroy
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_wait
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_state_change
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_int_set
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_enter
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_login
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_string_set
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_create
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_init
<BR>> >> > >roadbuilder.obj : error LNK2001: unresolved external symbol
<BR>> >> > >__imp__aw_object_add
<BR>> >> > >Debug/roadbuilder.exe : fatal error LNK1120: 11 unresolved
externals
<BR>> >> > >Error executing link.exe.
<BR>> >> > >roadbuilder.exe - 12 error(s), 0 warning(s)
<BR>> >> > >
<BR>> >>
<BR>> >> -----------------------------------------------------------------------
<BR>> -
<BR>> >>
<BR>> >> Jan-willem De Bleser <debleser at mediaone.net>
<BR>> >> High school
<BR>> >>
<BR>> >> Jan-willem De Bleser
<BR>> >> High school <debleser at mediaone.net>
<BR>> >>
Netscape Conference Address
<BR>> >>
Netscape Conference DLS Server
<BR>> >> Additional Information:
<BR>> >> Last Name De Bleser
<BR>> >> First Name Jan-willem
<BR>> >> Version 2.1
<BR>> >
<BR>> >
<BR>> >
<BR>>
<BR>>
Name: h.c
<BR>> h.c Type: C
File (application/x-unknown-content-type-c_auto_file)
<BR>> Encoding: x-uuencode
<BR>>
<BR>>
Name: Makefile.dat
<BR>> Makefile.dat
Type: DAT File (application/x-unknown-content-type-dat_auto_file)
<BR>>
Encoding: x-uuencode
<BR> </BLOCKQUOTE>
</HTML>
|
Oct 8, 1998, 5:19pm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
Lets say that I have my field full of deer. You remember the idea, 50 deer's
wandering around a field, grazing, walking and running away from approaching
people.
<P>All these deer will be driven by the same program but there is no way
for a program to know which deer noticed the approaching person first.
<P>The aw_event_set(AW_EVENT_AVATAR_ADD, function); allows me to set a
function to be called if an avatar approaches the bot within some distance.
The function called is not passed any arguments to indicate which bot noticed
the approaching avatar.
<P>There should probably be a "void *instance" parameter passed to the
function to indicate this.
<P>It will not look good for all my deer to run away at the same time.
<P>Edward Sumerfield.</HTML>
Nov 9, 1998, 11:03am
An interesting concept, not your dead body, but the idea of making money non financial. I
guess I would have to ask why because I can't see any in-world stuff that I would want to
purchase with it. Unless you wanted to start a poker league maybe.
Edward Sumerfield
[View Quote]
> OVER MY DEAD BODY!! I WAS TALKING ABOUT VIRTUAL MONEY, NOT REAL MONEY!! THAT WOULD RUIN
> ACTIVEWORLDS!!
>
[View Quote]> Edward Sumerfield wrote:
>
|
Nov 9, 1998, 11:03am
An interesting concept, not your dead body, but the idea of making money non financial. I
guess I would have to ask why because I can't see any in-world stuff that I would want to
purchase with it. Unless you wanted to start a poker league maybe.
Edward Sumerfield
[View Quote]
> OVER MY DEAD BODY!! I WAS TALKING ABOUT VIRTUAL MONEY, NOT REAL MONEY!! THAT WOULD RUIN
> ACTIVEWORLDS!!
>
[View Quote]> Edward Sumerfield wrote:
>
|
|