Ported particle System "Memory access violation" [SOLVED]

About Monkey 2 Forums Monkey 2 Programming Help Ported particle System "Memory access violation" [SOLVED]

This topic contains 8 replies, has 3 voices, and was last updated by  nobuyuki 2 years ago.

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #7624

    Diffrenzy
    Keymaster

    Hi, I did a quick port of https://github.com/nobuyukinyuu/argyne and put it here: https://github.com/Difference/argyneParticles4MX2

    The example runs, but I keep getting random “Memory access violation” . I dont get why, because it happens after a null check.

    Can anybody spot what I’ve done wrong? (I don’t quite get the output of the debugger.)

    [EDIT]: To quickly reproduce the error, pres spacebar 2-5 times, whilst moving the mouse.

    #7628

    Diffrenzy
    Keymaster

    I’m thinking it may have something to do with that I changed the Clone() Methods from :Object to dedicated types?

    #7633

    Mark Sibly
    Keymaster

    Ok, this one’s a bit fun as I’m finding it hard to reproduce here, but it does happen every now and then. What OS are you on? Windows 10 here.

    Anyway, this code looks a bit dodgy to me, one of the ParticleEmitter ctors:

    This is invoking Super.New using ‘unconstructed’ fields of the super class as parameters, ie: Self.initial and Self.last (which are really members of BaseParticle). This is IMO kind of nonsense code, like Local k:=k or something.

    These are *usually* null before super.Ctor is called, but apparently not always. Changing the ctor to:

    …appears to fix it for me, although like I say it’s hard to reproduce here so I’m not 100% sure.

    The ‘big fix’ is probably to (at least) disallow use of any base class members when evaluating parameters for use with Super.New calls, as it doesn’t make sense to allow use of yet-to-be-constructed members.

    #7640

    Diffrenzy
    Keymaster

    Great, fix confirmed working 🙂    (‘m on MacOS Sierra)

    Well spotted!

    I think implementing the “big fix” is worth looking into, although it is a logical error in the code, MX2 should probably catch it, especially because it is hard to reproduce, and only occurs randomly.

    [EDIT] I guess Self.something could be a global, set to something and that case should be allowed…

     

    PS: For anyone interested https://github.com/Difference/argyneParticles4MX2 is updated with the corrected version.

    #7650

    nobuyuki
    Participant

    Hi!

    Yes, it seems that bit of code from the original was a bit janky.  At some point in the design of argyne, I ran into a problem where I couldn’t make interfaces generic (a limitation of Monkey at the time) and ended up having to rewrite a large portion of the system.  This bug may have been an artifact of sloppy refactoring.

    One of the reasons I abandoned argyne was because it creates a lot of object initializations and does nothing to track or pool particle resources, making the entire system very resource-intensive compared to the (as of yet still unreleased) system I wrote to replace it.  Thrash was inevitable as the GC would have to sweep these eventually and that would cause big hiccups on Android (and eventually in glfw too if the example was anything to go by).

    Thanks for updating argyne for mx2.  If I were to rewrite it myself, it would probably handle a few things differently!  The general way to set it up would probably stay similar, though…… and there’d also be a way to delay its startTime, and an easing curve option in ParticleValues.Set()…..

    #7655

    Diffrenzy
    Keymaster

    Hi nobuyuki, nice to hear from you on this.

    (You are of course very welcome to clone back the MX2 port, and make your clone the new base version, I’ll delete mine if you do. )

    I think MX2 could do with a good particle system, so I’m not done looking into whats out there, but for now, I’ll be using my animation system that has similarities with your particle system, in that it also tweens between positions, and such.

    If you do release that other system, give a heads up! .-)

    #7658

    nobuyuki
    Participant

    I’d rather you keep your version available for the time being, since I don’t plan to do an authoritative version for mx2 anytime soon.  I’m waiting for Jungle to get some mx2 support before diving into that, and still have a few incomplete projects that aren’t even using mojo2 so I’ll be stuck there for at least a while.

    The other system is very simple and actually written less with public use in mind, but I’ll think about it!  It follows a “god particle” baseclass pattern which I didn’t favor for argyne, and doesn’t have intrinsic support for frame-based timing or second-order spawning.  What it does have is Easing curve functions and an allocator.  Here’s a code snippet of the main class, it won’t work without the nscreen framework (unreleased) but it should be fairly simple to understand.

    You can see an example of it working here.  The example extends Particle with a subclass that puts it on a rail, using Particle.RotMulDest() to spin back towards its destination.  Since the system was made specifically for this game, it’s a lot less elegant (especially to extend or if you need frame timing) but also a lot more compact and “to the point”.  The allocator here is also sloppy and just kills particles regardless of how close they are to expiring, which argyne would’ve done instead as a property of the Particle interface (which would’ve fetched a resource based on time-to-live, iirc).

    I would like to release something eventually for monkey/mx2 that is a “best of both worlds” of both of these systems.  Perhaps if mx2-only, have particles accept functions which define their behavior and reduce the number of classes/interfaces…

    #7660

    Diffrenzy
    Keymaster

    Great stuff.

    accept functions which define their behavior
     

    Yes!, like you do above with Method New(curve:nsEasingCurve)

    In MX2, we should probably be using Structs as mush as possible for the base objects, but if they are recycled, maybe it wont matter.

    One difference from what I’m messing with, is that I read Millisecs in my main loop, and pass that to the animation system. That way I can stop and scale time, which I think is super important. Also, that way I’m sure that all objects have the same time. It does mean a lot of passing nowtime around, and I guess you could put it in a global, but passing it, means you can scale/stop time for some objects/systems, and not for others.

    [EDIT] Thinking about this, maybe TimeFunc() should just be replacable, where the default just gets TimeManager.DefaultTime (that in turn returns a mainloop updated Millisecs() ) That would mean no passing of nowtime + a simple way to pause/scale the system, with out sacrificing special timescales if needed

    #7668

    nobuyuki
    Participant

    [EDIT] Thinking about this, maybe TimeFunc() should just be replacable, where the default just gets TimeManager.DefaultTime (that in turn returns a mainloop updated Millisecs() ) That would mean no passing of nowtime + a simple way to pause/scale the system, with out sacrificing special timescales if needed

    Yes!  One upgrade I was thinking of making in my monkey 1 framework was to give every system which relied on time a field for a timeIndex reference.  One of the reasons I never got around to it was that it meant wrapping Millisecs() globally (to more easily support pausing) and probably keeping a seperate frame timer too, and as you said probably even going a step further if I needed support for time stretching/compression in my games.  In mx2 this can be a simple Func type and ppl who don’t need that complexity can just keep the default timeIndex of a pointer to Millisecs().

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

You must be logged in to reply to this topic.