• Hello [name]! Thanks for joining the GMC. Before making any posts in the Tech Support forum, can we suggest you read the forum rules? These are simple guidelines that we ask you to follow so that you can get the best help possible for your issue.

Discussion [SUGGESTION] script_execute() shortcut and more...

Z

Zinx

Guest
I have two suggestions I'd like to make for GMS2 that I feel like is something little that would make more traditional OOP users happy. That would be a script_execute() shortcut. At the moment, we can access scripts stored in variables by using script_execute. That is great and all, but it'd feel more readable (in my opinion) if you made a shortcut for script_execute by utilizing the parentheses. Not only that, but maybe this shortcut could also utilize user events (which should an array like the arguments array). For example, let's say I wrote this:



First it checks to see if "ha" is a script or not then executes the corresponding function. Of course, this method does have flaws (like I could put that whole code segment in a script, but I'd find it more functional to have the GMS2 interpreter do that for me via so:



Note: notice how the user_event "ha" uses an array rather than the old-fashioned number after the name.



Now, this was a little one-sided, so here's a more realistic example. In the code below, I am cycling through every instance of the object obj_ai and executing the move function (which is a script I created off-screen):



While the non-shortcut version is this:



Basically, the way I see it is that we have shortcuts like this for DS Maps, so why not create a shortcut for scripts and user events?
 

zbox

Member
GMC Elder
If you want a more OOP approach you should be using maps as your "object" structures, not actual GM Objects. That way you can have a key for example, "create", "step" and "draw" that all correspond to function pointers. Then you can loop over all the maps, execute each map's (object's) respective function and pass the instance in with it. Would look pretty neat.

EDIT: Check this out, a nice start of some OOP implementation like thing
https://drive.google.com/open?id=0B7C84bRlE1LLcXFpTk5pNHpVLU0

For a little overview seeing as I dedicated some time to it, creat objects like:
Code:
ball1 = new(o_ball, "x", room_width/2, "y", 10, "xVel", 0);
o_ball is an instance type. In reality it is a script that looks like this, and you would use this code as a template for all your other objects where you need to supply methods:
Code:
//o_ball definition
var m = ds_map_create();

m[? "create"] = scr_ball_create;
m[? "step"]   = scr_ball_update;
m[? "draw"]   = scr_ball_draw;
m[? "reset"]  = scr_ball_reset;

var o = ds_map_create();
ds_map_add_map(o, "methods", m);
ds_map_add_map(o, "properties", ds_map_create());

return o;
So one of the ball's methods, for example, its step method, looks like this:
Code:
var o = argument0;

o[? "xVel"] += o[? "xAcc"];
o[? "yVel"] += o[? "yAcc"];

o[? "x"] += o[? "xVel"];
o[? "y"] += o[? "yVel"];

if (o[? "y"] + o[? "rad"] > o[? "floorY"]) {
    o[? "y"] = o[? "floorY"] - o[? "rad"];
    o[? "yVel"] = -o[? "yVel"] * o[? "yDamping"];
 
    o[? "xVel"] *= o[? "xDamping"];
}

if (o[? "x"] < - o[? "rad"])
    o[? "x"] = room_width + o[? "rad"];
 
if (o[? "x"] > room_width + o[? "rad"])
    o[? "x"] = - o[? "rad"];
And then to make the whole system active you just need a controller object doing this:
Code:
//Step - Management code
OOP_Perform("step");

//Draw - Management code
OOP_Perform("draw");
The OOP_Perform method also allows you to supply a second parameter, a type, so the methods will only be executed on a certain instance type.

Anyway if you're confused but still interested download the example and check it out. Quite cool. Also I think I just ignored OP's topic and posted an OOP-ish-thing-in-GM example. Sorry OP. Ohwell :p
 
Last edited:
Z

Zinx

Guest
If you want a more OOP approach you should be using maps as your "object" structures, not actual GM Objects.

That way you can have a key for example, "create", "step" and "draw" that all correspond to function pointers.

Then you can loop over all the maps, execute each map's (object's) respective function and pass the instance in with it. Would look pretty neat.
While I do stand by my point (it would give yet another reason for people to switch to GMS2), I am curious by your mention. So you're saying to have a ds_map where each key leads to a script? Kind of like so:

Note: in this case, I ignored all ds_map checks to make sure a value exists.

I'm sure I misunderstood what you meant, but I'm really curious on what your proposal is as I have been trying to think of a method to impose local functions onto objects.
 

zbox

Member
GMC Elder
Yeah I don't think I addressed your topic much I just made a little object system off my own bat for a laugh :p

Check out the source and see if it benefits you in any way. My main concern is always moving away from the bloat of GM-Objects. So the solution in my demo is to ditch GM objects totally and provide my own object system, which you can perform their "own" local methods with OOP_Perform(methodName)'


Did some performance test with an equivalent GM based object system (1000 instances), unfortunately in VM mode GM Objects are actually definitively faster. In YYC export however the performance seems to be on par. Should do a little more scientific investigation but dont have time atm.
 
Last edited:
Z

Zinx

Guest
Yeah I don't think I addressed your topic much I just made a little object system off my own bat for a laugh :p

Check out the source and see if it benefits you in any way. My main concern is always moving away from the bloat of GM-Objects. So the solution in my demo is to ditch GM objects totally and provide my own object system, which you can perform their "own" local methods with OOP_Perform(methodName)
A-ha! I see what you meant. So you really are basically creating your own object system using maps. While the writing wouldn't exactly be the same, that is definitely a way to get OOP working, and I really enjoy your work there. However, this seems like it could be more of a hassle setting up the functions. For example, here is the ball update event in GML:

Code:
var o = argument0;

with(o) {
    xVel += xAcc;
    yVel += yAcc;

    x += xVel;
    y += yVel;

    if (y + rad > floorY) {
        y = floorY - rad;
        yVel = -yVel * yDamping;
       
        xVel *= xDamping;
    }
   
    if (x < -rad) {
        x = room_width - rad;
    }

    if (x > room_width + rad) {
        x = -rad;
    }
}
Also, as you probably know, their "own" functions aren't really their "own" as they are literally just scripts which any object can access. For example, while both o_ball and o_window may both have different methods named "update", in reality they are just two different scripts using a self-imposed hierarchy (i.e. scr_ball_update). Now, if you were somehow able to make your own line pointer, that could be something special.

EDIT:
That experiment is definitely something that should have been done, so thank you. However, I would have been upset with YoYo a little if you fairly easily created a better object system than theirs.
 
Top