namespace graphics {
+Animation::Animation(loader::noinit_t) {
+
+}
+
+
void Animation::CreateTypeDescription() {
TypeDescription &td(TypeDescription::Create(TYPE_ID, "Animation"));
td.SetDescription("Abstract base type for animations.");
#include "../app/Timer.h"
#include "../math/Vector.h"
+#include "../loader/noinit.h"
#include <memory>
#include <SDL.h>
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; }
}
+ComplexAnimation::ComplexAnimation(loader::noinit_t n)
+: Animation(n) {
+
+}
+
int ComplexAnimation::NumFrames() const {
return numFrames;
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));
new (data) ComplexAnimation;
}
+void ComplexAnimation::Initialize(void *data) {
+ new (data) ComplexAnimation(loader::noinit);
+}
+
}
#define GRAPHICS_COMPLEXANIMATION_H_
#include "Animation.h"
+#include "../loader/noinit.h"
namespace graphics {
public:
ComplexAnimation();
ComplexAnimation(const Sprite *sprite, int frameTime, bool repeat = false);
+protected:
+ ComplexAnimation(loader::noinit_t);
public:
struct FrameProp {
static void CreateTypeDescription();
static void Construct(void *);
+ static void Initialize(void *);
protected:
virtual int NumFrames() const;
}
+SimpleAnimation::SimpleAnimation(loader::noinit_t n)
+: Animation(n) {
+
+}
+
int SimpleAnimation::NumFrames() const {
return numFrames;
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));
new (data) SimpleAnimation;
}
+void SimpleAnimation::Initialize(void *data) {
+ new (data) SimpleAnimation(loader::noinit);
+}
+
}
#define GRAPHICS_SIMPLEANIMATION_H_
#include "Animation.h"
+#include "../loader/noinit.h"
namespace graphics {
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; }
static void CreateTypeDescription();
static void Construct(void *);
+ static void Initialize(void *);
protected:
virtual int NumFrames() const;
LoadImages(header->ident,
header->ImagesBegin(),
header->ImagesEnd());
+
+ InitObjects(
+ header->ObjectsBegin(),
+ header->ObjectsEnd());
+ InitArrays(
+ header->ArraysBegin(),
+ header->ArraysEnd());
} catch (...) {
delete[] block;
throw;
}
}
+
+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);
+ }
+ }
+}
+
}
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;
}
}
+void TypeDescription::Init(void *data) const {
+ if (initializer) {
+ (*initializer)(data);
+ }
+}
+
void TypeDescription::Load(void *data) const {
if (loader) {
(*loader)(data);
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;
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;
--- /dev/null
+#ifndef LOADER_NOINIT_H_
+#define LOADER_NOINIT_H_
+
+namespace loader {
+
+enum noinit_t {
+ noinit,
+};
+
+}
+
+#endif