mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-12-04 01:41:42 +00:00
- allow hooking custom serializers into PPointer so that serializable types can be handled without having to create new type classes which would be a bit unwieldy thanks to how the type system works.
This commit is contained in:
parent
c630b07011
commit
fd20e1d78f
3 changed files with 97 additions and 4 deletions
|
@ -1396,6 +1396,10 @@ void PPointer::WriteValue(FSerializer &ar, const char *key,const void *addr) con
|
||||||
ar(key, *(DObject **)addr);
|
ar(key, *(DObject **)addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (writer != nullptr)
|
||||||
|
{
|
||||||
|
writer(ar, key, addr);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
I_Error("Attempt to save pointer to unhandled type %s", PointedType->DescriptiveName());
|
I_Error("Attempt to save pointer to unhandled type %s", PointedType->DescriptiveName());
|
||||||
|
@ -1425,6 +1429,10 @@ bool PPointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
else if (reader != nullptr)
|
||||||
|
{
|
||||||
|
return reader(ar, key, addr);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -362,13 +362,26 @@ public:
|
||||||
class PPointer : public PBasicType
|
class PPointer : public PBasicType
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(PPointer, PBasicType);
|
DECLARE_CLASS(PPointer, PBasicType);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef void(*WriteHandler)(FSerializer &ar, const char *key, const void *addr);
|
||||||
|
typedef bool(*ReadHandler)(FSerializer &ar, const char *key, void *addr);
|
||||||
|
|
||||||
PPointer();
|
PPointer();
|
||||||
PPointer(PType *pointsat, bool isconst = false);
|
PPointer(PType *pointsat, bool isconst = false);
|
||||||
|
|
||||||
PType *PointedType;
|
PType *PointedType;
|
||||||
bool IsConst;
|
bool IsConst;
|
||||||
|
|
||||||
|
WriteHandler writer = nullptr;
|
||||||
|
ReadHandler reader = nullptr;
|
||||||
|
|
||||||
|
void InstallHandlers(WriteHandler w, ReadHandler r)
|
||||||
|
{
|
||||||
|
writer = w;
|
||||||
|
reader = r;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||||
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
|
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
#include "teaminfo.h"
|
#include "teaminfo.h"
|
||||||
#include "r_data/sprites.h"
|
#include "r_data/sprites.h"
|
||||||
|
#include "serializer.h"
|
||||||
|
|
||||||
static TArray<FPropertyInfo*> properties;
|
static TArray<FPropertyInfo*> properties;
|
||||||
static TArray<AFuncDesc> AFTable;
|
static TArray<AFuncDesc> AFTable;
|
||||||
|
@ -741,7 +742,7 @@ static int fieldcmp(const void * a, const void * b)
|
||||||
void InitThingdef()
|
void InitThingdef()
|
||||||
{
|
{
|
||||||
// Create all global variables here because this cannot be done on the script side and really isn't worth adding support for.
|
// Create all global variables here because this cannot be done on the script side and really isn't worth adding support for.
|
||||||
// Also create all special fields here that cannot be declared by script syntax.
|
// Also create all special fields here that cannot be declared by script syntax plus the pointer serializers. Doing all these with class overrides would be a bit messy.
|
||||||
|
|
||||||
auto secplanestruct = NewNativeStruct("Secplane", nullptr);
|
auto secplanestruct = NewNativeStruct("Secplane", nullptr);
|
||||||
secplanestruct->Size = sizeof(secplane_t);
|
secplanestruct->Size = sizeof(secplane_t);
|
||||||
|
@ -750,18 +751,62 @@ void InitThingdef()
|
||||||
auto sectorstruct = NewNativeStruct("Sector", nullptr);
|
auto sectorstruct = NewNativeStruct("Sector", nullptr);
|
||||||
sectorstruct->Size = sizeof(sector_t);
|
sectorstruct->Size = sizeof(sector_t);
|
||||||
sectorstruct->Align = alignof(sector_t);
|
sectorstruct->Align = alignof(sector_t);
|
||||||
|
NewPointer(sectorstruct, false)->InstallHandlers(
|
||||||
|
[](FSerializer &ar, const char *key, const void *addr)
|
||||||
|
{
|
||||||
|
ar(key, *(sector_t **)addr);
|
||||||
|
},
|
||||||
|
[](FSerializer &ar, const char *key, void *addr)
|
||||||
|
{
|
||||||
|
Serialize<sector_t>(ar, key, *(sector_t **)addr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
auto linestruct = NewNativeStruct("Line", nullptr);
|
auto linestruct = NewNativeStruct("Line", nullptr);
|
||||||
linestruct->Size = sizeof(line_t);
|
linestruct->Size = sizeof(line_t);
|
||||||
linestruct->Align = alignof(line_t);
|
linestruct->Align = alignof(line_t);
|
||||||
|
NewPointer(linestruct, false)->InstallHandlers(
|
||||||
|
[](FSerializer &ar, const char *key, const void *addr)
|
||||||
|
{
|
||||||
|
ar(key, *(line_t **)addr);
|
||||||
|
},
|
||||||
|
[](FSerializer &ar, const char *key, void *addr)
|
||||||
|
{
|
||||||
|
Serialize<line_t>(ar, key, *(line_t **)addr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
auto sidestruct = NewNativeStruct("Side", nullptr);
|
auto sidestruct = NewNativeStruct("Side", nullptr);
|
||||||
sidestruct->Size = sizeof(side_t);
|
sidestruct->Size = sizeof(side_t);
|
||||||
sidestruct->Align = alignof(side_t);
|
sidestruct->Align = alignof(side_t);
|
||||||
|
NewPointer(sidestruct, false)->InstallHandlers(
|
||||||
|
[](FSerializer &ar, const char *key, const void *addr)
|
||||||
|
{
|
||||||
|
ar(key, *(side_t **)addr);
|
||||||
|
},
|
||||||
|
[](FSerializer &ar, const char *key, void *addr)
|
||||||
|
{
|
||||||
|
Serialize<side_t>(ar, key, *(side_t **)addr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
auto vertstruct = NewNativeStruct("Vertex", nullptr);
|
auto vertstruct = NewNativeStruct("Vertex", nullptr);
|
||||||
vertstruct->Size = sizeof(vertex_t);
|
vertstruct->Size = sizeof(vertex_t);
|
||||||
vertstruct->Align = alignof(vertex_t);
|
vertstruct->Align = alignof(vertex_t);
|
||||||
|
NewPointer(vertstruct, false)->InstallHandlers(
|
||||||
|
[](FSerializer &ar, const char *key, const void *addr)
|
||||||
|
{
|
||||||
|
ar(key, *(vertex_t **)addr);
|
||||||
|
},
|
||||||
|
[](FSerializer &ar, const char *key, void *addr)
|
||||||
|
{
|
||||||
|
Serialize<vertex_t>(ar, key, *(vertex_t **)addr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
auto sectorportalstruct = NewNativeStruct("SectorPortal", nullptr);
|
auto sectorportalstruct = NewNativeStruct("SectorPortal", nullptr);
|
||||||
sectorportalstruct->Size = sizeof(FSectorPortal);
|
sectorportalstruct->Size = sizeof(FSectorPortal);
|
||||||
|
@ -779,6 +824,36 @@ void InitThingdef()
|
||||||
teamstruct->Size = sizeof(FTeam);
|
teamstruct->Size = sizeof(FTeam);
|
||||||
teamstruct->Align = alignof(FTeam);
|
teamstruct->Align = alignof(FTeam);
|
||||||
|
|
||||||
|
PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr);
|
||||||
|
pstruct->Size = sizeof(player_t);
|
||||||
|
pstruct->Align = alignof(player_t);
|
||||||
|
NewPointer(pstruct, false)->InstallHandlers(
|
||||||
|
[](FSerializer &ar, const char *key, const void *addr)
|
||||||
|
{
|
||||||
|
ar(key, *(player_t **)addr);
|
||||||
|
},
|
||||||
|
[](FSerializer &ar, const char *key, void *addr)
|
||||||
|
{
|
||||||
|
Serialize<player_t>(ar, key, *(player_t **)addr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
auto fontstruct = NewNativeStruct("FFont", nullptr);
|
||||||
|
fontstruct->Size = sizeof(FFont);
|
||||||
|
fontstruct->Align = alignof(FFont);
|
||||||
|
NewPointer(fontstruct, false)->InstallHandlers(
|
||||||
|
[](FSerializer &ar, const char *key, const void *addr)
|
||||||
|
{
|
||||||
|
ar(key, *(FFont **)addr);
|
||||||
|
},
|
||||||
|
[](FSerializer &ar, const char *key, void *addr)
|
||||||
|
{
|
||||||
|
Serialize<FFont>(ar, key, *(FFont **)addr, nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// set up the lines array in the sector struct. This is a bit messy because the type system is not prepared to handle a pointer to an array of pointers to a native struct even remotely well...
|
// set up the lines array in the sector struct. This is a bit messy because the type system is not prepared to handle a pointer to an array of pointers to a native struct even remotely well...
|
||||||
// As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up.
|
// As a result, the size has to be set to something large and arbritrary because it can change between maps. This will need some serious improvement when things get cleaned up.
|
||||||
sectorstruct->AddNativeField("lines", NewPointer(NewResizableArray(NewPointer(linestruct, false)), false), myoffsetof(sector_t, Lines), VARF_Native);
|
sectorstruct->AddNativeField("lines", NewPointer(NewResizableArray(NewPointer(linestruct, false)), false), myoffsetof(sector_t, Lines), VARF_Native);
|
||||||
|
@ -843,9 +918,6 @@ void InitThingdef()
|
||||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(gi);
|
Namespaces.GlobalNamespace->Symbols.AddSymbol(gi);
|
||||||
|
|
||||||
// set up a variable for the global players array.
|
// set up a variable for the global players array.
|
||||||
PStruct *pstruct = NewNativeStruct("PlayerInfo", nullptr);
|
|
||||||
pstruct->Size = sizeof(player_t);
|
|
||||||
pstruct->Align = alignof(player_t);
|
|
||||||
PArray *parray = NewArray(pstruct, MAXPLAYERS);
|
PArray *parray = NewArray(pstruct, MAXPLAYERS);
|
||||||
PField *fieldptr = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players);
|
PField *fieldptr = new PField("players", parray, VARF_Native | VARF_Static, (intptr_t)&players);
|
||||||
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr);
|
||||||
|
|
Loading…
Reference in a new issue