]> git.localhorst.tv Git - l2e.git/commitdiff
initialize objects after loading
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 17 Mar 2013 17:09:08 +0000 (18:09 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 17 Mar 2013 17:10:15 +0000 (18:10 +0100)
this links the vtables and runs any custom loading function

src/graphics/Animation.cpp
src/graphics/Animation.h
src/graphics/ComplexAnimation.cpp
src/graphics/ComplexAnimation.h
src/graphics/SimpleAnimation.cpp
src/graphics/SimpleAnimation.h
src/loader/Loader.cpp
src/loader/Loader.h
src/loader/TypeDescription.cpp
src/loader/TypeDescription.h
src/loader/noinit.h [new file with mode: 0644]

index 602d7ef5d7613ada5118239b3ebf870e381633fc..bdd4b2905e75728c3d64523156203a714e4acff2 100644 (file)
@@ -14,6 +14,11 @@ using loader::TypeDescription;
 
 namespace graphics {
 
+Animation::Animation(loader::noinit_t) {
+
+}
+
+
 void Animation::CreateTypeDescription() {
        TypeDescription &td(TypeDescription::Create(TYPE_ID, "Animation"));
        td.SetDescription("Abstract base type for animations.");
index a224f548590c4af16edad31b32c1ab596881df3d..ddbf095f185e06d552cc38b4a0153a3c3db53aaa 100644 (file)
@@ -11,6 +11,7 @@ namespace loader {
 
 #include "../app/Timer.h"
 #include "../math/Vector.h"
+#include "../loader/noinit.h"
 
 #include <memory>
 #include <SDL.h>
@@ -30,6 +31,8 @@ public:
        Animation(const Sprite *sprite, int frameTime, bool repeat = false)
        : sprite(sprite), frameTime(frameTime), repeat(repeat) { }
        virtual ~Animation() { };
+protected:
+       Animation(loader::noinit_t);
 
 public:
        const Sprite *GetSprite() const { return sprite; }
index 95f58692ed67bae11a7cb2187e332c8336b18a57..942db777e0f72eeaec4e5b0e52777dc8db5a8fc6 100644 (file)
@@ -26,6 +26,11 @@ ComplexAnimation::ComplexAnimation(
 
 }
 
+ComplexAnimation::ComplexAnimation(loader::noinit_t n)
+: Animation(n) {
+
+}
+
 
 int ComplexAnimation::NumFrames() const {
        return numFrames;
@@ -51,6 +56,7 @@ void ComplexAnimation::CreateTypeDescription() {
        TypeDescription &td(TypeDescription::Create(TYPE_ID, "ComplexAnimation"));
        td.SetDescription("Complex animation type that supports per-frame disposition and non-linear sprite offset selection.");
        td.SetConstructor(&Construct);
+       td.SetInitializer(&Initialize);
        td.SetSize(sizeof(ComplexAnimation));
        td.AddSupertype(Animation::TYPE_ID, ((char *)a) - ((char *)&ca));
 
@@ -73,4 +79,8 @@ void ComplexAnimation::Construct(void *data) {
        new (data) ComplexAnimation;
 }
 
+void ComplexAnimation::Initialize(void *data) {
+       new (data) ComplexAnimation(loader::noinit);
+}
+
 }
index 92562c5469ebdb83850d9af9a3aa84d1e9801aaa..380ea2a066f831590f9e744d8215944ffdb239ef 100644 (file)
@@ -2,6 +2,7 @@
 #define GRAPHICS_COMPLEXANIMATION_H_
 
 #include "Animation.h"
+#include "../loader/noinit.h"
 
 namespace graphics {
 
@@ -14,6 +15,8 @@ public:
 public:
        ComplexAnimation();
        ComplexAnimation(const Sprite *sprite, int frameTime, bool repeat = false);
+protected:
+       ComplexAnimation(loader::noinit_t);
 
 public:
        struct FrameProp {
@@ -29,6 +32,7 @@ public:
 
        static void CreateTypeDescription();
        static void Construct(void *);
+       static void Initialize(void *);
 
 protected:
        virtual int NumFrames() const;
index 24985f91ebb12e5db89143389f29a29a71f2d4d8..75a327bd786c30a3809953cf39e37da8d0fe3906 100644 (file)
@@ -30,6 +30,11 @@ SimpleAnimation::SimpleAnimation(
 
 }
 
+SimpleAnimation::SimpleAnimation(loader::noinit_t n)
+: Animation(n) {
+
+}
+
 
 int SimpleAnimation::NumFrames() const {
        return numFrames;
@@ -51,6 +56,7 @@ void SimpleAnimation::CreateTypeDescription() {
        TypeDescription &td(TypeDescription::Create(TYPE_ID, "SimpleAnimation"));
        td.SetDescription("An animation that uses a fixed column and increasing row of a sprite based on the frame number.");
        td.SetConstructor(&Construct);
+       td.SetInitializer(&Initialize);
        td.SetSize(sizeof(SimpleAnimation));
        td.AddSupertype(Animation::TYPE_ID, ((char *)a) - ((char *)&sa));
 
@@ -64,4 +70,8 @@ void SimpleAnimation::Construct(void *data) {
        new (data) SimpleAnimation;
 }
 
+void SimpleAnimation::Initialize(void *data) {
+       new (data) SimpleAnimation(loader::noinit);
+}
+
 }
index 7e5a99a9a2630b6e4ba7eadf59e1a993349a6940..0864d2b024402f2509e01283558ded8f117615b3 100644 (file)
@@ -2,6 +2,7 @@
 #define GRAPHICS_SIMPLEANIMATION_H_
 
 #include "Animation.h"
+#include "../loader/noinit.h"
 
 namespace graphics {
 
@@ -15,6 +16,8 @@ public:
        SimpleAnimation();
        SimpleAnimation(const Sprite *sprite, int frameTime, int numFrames,
                        int col = 0, int row = 0, bool repeat = false);
+protected:
+       SimpleAnimation(loader::noinit_t);
 
 public:
        void SetNumFrames(int n) { numFrames = n; }
@@ -23,6 +26,7 @@ public:
 
        static void CreateTypeDescription();
        static void Construct(void *);
+       static void Initialize(void *);
 
 protected:
        virtual int NumFrames() const;
index dbfbe3186fdd93e8a508110c082753197778cc3c..961ec7cff6d315dec5537338fe08ba8cfc0b9450 100644 (file)
@@ -61,6 +61,13 @@ void Loader::Load(const std::string &filePath) {
                LoadImages(header->ident,
                                header->ImagesBegin(),
                                header->ImagesEnd());
+
+               InitObjects(
+                               header->ObjectsBegin(),
+                               header->ObjectsEnd());
+               InitArrays(
+                               header->ArraysBegin(),
+                               header->ArraysEnd());
        } catch (...) {
                delete[] block;
                throw;
@@ -159,4 +166,42 @@ void Loader::LoadArrays(char *src, Array *begin, Array *end) {
        }
 }
 
+
+void Loader::InitObjects(Object *begin, Object *end) {
+       for (Object *i = begin; i < end; i = i->Next()) {
+               const TypeDescription &td =
+                               TypeDescription::Get(i->typeId);
+               InitObject(i->RawObject(), td);
+       }
+}
+
+void Loader::InitObject(char *object, const TypeDescription &td) {
+       td.Init(object);
+       td.Load(object);
+       for (TypeDescription::FieldIterator
+                       i(td.FieldsBegin()), end(td.FieldsEnd());
+                       i != end; ++i) {
+               const FieldDescription &field = i->second;
+               if (field.IsReferenced() || field.IsAggregate()) {
+                       continue;
+               }
+               const TypeDescription &nestedType
+                               = TypeDescription::Get(field.TypeId());
+               InitObject(object + field.Offset(), nestedType);
+       }
+}
+
+void Loader::InitArrays(Array *begin, Array *end) {
+       for (Array *i = begin; i < end; i = i->Next()) {
+               if (i->ref) {
+                       continue;
+               }
+               const TypeDescription &td = TypeDescription::Get(i->typeId);
+               for (char *j = i->Data(), *end = i->Data() + i->size;
+                               j < end; j += td.Size()) {
+                       InitObject(j, td);
+               }
+       }
+}
+
 }
index 0839ecb3d3212a946c32303f35340fff803f6355..50876384d744b26e617cd8982a1ee282153b24c7 100644 (file)
@@ -29,6 +29,10 @@ private:
        void LoadObject(char *src, char *dest, const TypeDescription &);
        void LoadArrays(char *src, Array *begin, Array *end);
 
+       void InitObjects(Object *begin, Object *end);
+       void InitObject(char *object, const TypeDescription &);
+       void InitArrays(Array *begin, Array *end);
+
 private:
        std::map<std::string, char *> objectFiles;
        std::map<std::string, LoadedExport> exports;
index 19974fb52cced072a31509df6453cf84117f46d6..bd63d70137b5f0a27c2f6939a6bc14e11d05d692 100644 (file)
@@ -46,6 +46,12 @@ void TypeDescription::Construct(void *data) const {
        }
 }
 
+void TypeDescription::Init(void *data) const {
+       if (initializer) {
+               (*initializer)(data);
+       }
+}
+
 void TypeDescription::Load(void *data) const {
        if (loader) {
                (*loader)(data);
index 7b7483624bfe1577979e5ff849405ab25e2fc65b..078002fed916c2a96481be4b050c205edae60331 100644 (file)
@@ -40,9 +40,11 @@ public:
        bool HasField(const std::string &name) const;
        const FieldDescription &GetField(const std::string &name) const;
        void Construct(void *) const;
+       void Init(void *) const;
        void Load(void *) const;
 
        void SetConstructor(void (*ctor)(void *)) { constructor = ctor; }
+       void SetInitializer(void (*init)(void *)) { initializer = init; }
        void SetLoader(void (*ld)(void *)) { loader = ld; }
        void AddSupertype(int id, std::ptrdiff_t offset);
        bool IsSubtypeOf(int id) const;
@@ -72,10 +74,19 @@ public:
        static void WriteSourceWiki(std::ostream &);
 
 private:
-       TypeDescription(int id, const std::string &name) : constructor(0), loader(0), description(0), name(name), id(id), size(0) { }
+       TypeDescription(int id, const std::string &name)
+       : constructor(0)
+       , initializer(0)
+       , loader(0)
+       , description(0)
+       , name(name)
+       , id(id)
+       , size(0)
+       { }
 
 private:
        void (*constructor)(void *);
+       void (*initializer)(void *);
        void (*loader)(void *);
        const char *description;
        std::string name;
diff --git a/src/loader/noinit.h b/src/loader/noinit.h
new file mode 100644 (file)
index 0000000..fe9ce7e
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef LOADER_NOINIT_H_
+#define LOADER_NOINIT_H_
+
+namespace loader {
+
+enum noinit_t {
+       noinit,
+};
+
+}
+
+#endif