2018-04-10 05:35:29

I've been coming back to BGT every now and then while learning other languages, and have found my knowledge of others helping me understand some of the more vague parts of the manual. Most of my experience has been with Python, though I do have some experience with C++, but nothing yet that seems to help me understand the bit about BGT handles. I couldn't find much in the manual, so thought I'd throw it out here. Can someone explain exactly what they are, what they do, how they're used, and why they're used? Thanks in advance!

Los Angeles Based musician, blogger, and programmer.
https://artistibarra.com/

2018-04-10 10:11:49 (edited by Hijacker 2018-04-10 10:14:30)

Hi,

i'm not surprised that you don't know about handles when coming from Python, since Python does all the handle stuff for you already. I'm a bit surprised that you don't know them from the C++ region though. Anyway, here's a bit of explanation.

Any variable contains data, data which needs to be somewhere within the RAM, data which can grow in size. An integer variable with 32 bits is 4 bytes in size, which isn't that much, thats why you usually don't use integer handles that much. But there are variables which can actually grow rather large over time. Consider reading a file into a string which is multiple megabytes in size. The string will have exactly the same size, probably even more, due to null termination and what else. Whenever you call a function which uses this string and doesn't use handles, the compiler will create a copy of this string just to be used within this function. Copying is a rather time-consuming task, especially if the data which needs to be copied is huge.
And now consider classes which contain multiple of those strings, each time you call a function with them as parameter they will get copied over, and those copies will be recycled as soon as the function terminates.
To prevent the compiler from copying huge amounts of data where it isn't actually needed, some inteligent guys invented handles. A handle simply knows the location of specific data inside the RAM, and what type the data is which you can find there. Thats all. That results in a fixed handle size, no matter what data you put into the variable. The handle size differs from OS to OS, but its usually something between 4 and 16 bytes.
OK, now you can, instead of copying data around in-memory, simply code a function which doesn't take the data itself, but a handle which shows the location of the data instead, because this handle is much smaller in size than the data itself. The function can then follow the handle towards the data and process it just like before.
There are even more possible situations in which handles can become useful, like writing functions which return more than just one value, or just-in-place modification of data without the need of a return value, but those are more advanced and can be found on several handle (or pointer) tutorials on the net.
Well, in BGT the thing works like this:

void print_string(string@ data)
{
  // bgt does the dereferencing for us already, which is kinda confusing at times, but you'll probably get the hang of it
  alert("handle printer", data);
}
void main()
{
  string data = "i'm quite a small string, but even i am already bulkier than my handle.";
  string@ data_handle = @data;
  print_string(@data);
  // and because bgt always dereferences variables for us, we can access data_handle just like a usual string
  // so we need to reference it as well
  print_string(@data_handle);
  // it will print the exact same string twice, but in fact, its only stored in memory once
  // and thanks for the smart bgt interpreter, we can even do this:
  print_string(data);
  // since the interpreter knows that print_string() accepts a pointer, it will automatically and silently create a reference for us
}

Hope that helped.
Best Regards.
Hijacker

2018-04-10 17:21:03

This is basically references and passing by reference in C++.

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub

2018-04-10 19:33:29

Thanks so much! I've only very recently started on C++, so have only gotten as far as if statements and now starting onn loops. Haven't yet gotten to what would be comparable to this. Just to make sure I understand, here's the same example with my notes as to what I think I understand is happening. Please correct me if I'm wrong.

// Creates a function that takes a handle to a string as a parameter.
void print_string(string@ data)
{
  // Prints the alert with the string for which the handle that was passed to it points to.
  alert("handle printer", data);
}
void main()
{
  string data = "i'm quite a small string, but even i am already bulkier than my handle.";
  // Not too sure here, but assuming it creates a handle that points to the previous data handle?
  string@ data_handle = @data;
  // Calls the print_string function and passes it a handle to the string data.
  print_string(@data);
  // Again, not sure, but assuming it calls the function again, passing it the handle that points to the handle of string data?
  print_string(@data_handle);
  // Again not sure, but guessing it creates a handle to string data?
  print_string(data);
}

Thanks again for all the help!

Los Angeles Based musician, blogger, and programmer.
https://artistibarra.com/

2018-04-10 20:49:55

I'm not quite sure why, but generally speaking, the only time you need the @ sighn on the right side of an = is when comparing (ex, if(@a==@b), but @a=b).

看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
    George... Don't do that.

2018-04-14 00:13:08

I've spent some time playing with this. While trying this out with strings, I get a compilation error saying that object handles are not supported for this type. Am I missing something?

Los Angeles Based musician, blogger, and programmer.
https://artistibarra.com/

2018-04-14 01:16:07

I'm not sure that it works with strings in bgt. I don't think it works with vectors, either. And not for primitives. So mostly for dictionaries, sounds, classes you create, that sort of thing.

看過來!
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
    George... Don't do that.

2018-04-15 10:29:32

Thanks all for the help. Got another question though, which I believe may be related to this. I've started playing with classes, but having trouble accessing an instance of a class declared in one function from another function. I'm guessing this can be done by using handles? I now understand the general idea of handles, but am still unclear as to how exactly they're implemented, such as how they're declared and manipulated as far as the BGT syntax goes.

Los Angeles Based musician, blogger, and programmer.
https://artistibarra.com/

2018-04-24 04:34:55

Hi,
what you owuld want to do is declare the class as a global class. So in the main part of the script call something sound snd;

then, you can call it at any point of your script. snd.load("poolloop.ogg");
snd.pitch=250;
snd.play_looped();

Ivan M. Soto.
Feel free to check out my work and services.
http://ims-productions.com

2018-04-24 16:03:08

If you could refrain from making things global at all costs, it would make your programming life so much easier. Globals just clog up the namespace with clutter, It makes for sloppy coding habits, and it can make for debugging hell. As i don't even think BGT has a debugger, you will want to stay away from this.

all that being said, i can give you examples of c++ code with references which is close to BGT, but i can't give you the BGT syntax as i do not  know it.

the short answer is yes pass them around in functions.

//header file for person.h

class person
{
    private:
        char name[50];
        int age;
        float height;

    public:
        Person(); //default constructor
        // use a deconstructor or getters and setters if needed
};

Person::Person()
{
    name = "John Smith";
    age = 0;
    height = 0.0;
}

// main.cpp
#include "Person.h"

void fillPerson(Person & p);
void displayPerson(const Person & p);

int main()
{
    Person = p1; //has default args;
    Person p2; //has default ars.

    fillPerson(p1);
    fillPerson(p2);

    displayPerson(p1);
    displayPerson(p2);

    return 0;
}

void fillPerson(Person & p)
{
    //input data overriding defaults for person object
}

void displayPerson(const Person & p)
{
    // display person object overloading << if needed
    // operator<<();
    // only a c++ thing
}

Person & p is passing something by reference or by pointer address. sorry i can't help with the BGT syntax.

I don’t believe in fighting unnecessarily.  But if something is worth fighting for, then its always a fight worth winning.
check me out on Twitter and on GitHub