Dynamic particle property using pointers

  • Mdkar
    26th Mar 2020 Member 1 Permalink

    This title is confusing, but idk what else to call it.

     

    I am trying to implement ions and ionic compounds in a mod.

    Right now I have an ion implemented as a struct:

    struct ion {
    int type;
    int number;
    int charge;
    };

    Each particle stores 2 of these structs (one anion, one cation).

    However, this means that each particle (e.g. water) can only store one ionic compound. In reality, each type of ion has negligible effect on the solubility of another. So, I want to be able to store a seemingly unlimited number of ions in each particle. 

     

    What is the best way going about this?

    The way memory is handled currently makes it seem like directly storing a vector of ions is not possible because there would be no definite 'offset' due to the amount of memory needed not being constant.

    Making a large array would make no sense because it is not infinite and would be a waste of memory for each particle.

     

    The only way I can think of is making the actual data stored in the particle a pointer to a vector of ion structs. 

    I am still a noob concerning pointers, but how would I implement this? Where/when/how would I allocate and free the memory for the vector of structs?

    Edited 3 times by Mdkar. Last: 26th Mar 2020
  • INFINITY-BOI
    26th Mar 2020 Banned 0 Permalink
    This post is hidden because the user is banned
  • LBPHacker
    26th Mar 2020 Developer 1 Permalink
    If your only concern is the implementation, you can actually just have an std::vector in struct Particle (it's a C++ thing that an std::vector's size may at most depend on its template arguments, but in practice not even its value type will influence its size; much less its length at run-time). The vector would happily store its values in some random corner of memory, not in struct Particle. One problem with this is that getting that vector to construct and destruct can be non-trivial (read: extremely painful).

    I'm not at all saying that this is a good idea though, only that it's one way to do what you want. I would probably try to put a sane limit on the number of ions a particle of solvent can handle and try to cram them into only a few ints at most in struct Particle. You probably don't need those ints, especially for charge that rarely goes above 8 and below -8 (4 bits would probably suffice). See where I'm going with this?
    Edited 2 times by LBPHacker. Last: 26th Mar 2020
  • Mdkar
    26th Mar 2020 Member 0 Permalink

    @LBPHacker (View Post)

     so in the properties vector I should add

    { "ions", StructProperty::Vector, offsetof(Particle, ions) }

    and add definitions for Vector in StructProperty and PropertyTool.

     

    How/why do I store 4 bit numbers in the vector? I used ints because they seem hassle free, and initialize to 0.

     

    If I did something like this would it work?

    std::vector<ion> ions; //is in Particle

     

    //in element code

    ion ionP;

    ionP.type = PT_NA; //NA is sodium element

    ionP.number = 1;

    ionP.charge = 1;

    parts[i].ions.push_back(ionP);

     

    would ions[0].type == PT_NA?

     

    I have a feeling it is much more complicated than this. 

    Edited 3 times by Mdkar. Last: 26th Mar 2020
  • LBPHacker
    26th Mar 2020 Developer 1 Permalink
    What I suggested was abandoning the potentially infinite vector idea for a simpler but finite self-rolled vector-like construction implemented as a bunch of int properties. The two approaches are incompatible.

    Like I said, simply putting an std::vector in struct Particle wouldn't work out of the box because struct Particle is assumed to be a POD and no construction or destruction is done on it, which std::vectors need. And if we're already there, as for ints initialising to 0, that's not true.

    Also, I completely forgot about the StructProperty vector >_> yeah you'd have better chances of getting the PropertyTool working with my approach.
  • Mdkar
    26th Mar 2020 Member 0 Permalink

    @LBPHacker (View Post)

     ok, what about using a std::vector<ion>* in Particle? 

     

    this appears to be working somewhat, but idk

    Is there anything wrong with it?

    Edited once by Mdkar. Last: 26th Mar 2020
  • LBPHacker
    26th Mar 2020 Developer 0 Permalink
    It depends. Where does it point?
  • Mdkar
    26th Mar 2020 Member 0 Permalink

    @LBPHacker (View Post)

     I'm assuming it initializes to NULL and I can then create a new vector<ion>

    if(parts[i].ions == NULL)

    parts[i].ions = new vector<ion>();

    each time a solvent gets something dissolved in it, and push to it to add more ions.

     

    When would I need to delete/free?

  • Lord_Bowserinator
    26th Mar 2020 Member 2 Permalink

    You would delete the vector when a particle is killed (Simulation.kill_part) or the simulation is cleared (simulation.Clear I think). You would also need to add the ions to Snapshot.h / .cpp and wherever in Simulation.cpp it saves snapshots, otherwise undo / redo won't work properly as you aren't saving the dissolved ions in the undo / redo state.

  • Mdkar
    26th Mar 2020 Member 1 Permalink

    @Lord_Bowserinator (View Post)

    @LBPHacker (View Post)

     Thanks, learned a lot about c++ pointers and vectors!