Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: loading set from file

  1. #1

    loading set from file

    I have lot's of different sets that group 'minerals' like that:

    Code:
    sMinerals = set of TBlockType;
    
    mineralsWalkable, mineralsNonBlocking, mineralsRare.. : sMinerals;
    then I have a game object with one of felds being 'sMinerals' and would like to be able to load it's properties from file.
    I know that it's possible to convert string to enum with typeinfo and load set elements that way but is it possible to load a 'set name' instead and convert it somehow?
    loading only elements would mean I have to update the file manually each time I add new element to set definition

  2. #2
    Junior Member Delphius's Avatar
    Join Date
    Jul 2013
    Location
    Salta, Argentina
    Posts
    9
    Hello,


    Not sure if I understood well.
    You have on one hand an enumerated type plus a set of this type. That is:

    Code:
    TBlockType = (mineralsWalkable, mineralsNonBlocking, mineralsRare, etc); 
    stMinerals = set of TBlockType;

    Even if we were to be more accurate with correct nomenclature guide would be this:

    Code:
    TBlockType = (btWalkable, btNonBlocking, etc); 
    TMinerals = set of TBlockType;

    And you're looking for a way to "automate" the saved and read from a file of this set. And also, you do not look limited to a fixed amount of items, but you can add more types of minerals and not have to alter the file.


    If I am right, then I think the technique you're using is not entirely correct.
    I think that if you are not fully aware of the amount, and cardinality of items that will TBlockType and / or if you expect this to be a "listed open" then not it is the right kind.
    I recommend you to think more in design a list to it so that you can add as many types of minerals as you want.
    Then:
    1. Design an abstract class called TBlockType
    2. Desing as many classes as types descend from this need.
    3. Design a class TMineralsList that is responsible for maintaining the list (set) of minerals.


    What remains to be implemented, and for reading and saving the file based on the listing. I can suggest you to do based on the Factory pattern.


    To keep the set in the file, you could do something like XML:
    <set>
    NameOfClass1;
    NameOfClass2;
    ...
    NameOfClassN;
    </set>


    Then to read the file just read the name of the classes and proceed with a "materialization" of this and create an instance.
    The other way around (save), we scan the list of objects (minerals), determine the name of the class and stored on disk.

    Regards,
    P.S: Sorry for my bad English.

  3. #3
    I didn't explained it well enough, sorry. It turns out it's not possible so I used a map
    http://stackoverflow.com/questions/1...ng-to-set-type

  4. #4
    I know that using strings for naming block types might look easier but in the end it only complicates things not to mention that operating with strings is ususally slower.
    So I advice you to use numbers for defining your block type. Why? Becouse with numbers you can quickly kinda divide all of your block types into sets.
    Take a look at next example of block definition:
    Code:
    //Pseudocode
    
    //Passable blocks: 0-100
    begin
      0 = air
      1 = water
      2 = background wall
      3 = doors
      ....
    end
    
    //Unpassable blocks 100-900
    begin
      //Destructable blocks
      begin
        //Ground 100-199
        begin
          100 = dirt
          101 = grass
          102 = stone
          ...
        end
        //Minerals 200-300
        begin
          200 = iron
          201 = coal
          202 = coper
          ...
        end
      //Undestructable blocks 900-1000
      begin
        901 = bedrock
      end
    end
    In the end you can also define numeric sets in form of btMinerals: 201..300. This alows you to change the block definition types at any time without the need to recompile your program and still use sets to quickly determine block type.
    Last edited by SilverWarior; 17-07-2013 at 06:06 AM.

  5. #5
    it's a byte not a string. I just let the compiler number them
    Code:
    type 
       {$PACKENUM 1} 
       eBlockTypes = (btNone,btUndefined,btStone, btYellowFlower, btWoodBrown);
    
    ...
    
    mineralsNonBlocking:=[btNone]+mineralsOxygen;
    Last edited by laggyluk; 17-07-2013 at 06:44 AM.

  6. #6
    Hm, can't you just typecast the set to an integer when saving, and then do it the other way when loading?

    Btw, doing a writeln(enum_type) will print the name of the identifier, as it appears in code. Have you checked if readln(enum_type) works?

  7. #7
    I can't apparently. isn't writeln/readln console program thing? anyways it says 'Error: Can't read or write variables of this type'

  8. #8
    Quote Originally Posted by laggyluk View Post
    it's a byte not a string. I just let the compiler number them
    Automatic numbering for such things isn't verry suitable as you can quickly change the numbering order by changing the set itself. This means that after you change the set your program will no longer be able to load older savegame.
    Using my aproach also has advantage of you being albe to leave some identifier numbers unused so you can use them in the future and therefore avoid changing existing ones when adding new ones.

    EDIT: As for sets their primarry use is to add predefined identifiers for some properties. And yes in memory set elements are saved just as Indexes of set elements. You can consider sets as bunch od Constants of same type grouped together.
    Last edited by SilverWarior; 17-07-2013 at 08:02 AM.

  9. #9
    Quote Originally Posted by SilverWarior View Post
    Automatic numbering for such things isn't verry suitable as you can quickly change the numbering order by changing the set itself. This means that after you change the set your program will no longer be able to load older savegame.
    Using my aproach also has advantage of you being albe to leave some identifier numbers unused so you can use them in the future and therefore avoid changing existing ones when adding new ones.
    I know what you mean but so far so good, I just add new elements to end of set

  10. #10
    Junior Member Delphius's Avatar
    Join Date
    Jul 2013
    Location
    Salta, Argentina
    Posts
    9
    Although there are other possible ways to address the problem If the intention is to add more elements to the enumerated type seems just a design flaw and is making use of the wrong type.
    If you have not yet defined the number of items and you'll be adding more and more, it is clear that go on your design is counterproductive.
    It is better to redirect this design to one based on classes as I mentioned in a previous post.
    You design The class TMineralList with methods to add and remove items in an internal list. And until it can be designed to do set operations such as union and intersection if you want.
    TMineralList assumes responsibility for store / read the file and materialization. If you insist to make the correspondence by string, you be can avail the name of the class. Something like this:

    Code:
    type
    TBlockTypeClass = class of TBlockType; //TBlockType is the abstract base class
    
    var
    BlockType: TBlockType;
    BlockTypeClass: TBlockTypeClass;
    ...
    
    Index := BlockLists.IndexOf(TheTextReadFromFile);
    BlockTypeClass := TBlockType(BlockLists.Object[Index]);
    BlockType := BlockTypeClass.Create;
    BlockLists is a TStringList.
    To "register" each subclass of TBlockType:

    Code:
    BlockLists.AddObject(ConcreteBlockType.ClassName, TObject(ConcreteBlockType));

    Naturally this design not is "the solution", because it involves add new classes, but when trying to be adding elements to an enumerated type in the first thing you should think about is a lack of design and/or are not using the right path.
    I say this with all respect.

    Regards,
    P.S: Soory for my bad English.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •