Game Development Community

"};" - Question about Syntax

by Gina-Marie -Netjera- Hammer · in Torque Game Engine · 03/01/2005 (5:06 pm) · 14 replies

I've noticed that in the case of functions we surround with braces "{" and "}" just as in C++. However, in some cases, most noticeably datablocks, we use "};" to end the block of commands instead of just the closing brace.

Can anyone explain why, please?

Thanks in advance,

Gina-Marie

#1
03/01/2005 (5:19 pm)
Interesting, this same question was asked recently in I think the engine private forums--I'll try to summarize my semi-long winded answer from there:

TGEScript uses the {...} construct slightly differently with datablocks and the script new operator to make the parameters defined in datablocks, and sent in the new command much easier to read--there can be a lot of them!

To make this code readability decision work with the byte-code compiler however, the {...} block needs a ; at the end for the above two uses, because they are actually all one statement. If you simply remember that with the datablock definitions, and use of the new command you need a semi-colon at the end of the {...} block, and in all other cases you do not, you'll be happy!
#2
03/01/2005 (5:26 pm)
Ah, I think I understand it now, thanks!

Some of this syntax is really new to me. I'm still struggling with understanding namespaces, methods and that elusive

function isSomethingWeird::WhatTheHeckIs(%syntax)

:)

I originally thought that it was a way to call a sub-function.. like you'd call

myFunction.mySubFunction

But you don't ever fully define "isSomethingWeird" anywhere. Is the stuff before the "::" a premade function defined specifically for TGE or am I missing something?

Thanks a bunch for the help - I'll muddle through. *muddle, muddle* But it really helps to clearly understand this stuff. :)
#3
03/01/2005 (5:39 pm)
IsSomethingWierd is (and my terminology may be off here, Gonzo would be a good one to explain this better...) the namespace that the function resides in. For example, if you have a new script object that is declared like:

%myObject = new MyObject () {
param1 = somevalue;
param2 = somevalue;
param3 = somevalue;
};

then if you call %myObject.MyFunction();, it will look for:

function MyObject::MyFunction(%obj)
{
.
.
.
}

to find what function you want to call. In this case, %obj (or, more correctly, the first parameter in your function definition) is the objectID of the calling object.

Please do keep in mind that you need a source code (C++) implementation of any new object types that you may wish to create--the pseudo-code above is just for explanation purposes.

Also, one of the more common uses you will see in script is to create your functions as part of the datablock's namespace, such as:

MyObjectData::MyFunction(%this)
{
}

The main reason for this is that you may share a lot of functionality this way--every object that is assigned that datablock uses the same namespace (if called properly). To be fully honest, both ways work, but the second is how most people do it. I suspect there can be a complication if you do it both ways at once--anyone have comments/feedback about that? I'm fuzzy myself on how this type of situation would be handled.
#4
03/02/2005 (11:35 am)
Maybe I really *don't* understand namespaces enough, because I didn't really understand much of the explanation you provided. (Thanks for the try, though.)

My understanding, which I'm almost certain is wrong because I still feel confused, is that there's no difference between calling a function like this:

MyFunction.MySubFunction

and

MyFunction::MySubFunction.

But that doesn't seem to be right. I think I need to start with the very basics of this topic in order to understand. I have a little C++ - basic stuff - mostly the structured stuff, no OOP yet - and really old languages like BASIC and PASCAL.

I'm sure I'm intelligent enough to understand this material, but I think I'm missing some background that I need, perhaps. Although the book was listed as not requiring any programming languages, I'm having a great deal of trouble understanding some of the concepts. *sigh*

If you could give me a line on where I could find some background information related to this concept, I'd really appreciate it.

Thanks!
#5
03/02/2005 (5:53 pm)
MyFunction.MySubFunction means that MyFunction is an actual object.

MyFunction::MySubFunction means MyFunction is a namespace but I cannot access MyFunction - it isn't an object or a variable or anything.

Namespaces would be useful for this:

Math::Add(x, y)

List::Add(x, y)


I have two functions, both named Add but with very different purposes and I certainly don't want to accidently call the wrong one. By putting them each in their own namespace, we can avoid all confusion.
#6
03/02/2005 (8:27 pm)
So essentially, MyFunction in

MyFunction::MySubFunction

is something you define on-the-fly? Just as you would a variable? And it's only use is to give a.. sort of header.. to duplicate function calls?

I might be starting to understand this, I think.

I'll have to pull up one of the sample programs in the book and go through it step-by-step tomorrow. See if it makes more sense now. If I'm understanding correctly, then we're using a lot of duplicate functions and Mr. Finney is simply creating places to call them from so we don't get confused, right? Or are there specific, predefined namespaces in Torque that I should know about?

Thanks for the help, I'm beginning to feel a little like Eliza Doolittle now! :)

Incidentally, if you have two functions named "Add", as in your example - why wouldn't you just name them differently? Like Add1 and Add2?
#7
03/02/2005 (8:57 pm)
On your last question, because Add5467893 can be hard to remember what it does, while AircraftData::add() is easier!
#8
03/02/2005 (9:54 pm)
Exactly. :)
#9
03/04/2005 (7:31 am)
Oh! So, as with variables, you make the namespace something meaningful.

So essentially, if I have function add defined to add togther two numbers, then I could do:

PerimeterRectangle:Add

To remind myself that I'm adding together the numbers that will make a perimeter.

and

FruitInBasket::Add

To remind myself that I'm adding together the number of fruit in a basket.

Is that right? Add is the same in both cases, but the namespace indicates how it's used?

Thanks again,

Gina-Marie
#10
03/04/2005 (7:46 am)
You are getting close to the concept, yes. The other thing to keep in mind is that it isn't simply a "label", but it is also a grouping for related functions that should be treated as a data set, or data type. I.E:

"FruitBasket" would be a container in your game that can contain fruit.
--fruit can be placed in the container.
--fruit can be taken out of the container.
--the container can be "looked in to" to select a specific fruit.

So, a "Basket" is by nature a good namespace, and would be set up something like this (just an example, don't try to add this to any code in this form!--it's not correct TGEScript syntax, or even technique)

Basket::Add()
--adds a new basket to the world
Basket::addFruit(%this, %fruit)
--adds a new fruit to the basket identified by %this
Basket::takeFruit(%this, %fruitName)
--checks to see if any fruit that matches %fruitName is in the basket, if so, removes from basket and returns objectID

and with this little namespace, you can do all kinds of things:

%basketOne = new Basket();
%basketTwo = new Basket();
%myOrange = new Fruit(Orange);
%myBanana = new Fruit(Banana);
%myPear = new Fruit(Pear);

%basketOne.addFruit(%myOrange);
%basketTwo.addFruit(%myBanana);
%basketOne.takeFruit("Banana"); (fails, no Banana in BasketOne)
%basketTwo.takeFruit("Banana"); (succeeds, Banana in BasketTwo)
%basketOne.addFruit(%myPear);
%basketOne.addFruit(%myBanana);

As you can see, Namespaces (and the concept of data abstraction) is an object oriented concept that allows the programmer to create functionality that makes sense for a type of data or data set, and deal with it at a higher level. Once all of the implementation is checked, the programmer now has high level capabilities to accomplish tasks, without ever having to re-write the functions to do those tasks.
#11
03/04/2005 (5:19 pm)
So you make a container when you give it a name. Just like you define a name for a variable - which is a container for a particular piece of data; or you define a name for a function - which is a container for a particular set of logically-grouped commands.

Containers within containers.. hmm.

I guess what throws me is that I'm used to programming syntax where you have to define the variable and type before it actually exists. I guess I keep looking at these namespaces and wondering, "Where are they defined?" But what you're saying is that when we call them, we define them and make them in the same step as using them. That's pretty convenient.

I know torque has built in functions like setTransform() and getTransform() and so forth. Are there built in namespaces, too?
#12
03/05/2005 (8:31 am)
This is actually quite helpful, I too am around mid chapter 4 approaching 5 and suddenly alot of heavy stuff has been laid on. I am not sure I understand it all, but I will just keep plodding through. I wish there were some more excercises in the book, I find they help alot. :)

Ian
#13
03/05/2005 (8:52 am)
As wierd as this is going to sound, don't get too wrapped up about the theory behind scripting! TGEScript is a typeless language, so yes, you create new variables/namespaces/etc. the first time you use them.

I used the fruit basket example simply because that's what you brought up, and it was a simple example! Namespaces don't always act as containers (in the way a fruit basket does, "containing" fruit)--unless you are using the term container is a very loose sense. For example, Player is all of the data and functions that relate to the concept of a player, but a Player is not a container in the same way a fruit basket is...make sense?

At it's root level, a Namespace in TGEScript is really just a place for the byte code compiler to look for functions. In that way it's very similar to a C++ class in usage and theory (but certainly not exact implementation or syntax)--a way to use Object Oriented Programming techniques within a typeless language (TGEScript).

In general, the important things to keep in mind:

1) If you have a set of data that is associated with each other, you'll want to keep that data and the functions associated with it together. That will commonly be done by implementing a namespace of some sort.

2) Whenever you have a function that will need to be called by more than one object, and all of those objects are of the same "type" (bad word, since TGEScript is typeless), then you'll define that "type" as a namespace, which allows all of the objects to use the function.

a TGE example from starter.fps is the GameConnection:: namespace. all %clients are GameConnections, and therefore all have access to any of the functions in the GameConnection:: namespace such as:

GameConnection::onClientEnterGame()
GameConnection::onClientLeaveGame()
GameConnection::spawnPlayer()


Any (valid) %client on the server can execute functions in that namespace by using %client.onClientEnterGame(), %client.spawnPlayer(), etc... Keep in mind that any (valid) %client object was created in the game (server side) via a new GameConnection () command, which is how the engine knows which namespace is associated.

I highly recommend that if this topic interests you, pick up a book or two on Object Oriented Programming--it will explain a lot of the background concepts that are part of OOP, and will help to make this a lot more clear.

Some of the theory that we're covering here is data abstraction/encapsulation, as well as (indirectly) inheritence and possibly composition.
#14
03/05/2005 (9:24 am)
If you want to get really crazy, namespaces are also used in XML. They allow you to mix different markup languages freely within a document. For example, you could have an XHTML document with formulas written in MathML. The user agent knows which is which thanks to namespacing.