Skip to content

Commit

Permalink
Refactor|libdoomsday: Added DEDRegister and used it for DED flags
Browse files Browse the repository at this point in the history
DEDRegister maintains a Doomsday Script namespace that stores and
indexes definitions. DED flags are now stored in Defs.flags.
  • Loading branch information
skyjake committed May 18, 2014
1 parent c74160d commit 4aa1bd6
Show file tree
Hide file tree
Showing 6 changed files with 443 additions and 22 deletions.
20 changes: 13 additions & 7 deletions doomsday/libdoomsday/include/doomsday/defs/ded.h
Expand Up @@ -23,9 +23,11 @@
#include <vector>
#include <de/libcore.h>
#include <de/Vector>
#include <de/Record>
#include "../uri.h"

#include "dedtypes.h"
#include "dedregister.h"

// Version 6 does not require semicolons.
#define DED_VERSION 6
Expand All @@ -41,14 +43,17 @@
*/
struct LIBDOOMSDAY_PUBLIC ded_s
{
int version; // DED version number.
de::Record names; ///< Namespace where definition values are stored.

ded_flags_t modelFlags; // Default values for models.
float modelScale;
float modelOffset;
int version; // DED version number.

ded_flags_t modelFlags; // Default values for models.
float modelScale;
float modelOffset;

// Flag values (for all types of data).
DEDArray<ded_flag_t> flags;
//DEDArray<ded_flag_t> flags;
DEDRegister flags;

// Map object information.
DEDArray<ded_mobj_t> mobjs;
Expand Down Expand Up @@ -125,7 +130,9 @@ struct LIBDOOMSDAY_PUBLIC ded_s

void clear();

ded_flag_t *getFlag(char const *flag) const;
int addFlag(char const *id, int value);

//ded_flag_t *getFlag(char const *flag) const;

int evalFlags2(char const *ptr) const;

Expand Down Expand Up @@ -185,7 +192,6 @@ extern "C" {

// Routines for managing DED files:

int DED_AddFlag(ded_t* ded, char const* name, int value);
int DED_AddMobj(ded_t* ded, char const* idStr);
int DED_AddState(ded_t* ded, char const* id);
int DED_AddSprite(ded_t* ded, char const* name);
Expand Down
99 changes: 99 additions & 0 deletions doomsday/libdoomsday/include/doomsday/defs/dedregister.h
@@ -0,0 +1,99 @@
/** @file dedregister.h Register of definitions.
*
* @authors Copyright (c) 2014 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef LIBDOOMSDAY_DEDREGISTER_H
#define LIBDOOMSDAY_DEDREGISTER_H

#include "../libdoomsday.h"
#include <de/Record>

/**
* General purpose register of DED definitions.
*
* The important characteristics of definitions are:
* - preserving the order in which the definitions were parsed
* - definitions are looked up by ID, name, and/or other members in addition to the
* ordinal number
*
* DEDRegister is not specific to any one kind of definition, but instead maintains an
* array of definitions and a set of lookup dictionaries referencing subrecords in the
* ordered array.
*
* This implementation assumes that definitions are only added, not removed (unless
* all of them are removed at once).
*/
class LIBDOOMSDAY_PUBLIC DEDRegister
{
public:
/// The specified index or key value was not found from the register. @ingroup errors
DENG2_ERROR(NotFoundError);

/// Attempted to use a key for looking up that hasn't been previously registered.
/// @ingroup errors
DENG2_ERROR(UndefinedKeyError);

enum LookupFlag
{
CaseSensitive = 0x1, ///< Looking up is done case sensitively.
OnlyFirst = 0x2, ///< Only the first defined value is stored (otherwise last).

DefaultLookup = 0
};
Q_DECLARE_FLAGS(LookupFlags, LookupFlag)

public:
DEDRegister(de::Record &names);

/**
* Adds a member variable that is needed for looking up definitions. Once added,
* the key can be used in has(), tryFind() and find().
*
* @param keyName Name of the key variable.
* @param flags Indexing behavior for the lookup.
*/
void addLookupKey(de::String const &variableName, LookupFlags const &flags = DefaultLookup);

/**
* Clears the existing definitions. The existing lookup keys are not removed.
*/
void clear();

/**
* Adds a new definition as the last one.
*
* @return Reference to the added definition. Same as operator[](size()-1).
*/
de::Record &append();

int size() const;
bool has(de::String const &key, de::String const &value) const;

de::Record & operator [] (int index);
de::Record const & operator [] (int index) const;

de::Record * tryFind(de::String const &key, de::String const &value);
de::Record const * tryFind(de::String const &key, de::String const &value) const;

de::Record & find(de::String const &key, de::String const &value);
de::Record const & find(de::String const &key, de::String const &value) const;

private:
DENG2_PRIVATE(d)
};

#endif // LIBDOOMSDAY_DEDREGISTER_H
2 changes: 2 additions & 0 deletions doomsday/libdoomsday/libdoomsday.pro
Expand Up @@ -68,6 +68,7 @@ HEADERS += \
include/doomsday/defs/dedarray.h \
include/doomsday/defs/dedfile.h \
include/doomsday/defs/dedparser.h \
include/doomsday/defs/dedregister.h \
include/doomsday/defs/dedtypes.h \
include/doomsday/dualstring.h \
include/doomsday/filesys/file.h \
Expand Down Expand Up @@ -102,6 +103,7 @@ SOURCES += \
src/defs/ded.cpp \
src/defs/dedfile.cpp \
src/defs/dedparser.cpp \
src/defs/dedregister.cpp \
src/dualstring.cpp \
src/filesys/file.cpp \
src/filesys/filehandle.cpp \
Expand Down
26 changes: 15 additions & 11 deletions doomsday/libdoomsday/src/defs/ded.cpp
Expand Up @@ -42,7 +42,10 @@ float ded_ptcstage_t::particleRadius(int ptcIDX) const
}

ded_s::ded_s()
: flags(names.addRecord("flags"))
{
flags.addLookupKey("id");

clear();
}

Expand All @@ -56,6 +59,14 @@ void ded_s::clear()
modelOffset = 0;
}

int ded_s::addFlag(char const *id, int value)
{
Record &def = flags.append();
def.addText("id", id);
def.addNumber("value", value);
return def.geti("__order__");
}

void ded_s::release()
{
flags.clear();
Expand Down Expand Up @@ -104,14 +115,6 @@ int DED_AddMobj(ded_t* ded, char const* idstr)
return ded->mobjs.indexOf(mo);
}

int DED_AddFlag(ded_t* ded, char const* name, int value)
{
ded_flag_t *fl = ded->flags.append();
strcpy(fl->id, name);
fl->value = value;
return ded->flags.indexOf(fl);
}

int DED_AddModel(ded_t* ded, char const* spr)
{
ded->models.push_back(ded_model_t(spr));
Expand Down Expand Up @@ -469,6 +472,7 @@ int ded_s::getStateNum(char const *id) const
return idx;
}

/*
ded_flag_t *ded_s::getFlag(char const *flag) const
{
if(!flag || !flag[0]) return 0;
Expand All @@ -480,7 +484,7 @@ ded_flag_t *ded_s::getFlag(char const *flag) const
}
return 0;
}
}*/

int ded_s::evalFlags2(char const *ptr) const
{
Expand All @@ -496,9 +500,9 @@ int ded_s::evalFlags2(char const *ptr) const
String flagName(ptr, flagNameLength);
ptr += flagNameLength;

if(ded_flag_t *flag = getFlag(flagName.toUtf8().constData()))
if(Record const *flag = flags.tryFind("id", flagName.toLower()))
{
value |= flag->value;
value |= flag->geti("value");
}
else
{
Expand Down
14 changes: 10 additions & 4 deletions doomsday/libdoomsday/src/defs/dedparser.cpp
Expand Up @@ -821,19 +821,25 @@ DENG2_PIMPL(DEDParser)

if(ISTOKEN("Flag"))
{
ded_stringid_t id;
int value;
char dummyStr[2];
// A new flag.
idx = DED_AddFlag(ded, "", 0);

FINDBEGIN;
for(;;)
{
READLABEL;
RV_STR("ID", ded->flags[idx].id)
RV_UINT("Value", ded->flags[idx].value)
RV_STR("ID", id)
RV_UINT("Value", value)
RV_STR("Info", dummyStr) // ignored
RV_END
CHECKSC;
}

ded->addFlag(id, value);

// Sanity check.
DENG2_ASSERT(ded->flags.find("id", id).geti("value") == value);
}

if(ISTOKEN("Mobj") || ISTOKEN("Thing"))
Expand Down

0 comments on commit 4aa1bd6

Please sign in to comment.