Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it worth it to abstract out this process?

I have the following memory layout:

typedef struct map_obj_s
{
    thing_t**       things;

    linedef_t**     linedefs;

    sidedef_t**     sidedefs;

    vertex_t**      vertices;

    segment_t**     segments;

    ssector_t**     subsectors;

    node_t*         node_tree;

    sector_t**      sectors;

    int32_t         lump_counts[ MAP_LUMP_COUNT ];
}
map_obj_t;

The problem is that I'm basically repeating the exact same processes for each of these data types, here, with the exception of the node_tree and lump_counts members.

Here's what the result is with the repetition:

map_obj_t* Map_Read( lumpbuffer_t* map_lump )
{
    int32_t lump_counts[ MAP_LUMP_COUNT ];

    __GetLumpCounts( map_lump, lump_counts );

    // laziness
    const lumpinfo_t* const mlumps = map_lump->lumps;

    FILE* mapfile   = Wad_GetFilePtr();

    map_obj_t* map  = Mem_Alloc( 1, sizeof( map_obj_t ) );

    // allocate buffers

    map->things     = Mem_Alloc( lump_counts[ LUMP_THINGS ],   sizeof( thing_t* ) );
    map->linedefs   = Mem_Alloc( lump_counts[ LUMP_LINEDEFS ], sizeof( linedef_t* ) );
    map->sidedefs   = Mem_Alloc( lump_counts[ LUMP_SIDEDEFS ], sizeof( sidedef_t* ) );
    map->vertices   = Mem_Alloc( lump_counts[ LUMP_VERTICES ], sizeof( vertex_t* ) );
    map->segments   = Mem_Alloc( lump_counts[ LUMP_SEGMENTS ], sizeof( segment_t* ) );
    map->subsectors = Mem_Alloc( lump_counts[ LUMP_SSECTORS ], sizeof( ssector_t* ) );
    map->node_tree  = Mem_Alloc( lump_counts[ LUMP_NODES ], sizeof( node_t ) );
    map->sectors    = Mem_Alloc( lump_counts[ LUMP_SECTORS ], sizeof( sector_t* ) );

    // parse things
    PARSE_LUMP( mapfile,
                map->things,
                sizeof( thing_t ),
                lump_counts[ LUMP_THINGS ],
                mlumps,
                LUMP_THINGS );

    // parse linedefs
    PARSE_LUMP( mapfile,
                map->linedefs,
                sizeof( linedef_t ),
                lump_counts[ LUMP_LINEDEFS ],
                mlumps,
                LUMP_LINEDEFS );


    // parse sidedefs
    PARSE_LUMP( mapfile,
                map->sidedefs,
                sizeof( sidedef_t ),
                lump_counts[ LUMP_SIDEDEFS ],
                mlumps,
                LUMP_SIDEDEFS );

    // parse vertices
    PARSE_LUMP( mapfile,
                map->vertices,
                sizeof( vertex_t ),
                lump_counts[ LUMP_VERTICES ],
                mlumps,
                LUMP_VERTICES );

    // parse segments
    PARSE_LUMP( mapfile,
                map->segments,
                sizeof( vertex_t ),
                lump_counts[ LUMP_SEGMENTS ],
                mlumps,
                LUMP_SEGMENTS );


    // parse subsectors
    PARSE_LUMP( mapfile,
                map->subsectors,
                sizeof( ssector_t ),
                lump_counts[ LUMP_SSECTORS ],
                mlumps,
                LUMP_SSECTORS );

    // parse nodes
    PARSE_LUMP( mapfile,
                map->node_tree,
                sizeof( node_t ),
                lump_counts[ LUMP_NODES ],
                mlumps,
                LUMP_NODES );


    // parse sectors
    PARSE_LUMP( mapfile,
                map->sectors,
                sizeof( sector_t ),
                lump_counts[ LUMP_SECTORS ],
                mlumps,
                LUMP_SECTORS );

    memcpy( map->lump_counts, lump_counts, sizeof( int32_t ) * MAP_LUMP_COUNT );

    return map;
}

And the PARSE_LUMP macro:

#define PARSE_LUMP( wad_fileptr, data, data_size, count, lumps_ptr, lump_type ) \
    do {                                                                        \
                                                                                \
        Mem_AllocBuffer( ( generic_buffer_t ) ( data ), ( data_size ), ( count ) ); \
                                                                                \
        fseek( ( wad_fileptr ),                                                 \
               ( lumps_ptr )[ ( lump_type ) ].address_offset,                   \
               SEEK_SET );                                                      \
                                                                                \
        for ( int32_t i = 0; i < count; ++i )                                   \
        {                                                                       \
            fread( ( data )[ i ], ( data_size ), 1, ( wad_fileptr ) );          \
        }                                                                       \
                                                                                \
    } while( 0 )                                                                \

The Point

Is it wrong of me to want to abstract this out? It's readable, sure, but the idea of it consists of a lot of code. I'm not an awesome C programmer (this is my first real/serious project with it), but I have experience with C++. On the C++ side this would be easy with templates, but in C I'm limited to void* and macro functions. Serialization seems like a possibility, but the issue with all of these seems to point to the fact that I have pointers-to-pointers for my buffers. Is there any sense of going about this, or am I just wasting my time even bothering with it? Not to mention the fact that I'm even sure of how to dynamically allocate memory from a serialized struct.

like image 839
zeboidlund Avatar asked Dec 14 '25 16:12

zeboidlund


1 Answers

What you have works I guess, but I think there's no reason to allocate and then read each set of lumps separatly, if you know the number of lumps and their sizes in advance then you could allocate all the memory you will need and read the whole file in one go and then you'd just set each pointer to the start (offset) of its respective set of lumps, something like this:

//first set of lumps
map->things = map_data;
//increment pointer
map_data += lump_counts[ LUMP_THINGS ] * sizeof( thing_t );

//second set of lumps
map->linedefs = map_data;
map_data += lump_counts[ LUMP_LINEDEFS ] * sizeof( linedefs_t );
...
like image 91
iabdalkader Avatar answered Dec 18 '25 06:12

iabdalkader



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!