File: recordptr.hpp

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (240 lines) | stat: -rw-r--r-- 8,110 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#ifndef OPENMW_COMPONENTS_NIF_RECORDPTR_HPP
#define OPENMW_COMPONENTS_NIF_RECORDPTR_HPP

#include <vector>

#include "niffile.hpp"
#include "nifstream.hpp"

namespace Nif
{

    /** A reference to another record. It is read as an index from the
        NIF, and later looked up in the index table to get an actual
        pointer.
    */
    template <class X>
    class RecordPtrT
    {
        union
        {
            intptr_t index;
            X* ptr;
        };

    public:
        RecordPtrT()
            : index(-2)
        {
        }

        RecordPtrT(X* ptr)
            : ptr(ptr)
        {
        }

        /// Read the index from the nif
        void read(NIFStream* nif)
        {
            // Can only read the index once
            assert(index == -2);

            // Store the index for later
            index = nif->get<int32_t>();
            assert(index >= -1);
        }

        /// Resolve index to pointer
        void post(Reader& nif)
        {
            if (index < 0)
                ptr = nullptr;
            else
            {
                Record* r = nif.getRecord(index);
                // And cast it
                ptr = dynamic_cast<X*>(r);
                assert(ptr != nullptr);
            }
        }

        /// Look up the actual object from the index
        const X* getPtr() const
        {
            assert(ptr != nullptr);
            return ptr;
        }
        X* getPtr()
        {
            assert(ptr != nullptr);
            return ptr;
        }

        const X& get() const { return *getPtr(); }
        X& get() { return *getPtr(); }

        /// Syntactic sugar
        const X* operator->() const { return getPtr(); }
        X* operator->() { return getPtr(); }

        /// Pointers are allowed to be empty
        bool empty() const { return ptr == nullptr; }
    };

    /** A list of references to other records. These are read as a list,
        and later converted to pointers as needed. Not an optimized
        implementation.
     */
    template <class X>
    using RecordListT = std::vector<RecordPtrT<X>>;

    template <class T>
    void readRecordList(NIFStream* nif, RecordListT<T>& list)
    {
        const std::uint32_t length = nif->get<std::uint32_t>();

        // No reasonable list can hit this generous limit
        if (length >= (1 << 24))
            throw std::runtime_error("Record list too long: " + std::to_string(length));

        list.resize(length);

        for (auto& value : list)
            value.read(nif);
    }

    template <class T>
    void postRecordList(Reader& nif, RecordListT<T>& list)
    {
        for (auto& value : list)
            value.post(nif);
    }

    struct NiAVObject;
    struct Extra;
    struct NiProperty;
    struct NiUVData;
    struct NiPosData;
    struct NiVisData;
    struct NiTimeController;
    struct NiObjectNET;
    struct NiSkinData;
    struct NiFloatData;
    struct NiMorphData;
    struct NiPixelData;
    struct NiColorData;
    struct NiKeyframeData;
    struct NiTriStripsData;
    struct NiSkinInstance;
    struct NiSourceTexture;
    struct NiPalette;
    struct NiParticleModifier;
    struct BSMasterParticleSystem;
    struct NiParticleSystem;
    struct NiPSysCollider;
    struct NiPSysColliderManager;
    struct NiPSysEmitterCtlrData;
    struct NiPSysModifier;
    struct NiPSysSpawnModifier;
    struct NiBoolData;
    struct NiBSplineData;
    struct NiBSplineBasisData;
    struct NiSkinPartition;
    struct BSShaderTextureSet;
    struct NiTriBasedGeom;
    struct NiGeometryData;
    struct BSShaderProperty;
    struct NiAlphaProperty;
    struct NiCollisionObject;
    struct bhkSystem;
    struct bhkWorldObject;
    struct bhkShape;
    struct bhkSerializable;
    struct bhkEntity;
    struct bhkConvexShape;
    struct bhkRigidBody;
    struct hkPackedNiTriStripsData;
    struct NiAccumulator;
    struct NiInterpolator;
    struct NiStringPalette;
    struct NiControllerManager;
    struct NiBlendInterpolator;
    struct NiDefaultAVObjectPalette;
    struct NiControllerSequence;
    struct bhkCompressedMeshShapeData;
    struct BSMultiBound;
    struct BSMultiBoundData;
    struct BSSkinBoneData;
    struct BSAnimNote;
    struct BSAnimNotes;

    using NiAVObjectPtr = RecordPtrT<NiAVObject>;
    using ExtraPtr = RecordPtrT<Extra>;
    using NiUVDataPtr = RecordPtrT<NiUVData>;
    using NiPosDataPtr = RecordPtrT<NiPosData>;
    using NiVisDataPtr = RecordPtrT<NiVisData>;
    using NiTimeControllerPtr = RecordPtrT<NiTimeController>;
    using NiObjectNETPtr = RecordPtrT<NiObjectNET>;
    using NiSkinDataPtr = RecordPtrT<NiSkinData>;
    using NiMorphDataPtr = RecordPtrT<NiMorphData>;
    using NiPixelDataPtr = RecordPtrT<NiPixelData>;
    using NiFloatDataPtr = RecordPtrT<NiFloatData>;
    using NiColorDataPtr = RecordPtrT<NiColorData>;
    using NiKeyframeDataPtr = RecordPtrT<NiKeyframeData>;
    using NiSkinInstancePtr = RecordPtrT<NiSkinInstance>;
    using NiSourceTexturePtr = RecordPtrT<NiSourceTexture>;
    using NiPalettePtr = RecordPtrT<NiPalette>;
    using NiParticleModifierPtr = RecordPtrT<NiParticleModifier>;
    using BSMasterParticleSystemPtr = RecordPtrT<BSMasterParticleSystem>;
    using NiParticleSystemPtr = RecordPtrT<NiParticleSystem>;
    using NiPSysColliderPtr = RecordPtrT<NiPSysCollider>;
    using NiPSysColliderManagerPtr = RecordPtrT<NiPSysColliderManager>;
    using NiPSysEmitterCtlrDataPtr = RecordPtrT<NiPSysEmitterCtlrData>;
    using NiPSysModifierPtr = RecordPtrT<NiPSysModifier>;
    using NiPSysSpawnModifierPtr = RecordPtrT<NiPSysSpawnModifier>;
    using NiBoolDataPtr = RecordPtrT<NiBoolData>;
    using NiBSplineDataPtr = RecordPtrT<NiBSplineData>;
    using NiBSplineBasisDataPtr = RecordPtrT<NiBSplineBasisData>;
    using NiSkinPartitionPtr = RecordPtrT<NiSkinPartition>;
    using BSShaderTextureSetPtr = RecordPtrT<BSShaderTextureSet>;
    using NiTriBasedGeomPtr = RecordPtrT<NiTriBasedGeom>;
    using NiGeometryDataPtr = RecordPtrT<NiGeometryData>;
    using BSShaderPropertyPtr = RecordPtrT<BSShaderProperty>;
    using NiAlphaPropertyPtr = RecordPtrT<NiAlphaProperty>;
    using NiCollisionObjectPtr = RecordPtrT<NiCollisionObject>;
    using bhkSystemPtr = RecordPtrT<bhkSystem>;
    using bhkWorldObjectPtr = RecordPtrT<bhkWorldObject>;
    using bhkShapePtr = RecordPtrT<bhkShape>;
    using bhkEntityPtr = RecordPtrT<bhkEntity>;
    using bhkConvexShapePtr = RecordPtrT<bhkConvexShape>;
    using bhkRigidBodyPtr = RecordPtrT<bhkRigidBody>;
    using hkPackedNiTriStripsDataPtr = RecordPtrT<hkPackedNiTriStripsData>;
    using NiAccumulatorPtr = RecordPtrT<NiAccumulator>;
    using NiInterpolatorPtr = RecordPtrT<NiInterpolator>;
    using NiStringPalettePtr = RecordPtrT<NiStringPalette>;
    using NiControllerManagerPtr = RecordPtrT<NiControllerManager>;
    using NiBlendInterpolatorPtr = RecordPtrT<NiBlendInterpolator>;
    using NiDefaultAVObjectPalettePtr = RecordPtrT<NiDefaultAVObjectPalette>;
    using bhkCompressedMeshShapeDataPtr = RecordPtrT<bhkCompressedMeshShapeData>;
    using BSMultiBoundPtr = RecordPtrT<BSMultiBound>;
    using BSMultiBoundDataPtr = RecordPtrT<BSMultiBoundData>;
    using BSSkinBoneDataPtr = RecordPtrT<BSSkinBoneData>;

    using NiAVObjectList = RecordListT<NiAVObject>;
    using NiPropertyList = RecordListT<NiProperty>;
    using ExtraList = RecordListT<Extra>;
    using NiSourceTextureList = RecordListT<NiSourceTexture>;
    using NiInterpolatorList = RecordListT<NiInterpolator>;
    using NiTriStripsDataList = RecordListT<NiTriStripsData>;
    using bhkShapeList = RecordListT<bhkShape>;
    using bhkSerializableList = RecordListT<bhkSerializable>;
    using bhkEntityList = RecordListT<bhkEntity>;
    using bhkRigidBodyList = RecordListT<bhkEntity>;
    using NiControllerSequenceList = RecordListT<NiControllerSequence>;
    using NiPSysModifierList = RecordListT<NiPSysModifier>;
    using NiTriBasedGeomList = RecordListT<NiTriBasedGeom>;
    using BSAnimNoteList = RecordListT<BSAnimNote>;
    using BSAnimNotesList = RecordListT<BSAnimNotes>;

} // Namespace
#endif