mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-02-20 12:31:14 +00:00
Add deep copy functions
Does allocation, a memcpy shallow copy, and a callback to handle memory addresses if desired. Might be reusable for runahead saves.
This commit is contained in:
parent
e3ccc4f0ea
commit
353af883aa
4 changed files with 365 additions and 12 deletions
|
|
@ -167,6 +167,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
|||
music.cpp
|
||||
music_manager.cpp
|
||||
sanitize.cpp
|
||||
p_deepcopy.cpp
|
||||
)
|
||||
|
||||
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
|
||||
|
|
|
|||
229
src/p_deepcopy.cpp
Normal file
229
src/p_deepcopy.cpp
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2024 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file p_deepcopy.cpp
|
||||
/// \brief Methods for deep copying
|
||||
|
||||
#include "p_deepcopy.h"
|
||||
|
||||
#include "typedef.h"
|
||||
#include "z_zone.h"
|
||||
#include "taglist.h"
|
||||
#include "r_defs.h"
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void P_DeepCopy(Type *target, Type *source, void (*callback)(Type *, Type *))
|
||||
|
||||
Make a deep copy of a struct, by using memcpy
|
||||
for an initial shallow copy, and a callback
|
||||
function to handle any memory addresses.
|
||||
|
||||
Input Arguments:-
|
||||
Type: The type of the structs.
|
||||
target: The struct to copy into.
|
||||
source: The struct to copy from.
|
||||
callback: A callback function, intended to replace
|
||||
pointers after the initial shallow copy.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
template <typename Type>
|
||||
static void P_DeepCopy(Type *target, Type *source, void (*callback)(Type *, Type *))
|
||||
{
|
||||
memcpy(target, source, sizeof(Type));
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
callback(target, source);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void P_DeepCopyArray(Type **target_array, Type **source_array, size_t source_len, void (*callback)(Type *, Type *))
|
||||
|
||||
Make a deep copy of an array of structs, by using
|
||||
memcpy for an initial shallow copy, and a callback
|
||||
function to handle any memory addresses for each
|
||||
individual struct.
|
||||
|
||||
Input Arguments:-
|
||||
Type: The type of the structs.
|
||||
target_array: The start of the array to copy into.
|
||||
This will be allocated by this function, so
|
||||
it should be freed beforehand.
|
||||
source_array: The start of the array to copy from.
|
||||
source_len: The length of the array to copy from.
|
||||
callback: A callback function, intended to replace
|
||||
pointers after the initial shallow copy.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
template <typename Type>
|
||||
static void P_DeepCopyArray(Type **target_array, Type **source_array, size_t source_len, void (*callback)(Type *, Type *))
|
||||
{
|
||||
const size_t source_total = source_len * sizeof(Type);
|
||||
|
||||
*target_array = static_cast<Type *>(Z_Calloc(source_total, PU_LEVEL, nullptr));
|
||||
memcpy(*target_array, *source_array, source_total);
|
||||
|
||||
if (callback != nullptr)
|
||||
{
|
||||
for (size_t i = 0; i < source_len; i++)
|
||||
{
|
||||
Type *target = &(*target_array)[i];
|
||||
Type *source = &(*source_array)[i];
|
||||
|
||||
callback(target, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void copy_taglist_tags(taglist_t *target, taglist_t *source)
|
||||
|
||||
Make a deep copy of taglist's tags fields.
|
||||
Used as a helper function for other callbacks,
|
||||
does not work as a full deep copy of taglist_t
|
||||
on its own.
|
||||
|
||||
Input Arguments:-
|
||||
target: The struct to copy into.
|
||||
source: The struct to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
static void copy_taglist_tags(taglist_t *target, taglist_t *source)
|
||||
{
|
||||
if (source->count)
|
||||
{
|
||||
target->tags = static_cast<mtag_t *>(
|
||||
memcpy(
|
||||
Z_Malloc(
|
||||
source->count * sizeof(mtag_t),
|
||||
PU_LEVEL,
|
||||
nullptr
|
||||
),
|
||||
source->tags,
|
||||
source->count * sizeof(mtag_t)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void copy_sector_callback(sector_t *target, sector_t *source)
|
||||
|
||||
Handles memory addresses after creating a shallow copy
|
||||
of a sector_t, to turn it into a deep copy.
|
||||
|
||||
Input Arguments:-
|
||||
target: The struct to copy into.
|
||||
source: The struct to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
static void copy_sector_callback(sector_t *target, sector_t *source)
|
||||
{
|
||||
// (Not a true deep copy until all of the memory addresses are accounted for.)
|
||||
copy_taglist_tags(&target->tags, &source->tags);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySector(sector_t *target, sector_t *source)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySector(sector_t *target, sector_t *source)
|
||||
{
|
||||
P_DeepCopy<sector_t>(target, source, copy_sector_callback);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySectors(sector_t **target_array, sector_t **source_array, size_t source_len)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySectors(sector_t **target_array, sector_t **source_array, size_t source_len)
|
||||
{
|
||||
P_DeepCopyArray<sector_t>(target_array, source_array, source_len, copy_sector_callback);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void copy_line_callback(line_t *target, line_t *source)
|
||||
|
||||
Handles memory addresses after creating a shallow copy
|
||||
of a line_t, to turn it into a deep copy.
|
||||
|
||||
Input Arguments:-
|
||||
target: The struct to copy into.
|
||||
source: The struct to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
static void copy_line_callback(line_t *target, line_t *source)
|
||||
{
|
||||
// (Not a true deep copy until all of the memory addresses are accounted for.)
|
||||
copy_taglist_tags(&target->tags, &source->tags);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopyLine(line_t *target, line_t *source)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopyLine(line_t *target, line_t *source)
|
||||
{
|
||||
P_DeepCopy<line_t>(target, source, copy_line_callback);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopyLines(line_t **target_array, line_t **source_array, size_t source_len)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopyLines(line_t **target_array, line_t **source_array, size_t source_len)
|
||||
{
|
||||
P_DeepCopyArray<line_t>(target_array, source_array, source_len, copy_line_callback);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySide(line_t *target, line_t *source)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySide(side_t *target, side_t *source)
|
||||
{
|
||||
P_DeepCopy<side_t>(target, source, nullptr); // (Not a true deep copy until all of the memory addresses are accounted for.)
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySides(side_t **target_array, side_t **source_array, size_t source_len)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySides(side_t **target_array, side_t **source_array, size_t source_len)
|
||||
{
|
||||
P_DeepCopyArray<side_t>(target_array, source_array, source_len, nullptr); // (Not a true deep copy until all of the memory addresses are accounted for.)
|
||||
}
|
||||
131
src/p_deepcopy.h
Normal file
131
src/p_deepcopy.h
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
// DR. ROBOTNIK'S RING RACERS
|
||||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
|
||||
// Copyright (C) 2024 by Kart Krew
|
||||
//
|
||||
// This program is free software distributed under the
|
||||
// terms of the GNU General Public License, version 2.
|
||||
// See the 'LICENSE' file for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file p_deepcopy.h
|
||||
/// \brief Methods for deep copying
|
||||
|
||||
#ifndef __P_DEEPCOPY__
|
||||
#define __P_DEEPCOPY__
|
||||
|
||||
#include "doomdef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySector(sector_t *target, sector_t *source);
|
||||
|
||||
Make a deep copy of a single sector_t.
|
||||
|
||||
Input Arguments:-
|
||||
target: The struct to copy into.
|
||||
source: The struct to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySector(sector_t *target, sector_t *source);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySectors(sector_t **target_array, sector_t **source_array, size_t source_len);
|
||||
|
||||
Make a deep copy of an array of sector_t.
|
||||
|
||||
Input Arguments:-
|
||||
target_array: The start of the array to copy into.
|
||||
This will be allocated by this function, so
|
||||
it should be freed beforehand.
|
||||
source_array: The start of the array to copy from.
|
||||
source_len: The length of the array to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySectors(sector_t **target_array, sector_t **source_array, size_t source_len);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopyLine(line_t *target, line_t *source)
|
||||
|
||||
Make a deep copy of a single line_t.
|
||||
|
||||
Input Arguments:-
|
||||
target: The struct to copy into.
|
||||
source: The struct to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopyLine(line_t *target, line_t *source);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopyLines(line_t **target_array, line_t **source_array, size_t source_len)
|
||||
|
||||
Make a deep copy of an array of line_t.
|
||||
|
||||
Input Arguments:-
|
||||
target_array: The start of the array to copy into.
|
||||
This will be allocated by this function, so
|
||||
it should be freed beforehand.
|
||||
source_array: The start of the array to copy from.
|
||||
source_len: The length of the array to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopyLines(line_t **target_array, line_t **source_array, size_t source_len);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySide(line_t *target, line_t *source)
|
||||
|
||||
Make a deep copy of a single side_t.
|
||||
|
||||
Input Arguments:-
|
||||
target: The struct to copy into.
|
||||
source: The struct to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySide(side_t *target, side_t *source);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void P_DeepCopySides(side_t **target_array, side_t **source_array, size_t source_len)
|
||||
|
||||
Make a deep copy of an array of side_t.
|
||||
|
||||
Input Arguments:-
|
||||
target_array: The start of the array to copy into.
|
||||
This will be allocated by this function, so
|
||||
it should be freed beforehand.
|
||||
source_array: The start of the array to copy from.
|
||||
source_len: The length of the array to copy from.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
|
||||
void P_DeepCopySides(side_t **target_array, side_t **source_array, size_t source_len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // __P_DEEPCOPY__
|
||||
|
|
@ -119,6 +119,7 @@
|
|||
#include "k_endcam.h"
|
||||
#include "k_credits.h"
|
||||
#include "k_objects.h"
|
||||
#include "p_deepcopy.h"
|
||||
|
||||
// Replay names have time
|
||||
#if !defined (UNDER_CE)
|
||||
|
|
@ -7535,7 +7536,6 @@ static boolean P_LoadMapFromFile(void)
|
|||
TracyCZone(__zone, true);
|
||||
|
||||
virtlump_t *textmap = vres_Find(curmapvirt, "TEXTMAP");
|
||||
size_t i;
|
||||
|
||||
udmf = textmap != NULL;
|
||||
udmf_version = 0;
|
||||
|
|
@ -7563,17 +7563,9 @@ static boolean P_LoadMapFromFile(void)
|
|||
P_WriteTextmap();
|
||||
|
||||
// Copy relevant map data for NetArchive purposes.
|
||||
spawnsectors = static_cast<sector_t*>(Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL));
|
||||
spawnlines = static_cast<line_t*>(Z_Calloc(numlines * sizeof(*lines), PU_LEVEL, NULL));
|
||||
spawnsides = static_cast<side_t*>(Z_Calloc(numsides * sizeof(*sides), PU_LEVEL, NULL));
|
||||
|
||||
memcpy(spawnsectors, sectors, numsectors * sizeof(*sectors));
|
||||
memcpy(spawnlines, lines, numlines * sizeof(*lines));
|
||||
memcpy(spawnsides, sides, numsides * sizeof(*sides));
|
||||
|
||||
for (i = 0; i < numsectors; i++)
|
||||
if (sectors[i].tags.count)
|
||||
spawnsectors[i].tags.tags = static_cast<mtag_t*>(memcpy(Z_Malloc(sectors[i].tags.count*sizeof(mtag_t), PU_LEVEL, NULL), sectors[i].tags.tags, sectors[i].tags.count*sizeof(mtag_t)));
|
||||
P_DeepCopySectors(&spawnsectors, §ors, numsectors);
|
||||
P_DeepCopyLines(&spawnlines, &lines, numlines);
|
||||
P_DeepCopySides(&spawnsides, &sides, numsides);
|
||||
|
||||
P_MakeMapMD5(curmapvirt, &mapmd5);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue