Struct goofiness

About Monkey 2 Forums Monkey 2 Development Struct goofiness

Tagged: ,

This topic contains 7 replies, has 7 voices, and was last updated by  Amon 2 years ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #7570

    Ethernaut
    Participant

    https://github.com/blitz-research/monkey2/issues/160

    In the following code, calling the virtual method Update() from each item in the stack will call the Base Struct’s Update, instead of the correct one. Replacing Structs with Classes works as expected.

    Cheers.

    #7571

    abakobo
    Participant

    In the docs:

    Structs

    Structs are similar classes, but differ in several important ways:

    A struct is a ‘value type’, whereas a class is a ‘reference type’. This means that when you assign a struct to a variable, pass a struct to a function or return a struct from a function, the entire struct is copied in the process.
    Stucts are statically typed, whereas classes are dynamically typed.
    Struct methods cannot be virtual.
    A struct cannot extend anything.

    So it should tell you may not extend struct and use virtual methods. Or structs are now extendable?

    #7574

    Ethernaut
    Participant

    Hmm bummer, didn’t know about that. An error message would be nice in a case like this.

    How would you deal with this situation, where I need a single stack and each item in the stack needs to call its own “Update” method? I’m creating a render queue (so I can sort the drawing order based on coordinates) where each item in the queue can be of a different type (“Image quad”, “text”, etc.).

    The reason I’m using structs is that a large number of those are created each frame and discarded on the next.

    I guess I’ll create a single Struct with a “style:Int” field, and use 0 for quads, 1 for text, etc, and the Update method will select the appropriate rendering style for each item.

    Thanks!

    #7577

    Mark Sibly
    Keymaster

    Structs cannot use ‘extends’ – I’m sure they use to give an error, not sure what happened there but I’ll add the error back.

    Hypothetical structs of common base type could not (easily) be added to a stack anyway, mainly because different derived structs may have different sizes, eg: a ‘Text Extends Drawable’ struct may have an extra ‘text’ field etc, and stacks (or really the underlying arrays) expect elements to be of the same size for sane indexing. This is not a problem with class objects, as elements are just pointers.

    In general, this is the core problem with allowing structs to ‘extend’ other structs – converting a derived struct to a base struct (when assigning to var or passing to function) often means truncating the derived struct – and this really means changing the ‘virtual function table’ pointer in case derived’s virtual methods use fields not in base. This means virtual methods are pretty much useless.

    All in all it gets pretty ugly so I decided to give it a miss.

    #7734

    cocon
    Participant

    In the world of C structs technically are a collection of variables, where this is the only way that the data of the program can be modeled.

    However in other object oriented languages, usage of structs has been limited to some very specific purposes. You have to be totally responsible why you need to use structs. Perhaps you might need, compatibility with native C libraries, or having some binary memory alignment, or have some “structs” with very precise lifescope.

    Elevating the features of structs is a trap that high level programming languages make. Perhaps other programming languages as C# want to make life easier and provide some useful features. But in the end it only makes things complicated, because makes design choices ambiguous.

    In practical terms, it’s not about gaining any benefits in speed or efficiency. One user in this forum created some benchmarks to see the difference in speed between classes and structs and the difference is less than 30% (structs are faster).

    #7765

    sicilica
    Participant

    The biggest argument not to use structs is the 1kb rule – 90% of heap allocations are garbage by the time another 1kb of data has been allocated, or something.

    Even if computers are fast, I don’t think “never use structs” is a good answer though. While I don’t care about how memory is configured most of the time, I care a lot for performance-critical code, and structs give you a lot more control over how your memory is laid out (so do custom allocators, but ew). For doing 3D, for example, you can use structs to make sure that all of your mesh data is contiguous in memory. If there are tens of thousands of entities in your game, you might care about being able to have a fast way to index all of them (to iterate over some subset, or just get a list of all enemies, or whatever). The addition of structs was by far the most compelling reason for me to want to switch to monkey2 instead of staying on the otherwise-fantastic monkey1.

    But yeah, unless you *know* that there’s a reason you’re supposed to use a struct, always use classes! You’ll get yourself into a lot less trouble.

    #7770

    therevills
    Participant

    I’m really lazy and just use classes for everything!

    #7900

    Amon
    Participant

    I learnt a lot from this thread. Thank you.

    🙂

Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.