0

Generally low-level languages support structs, just what I want to hackishly define in AS3. We can do this on C#, but why do it? Because 3d positions are very common and it's boring to create an object for each 3d position just because you can't get a immutable structure in other languages freely, unless you don't want to declare a bunch of locals yourself.

Repl.it

struct Vec3f {
    public double x;
    public double y;
    public double z;
}

class Test {
    static void Main() {
        Vec3f cam1 = new Vec3f();
        Vec3f cam2 = cam1;
        cam1.x = 10;
        System.Console.WriteLine(cam1.x == cam2.x); // false
    }
}

As you can see, Vec3f is a immutable value type. But in JS, Lua, AS3 or whatever we usually can't have these kinds of immutable structures. Yep, we use objects, which are always garbage-collected AFAIK.

In AS3 I wanted to be able to meta-mark a class as *immutable*, but I don't see how if that's not supported anywhere. There's no existing ABC-level tool, so how?

[Immut] // or [Immutable]
class Vec3f {
    var x: Number
    var y: Number
    var z: Number
}

var a: Location = new Location
var b: Location = a
a.x = 10
a.y === b.x // `true`, but should be *********`false`*********
            // for `Vec3f`.
  • 1
    Plain data types (**String**, **Boolean**, **int**, **uint**, **Number**) are immutable and are passed as a value, all other data types subclass the **Object** class and are mutable, which means you pass any instance as a reference (pointer if you speak C/C++) to it. There's no avoiding it. The common practice here is to define classes with a custom **clone(...)** method that returns a (shallow or deep upon your needs) copy of a given instance. – Organis Aug 07 '18 at 23:16
  • @Organis Immutability isn't my goal at all. I wanna immutability in the sense `Vec3f` objects violate the default object rule (like `Vec3f` were a primitive), so mostly a `[Immut]` meta-data could allow me to violate default mutability. I wanna make `Vec3f` work exactly as a native, low-level and non-object C `struct`. What I want is that `Vec3f` violates at all many object concepts from ECMAScript and expands everywhere like it were a local box, container. –  Aug 07 '18 at 23:19
  • Yes, I understand what you aim at. Let me say it again: there's no avoiding it. AS3 just does not have such an option or metadata. – Organis Aug 07 '18 at 23:22
  • @Organis It's possible to violate `Vec3f` semantics in ABC-level, so it's just missing a tool for that. The ABC tool can expand it to 1) ABC locals and variables, 2) box it to an object (whose constructor is still flagged as _Vec3f_, making `is` and `as` operators work) where it's _\*irregularly\*_ used 3) and maybe some extra actions. Extra checking can ensure the struct-like class is appropriate for inheritance. –  Aug 07 '18 at 23:26
  • Weeeell, you can command the compiler to keep the custom metadata while compiling to ABC: https://stackoverflow.com/questions/5729294/custom-metadata-in-as3-flex Then you indeed need some ABC editor tool to tweak the result so it respects the metadata. As a proof of concept, well, if you say it is possible. Otherwise, I believe, **clone(...)** way is much simpler. – Organis Aug 07 '18 at 23:32

1 Answers1

0

(1)

Generally low-level languages support structs, just what I want to hackish-ly define in AS3.
We can do this on C#...

With regards to your AS3 versus C# results...

// C#   :   System.Console.WriteLine(cam1.x == cam2.x); // gives false.
// AS3  :   trace(a.y === b.x); // gives "true", but should be ******** "false".

The AS3 results are because you previously used: var b: Location = a which effectively makes b == a. So now whenever a changes then b changes equally too.

Solution:

To create a hack-ish version of a struct, you'll simply have to use a class. To make each class unique, just use the new keyword.

import Vec3f; //import the class (if external AS file)

//# then use "new" keyword to make variables as unique instance of class
var cam1 :Vec3f = new Vec3f();
var cam2 :Vec3f = new Vec3f();

//# check start values (where... vec3f.x == 5 )
trace(" 01 :: cam1.x == " + (cam1.x) ); //gives 5
trace(" 01 :: cam2.x == " + (cam2.x) ); //gives 5

//# update values
cam1.x = 10;
trace("cam1.x == cam2.x ??? result : " + (cam1.x == cam2.x) ); //gives false

//# value checks v2 (results after update)
trace(" 02 :: cam1.x == " + (cam1.x) ); //gives 10
trace(" 02 :: cam2.x == " + (cam2.x) ); //gives 5

Even Java does not have struct objects so the typical solution (example) is to "just use classes".

In AS3 others have solved this by creating their own point3D implementation like in this example.

(2)

But why do it (use a struct)? Because 3D positions are very common and it's boring to create an object for each 3D position.

Maybe investigate the Vector3D API. It's easy to setup (the w is an optional value, eg: angle or velocity).

var some_vec3f = new Vector3D(x:Number = 0., y:Number = 0., z:Number = 0., w:Number = 0.);

Also read:

Hopefully this might be enough to help you achieve a data-container for your 3D points.

VC.One
  • 14,790
  • 4
  • 25
  • 57
  • Thank you for the answer. Truly I know how to use classes and define my own constructors, or maybe even builders. But there's an inefficiency in constructing true objects (when using `new Class` or just `{ p: 'v' ] }, [ array ]`), or mayben't at all. The inefficiency is the fact the instance object will go to heap and be garbage-collected in a hidden mark-sweep algorithm, while within a `struct` I won't have these issues, it'll simply be performant as a primitive value. –  Aug 13 '18 at 09:55
  • But I still guess the performance difference between value-type `struct`s and objects (`class`es, usually) is minor, if many persons out there say so... –  Aug 13 '18 at 09:57