my AVM2 frustration is reaching a critical level back here... for those who don't know what that is, AVM2 = Flash for all intents and purposes
i find that i'm faced with a plethora of situations where i'm working against this tool... this is mostly related to my job, building flash games... but the reasons for my restlessness stems from this little hobby of mine where i make addons for a certain space flight simulator you might have heard about :hmm:
thing is, in my play time, i get to use wonderful C++ - but at work, the nature of how these web-games are deployed forces me to use either AS3 (java-for-babies made intentionally slower) or, more advanced haXe (which although commendable as a one-man-army project, lacks documentation and general resolve in several areas)
what makes me lose most sleep, is pretty much the "way" AS3/haXe (the AVM2 languages) deal with pretty much everything...
let me try to paint you a picture...
one of the most heavily abused data types in any game's development is the all-singing-all-dancing Vec2D, Vector, Point, whatever-you-call-it pair of X/Y floating-point vars for representing positions in cartesian space...
now, this is quite a basic thing right? any working-state game is bound to rely on at least a couple hundreds of those (or more)
say, such a basic thing should be legally obliged to be optimized to the very bones (bytes) if we're gonna put it through the wringer like we do...
ok, so what's my point?
say i need a few of those on my Orbiter addon ship (C++)
if i plan on keeping them for as long as the ship is "alive" inside the sim, i can just toss them into the class definition with a pair of words, like this:
VECTOR3 v1, v2;
and C++, in it's near-poetical glory not only ensures me those WILL BE THERE when i need them, they will also be contiguosly positioned in the class' memory footprint... awesome right?
or say, if i just need a toss-about vector to hold some temporary data during the course of a function, after which it's needed no longer, i can just throw an exactly-alike line inside said function and again, i'm guaranteed i'll have them ready to go (you'll see the alternative shortly, and it's grim) - and i'll have a clear mind that the memory where they were will be free as soon as i decide it should...
now... why is that a thing?
look what i have to deal with in Flash:
if i want a few vars worth of vectors in my class, i must define them like so:
var vee:Vec2D = new Vec2D(42, 42);
not too bad? well, for once it's redundant... tho that's ok... haXe will even let you skip the type declaration whilst maintaning type-strictness from the "inferred" type... ok then...
but then it hits ya... "vee" is NOT a Vec2D-shaped lump of memory - nooo, far from it, is it a reference to a Vec2D, then? well, that's the thing - WHO KNOWS??
apart from the actual layout of the memory used by that class being miles deep under the sea of undefined, the thing that bears most resemblance to what "vee" actually bears, in a C++ sense, is a pointer...
a pointer... huh, is that bad?
shouldn't be... but they managed it somehow... and even genius-boy Nicolas and his powerful haXe language don't seem mighy enough to fix it...
the reason this is bad is quite simple to grasp, if you know C++
a "pointer" is a distinct memory address holding another memory address, which "points" to the thing you want...
in C++, there are a number of times where those are quite useful, even non-optional, depending on your goals
but those are about one or two in every ten times you need a variable for anything....
yet Flash forces "pointers" implicitly and unrevokably for every data-type more complex than the built-in "Int" and "Float"
theres absolutely no way one can bypass this....
and this is what this imples, not having a "pointer-free" option:
thing 1: the "null" menace...
since a pointer isn't really the data itself, it can very well not point to it at all... and guess what, i Flash by default, it wont!
all variables of non-primitive types default to "null" unless assigned to... and guess what - there's no compile-time checking for that, millions of AVM2 opcodes are wasted every second around the world checking for possibly "null" vars... vars that under no circumstance were intended by the authors to read "null"
it's a segfault-guarantee - by default, it's build to break on ya.... and if you don't watch out, it most certainly will.... but not on your watch - "null" is only catchable in run-time, which means your USERS will find it for you!
beautiful! bravo! they've done it! :facepalm:*1e20
as if that was all that's wrong with it....
of course it doesn't end there.... lets see what else...
thing 2: the "new" imposition
as if things weren't slow enough with interpreted bytecode, get this -- every time you need a non-primitive var to be other than "null" (gasp) - you gotta instantiate something and/or assign to it...
yet "new" is THE ONE SLOWEST piece of code you can have in Flash - the class constructor function, i mean... from what i read, Flash will always re-interpret and "manually" build up your class, which then it allocates into crudely-managed memory (which you may know nothing of)
it returns you a "pointer" to fill up that "var".... relieving it from the ghost of "null"
but that's only at runtime...
you see, 'till then, every member field of a class is set on being "null"... and "null" it shall remain untill the "new" debacle takes place and fills up this bug-hole that adobe dares call a variable....
sad really, but that's the least of it....
thing 3: the best worst way to clean up this mess
ok, so what's gonna go down when i need a Vec2D var to use in a function? (which in C++ we do without even giving it much though)
we still gotta use "new" - there's no such thing as a "stack declaration" in Flash... nooo that would be "hard for us"
so, to have it all be the same, "new" is the way to create every new variable... including those that are needed for not more than a couple of cycles inside a function.... well, what happens to those allocated bytes after no more vars remain "pointing" to it - if this was C++, we'd have a nasty memory leak
but this is Flash - it "takes care" of "complicated things" like that.... (adobe takes another shovel-load at the digging of their own graves)
a complex "garbage collector" systems keeps track of every var you "new"... this, of course means overhead when creating these objects, and some more to get rid of them later...
all so you could absent-mindedly forget to add a "delete" later on... *cringe*
which leads to thing 4: "hey, wait! i was gonna use that!"
not fewer than a whole bunch of times, i had to somehow "overprogram" something just to prevent the GC from killing data i had further plans for...
yep, it's quite capable of that - if it THINKS you can't access that object - it kills it dead!
and nope - it ain't telling you about it... isn't debbuging what end-users are for anyways?
so that leads to further complications... now we gotta ensure that we always have something pointing to our vars, even when doing so would be madly inconvenient...
at this point, i'd like to raise attention to the asynchronous coding model used by Flash....
since stopping code at any time is deemed "foul" and most unmanageable by the very architecture of the AVM2, a "clever" event-driven model is forced upon us poor flash-monkeys...
long story short, there's absolutely no stopping a function for ANYTHING - even if nothing can/should be done before that thing is complete (i.e. loading a file, or receiving socket data)
so Flash constrains us to structure our programs in some what thay permits the terminating of every running scope before the "event" can be triggered... sigh... ok then, let's pretend we don't mind....
first problem... the vars declared in the function that called for the event are lost... the garbage-collector is having it's way with them by now...
second problem, whatever way we choose to preserve that data, implies the risk of a MEMORY LEAK
OMG... we need more facepalm :facepalm:
WHY ON THIS GOOD EARTH THEY WENT TO ALL THIS "NULL-NEW-GC" TROUBLE IF WE END UP WITH THE SAME PROBLEMS AS WITHOUT IT???
actually much worse, really... because without ANY way to explicitly remove a previously instantiated object, (the GC should "take care" of that, remember?) we can only make feeble attempts to satisfy the requirements for something to be considered "garbage"...
and no, you're not told if it works or not... it's erm... "automatic" :suicide:
so lets see.... in C++ we have to decide how to instantiate an object... options are global-memory, class-member, function-scope or "manually" via "new" and ensuring that there's a "delete" later...
seems tough, Flash should be MUCH easier, being all "automatic" and stuff...
in Flash we have to...
-redundantly declare "var" followed by the data type... then mind that until "new" comes along, that variable is defaulted to "NULL" (i can't even... urgh)
- add a myriad run-time checks to ensure that "null" vars don't get where real data is needed
- then we gotta ensurethat we don't lose the pointer to that object, lest the GC-boogieman takes it 'round back and beats it a'ground
- then we gotta make sure that member-vars are reset to "null" before a parenting class is disposed of (which you don't know when it is)
- somehow deal with the fact that low-level memory management must be done "against the machine" in bytecode interpreted language
so let me ask of you... given these considerations - API's aside, which is harder to work with - C++ or
Flash?
well, one is used for "play" while the other is "work"... makes sense, no?
oh, the humanity :uhh:
next post will be about my conceptual solution to this cataclysmic series of mis-features that plague my tool-of-the-trade... i shall call this: "aXiom"
i find that i'm faced with a plethora of situations where i'm working against this tool... this is mostly related to my job, building flash games... but the reasons for my restlessness stems from this little hobby of mine where i make addons for a certain space flight simulator you might have heard about :hmm:
thing is, in my play time, i get to use wonderful C++ - but at work, the nature of how these web-games are deployed forces me to use either AS3 (java-for-babies made intentionally slower) or, more advanced haXe (which although commendable as a one-man-army project, lacks documentation and general resolve in several areas)
what makes me lose most sleep, is pretty much the "way" AS3/haXe (the AVM2 languages) deal with pretty much everything...
let me try to paint you a picture...
one of the most heavily abused data types in any game's development is the all-singing-all-dancing Vec2D, Vector, Point, whatever-you-call-it pair of X/Y floating-point vars for representing positions in cartesian space...
now, this is quite a basic thing right? any working-state game is bound to rely on at least a couple hundreds of those (or more)
say, such a basic thing should be legally obliged to be optimized to the very bones (bytes) if we're gonna put it through the wringer like we do...
ok, so what's my point?
say i need a few of those on my Orbiter addon ship (C++)
if i plan on keeping them for as long as the ship is "alive" inside the sim, i can just toss them into the class definition with a pair of words, like this:
VECTOR3 v1, v2;
and C++, in it's near-poetical glory not only ensures me those WILL BE THERE when i need them, they will also be contiguosly positioned in the class' memory footprint... awesome right?
or say, if i just need a toss-about vector to hold some temporary data during the course of a function, after which it's needed no longer, i can just throw an exactly-alike line inside said function and again, i'm guaranteed i'll have them ready to go (you'll see the alternative shortly, and it's grim) - and i'll have a clear mind that the memory where they were will be free as soon as i decide it should...
now... why is that a thing?
look what i have to deal with in Flash:
if i want a few vars worth of vectors in my class, i must define them like so:
var vee:Vec2D = new Vec2D(42, 42);
not too bad? well, for once it's redundant... tho that's ok... haXe will even let you skip the type declaration whilst maintaning type-strictness from the "inferred" type... ok then...
but then it hits ya... "vee" is NOT a Vec2D-shaped lump of memory - nooo, far from it, is it a reference to a Vec2D, then? well, that's the thing - WHO KNOWS??
apart from the actual layout of the memory used by that class being miles deep under the sea of undefined, the thing that bears most resemblance to what "vee" actually bears, in a C++ sense, is a pointer...
a pointer... huh, is that bad?
shouldn't be... but they managed it somehow... and even genius-boy Nicolas and his powerful haXe language don't seem mighy enough to fix it...
the reason this is bad is quite simple to grasp, if you know C++
a "pointer" is a distinct memory address holding another memory address, which "points" to the thing you want...
in C++, there are a number of times where those are quite useful, even non-optional, depending on your goals
but those are about one or two in every ten times you need a variable for anything....
yet Flash forces "pointers" implicitly and unrevokably for every data-type more complex than the built-in "Int" and "Float"
theres absolutely no way one can bypass this....
and this is what this imples, not having a "pointer-free" option:
thing 1: the "null" menace...
since a pointer isn't really the data itself, it can very well not point to it at all... and guess what, i Flash by default, it wont!
all variables of non-primitive types default to "null" unless assigned to... and guess what - there's no compile-time checking for that, millions of AVM2 opcodes are wasted every second around the world checking for possibly "null" vars... vars that under no circumstance were intended by the authors to read "null"
it's a segfault-guarantee - by default, it's build to break on ya.... and if you don't watch out, it most certainly will.... but not on your watch - "null" is only catchable in run-time, which means your USERS will find it for you!
beautiful! bravo! they've done it! :facepalm:*1e20
as if that was all that's wrong with it....
of course it doesn't end there.... lets see what else...
thing 2: the "new" imposition
as if things weren't slow enough with interpreted bytecode, get this -- every time you need a non-primitive var to be other than "null" (gasp) - you gotta instantiate something and/or assign to it...
yet "new" is THE ONE SLOWEST piece of code you can have in Flash - the class constructor function, i mean... from what i read, Flash will always re-interpret and "manually" build up your class, which then it allocates into crudely-managed memory (which you may know nothing of)
it returns you a "pointer" to fill up that "var".... relieving it from the ghost of "null"
but that's only at runtime...
you see, 'till then, every member field of a class is set on being "null"... and "null" it shall remain untill the "new" debacle takes place and fills up this bug-hole that adobe dares call a variable....
sad really, but that's the least of it....
thing 3: the best worst way to clean up this mess
ok, so what's gonna go down when i need a Vec2D var to use in a function? (which in C++ we do without even giving it much though)
we still gotta use "new" - there's no such thing as a "stack declaration" in Flash... nooo that would be "hard for us"
so, to have it all be the same, "new" is the way to create every new variable... including those that are needed for not more than a couple of cycles inside a function.... well, what happens to those allocated bytes after no more vars remain "pointing" to it - if this was C++, we'd have a nasty memory leak
but this is Flash - it "takes care" of "complicated things" like that.... (adobe takes another shovel-load at the digging of their own graves)
a complex "garbage collector" systems keeps track of every var you "new"... this, of course means overhead when creating these objects, and some more to get rid of them later...
all so you could absent-mindedly forget to add a "delete" later on... *cringe*
which leads to thing 4: "hey, wait! i was gonna use that!"
not fewer than a whole bunch of times, i had to somehow "overprogram" something just to prevent the GC from killing data i had further plans for...
yep, it's quite capable of that - if it THINKS you can't access that object - it kills it dead!
and nope - it ain't telling you about it... isn't debbuging what end-users are for anyways?
so that leads to further complications... now we gotta ensure that we always have something pointing to our vars, even when doing so would be madly inconvenient...
at this point, i'd like to raise attention to the asynchronous coding model used by Flash....
since stopping code at any time is deemed "foul" and most unmanageable by the very architecture of the AVM2, a "clever" event-driven model is forced upon us poor flash-monkeys...
long story short, there's absolutely no stopping a function for ANYTHING - even if nothing can/should be done before that thing is complete (i.e. loading a file, or receiving socket data)
so Flash constrains us to structure our programs in some what thay permits the terminating of every running scope before the "event" can be triggered... sigh... ok then, let's pretend we don't mind....
first problem... the vars declared in the function that called for the event are lost... the garbage-collector is having it's way with them by now...
second problem, whatever way we choose to preserve that data, implies the risk of a MEMORY LEAK
OMG... we need more facepalm :facepalm:
WHY ON THIS GOOD EARTH THEY WENT TO ALL THIS "NULL-NEW-GC" TROUBLE IF WE END UP WITH THE SAME PROBLEMS AS WITHOUT IT???
actually much worse, really... because without ANY way to explicitly remove a previously instantiated object, (the GC should "take care" of that, remember?) we can only make feeble attempts to satisfy the requirements for something to be considered "garbage"...
and no, you're not told if it works or not... it's erm... "automatic" :suicide:
so lets see.... in C++ we have to decide how to instantiate an object... options are global-memory, class-member, function-scope or "manually" via "new" and ensuring that there's a "delete" later...
seems tough, Flash should be MUCH easier, being all "automatic" and stuff...
in Flash we have to...
-redundantly declare "var" followed by the data type... then mind that until "new" comes along, that variable is defaulted to "NULL" (i can't even... urgh)
- add a myriad run-time checks to ensure that "null" vars don't get where real data is needed
- then we gotta ensurethat we don't lose the pointer to that object, lest the GC-boogieman takes it 'round back and beats it a'ground
- then we gotta make sure that member-vars are reset to "null" before a parenting class is disposed of (which you don't know when it is)
- somehow deal with the fact that low-level memory management must be done "against the machine" in bytecode interpreted language
so let me ask of you... given these considerations - API's aside, which is harder to work with - C++ or
Flash?
well, one is used for "play" while the other is "work"... makes sense, no?
oh, the humanity :uhh:
next post will be about my conceptual solution to this cataclysmic series of mis-features that plague my tool-of-the-trade... i shall call this: "aXiom"