summaryrefslogtreecommitdiff
path: root/src/craftdef.h
diff options
context:
space:
mode:
authorest31 <MTest31@outlook.com>2015-04-04 01:33:34 +0200
committerest31 <MTest31@outlook.com>2015-04-05 09:25:46 +0200
commit334e70455b7f8a4607fe99dc12710d48169113a6 (patch)
treebc1612e206a14067280ae3fcc11340b14d747314 /src/craftdef.h
parentfedbbc8883c1c8252fd8b40023687d953f93d10c (diff)
downloadminetest-334e70455b7f8a4607fe99dc12710d48169113a6.tar.gz
minetest-334e70455b7f8a4607fe99dc12710d48169113a6.tar.bz2
minetest-334e70455b7f8a4607fe99dc12710d48169113a6.zip
Crafting speedup
This greatly increases crafting performance, especially in worlds with many mods. Approved by @kwolekr. Introduces a hash-type-layered fall-through mechanism, where every layer specifies one hash algorithm, and the "deeper the fall", the more collisions to expect for the algorithm. One Craft definition only resides at one layer, which improves speed for lower layers (and a complete fail), due to most craft definitions residing at high layers. Due to the fall-through design, the undocumented behaviour that later craft recipes override older ones had to be weaked up a bit, but craft recipes with the same hash and layer will still override.
Diffstat (limited to 'src/craftdef.h')
-rw-r--r--src/craftdef.h96
1 files changed, 83 insertions, 13 deletions
diff --git a/src/craftdef.h b/src/craftdef.h
index 7902a2e27..cc7a0619c 100644
--- a/src/craftdef.h
+++ b/src/craftdef.h
@@ -44,6 +44,28 @@ enum CraftMethod
};
/*
+ The type a hash can be. The earlier a type is mentioned in this enum,
+ the earlier it is tried at crafting, and the less likely is a collision.
+ Changing order causes changes in behaviour, so know what you do.
+ */
+enum CraftHashType
+{
+ // Hashes the normalized names of the recipe's elements.
+ // Only recipes without group usage can be found here,
+ // because groups can't be guessed efficiently.
+ CRAFT_HASH_TYPE_ITEM_NAMES,
+
+ // Counts the non-empty slots.
+ CRAFT_HASH_TYPE_COUNT,
+
+ // This layer both spares an extra variable, and helps to retain (albeit rarely used) functionality. Maps to 0.
+ // Before hashes are "initialized", all hashes reside here, after initialisation, none are.
+ CRAFT_HASH_TYPE_UNHASHED
+
+};
+const int craft_hash_type_max = (int) CRAFT_HASH_TYPE_UNHASHED;
+
+/*
Input: The contents of the crafting slots, arranged in matrix form
*/
struct CraftInput
@@ -135,8 +157,13 @@ public:
// Decreases count of every input item
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const=0;
- virtual std::string dump() const=0;
+ virtual CraftHashType getHashType() const = 0;
+ virtual u64 getHash(CraftHashType type) const = 0;
+
+ // to be called after all mods are loaded, so that we catch all aliases
+ virtual void initHash(IGameDef *gamedef) = 0;
+ virtual std::string dump() const=0;
protected:
virtual void serializeBody(std::ostream &os) const=0;
virtual void deSerializeBody(std::istream &is, int version)=0;
@@ -152,14 +179,15 @@ class CraftDefinitionShaped: public CraftDefinition
{
public:
CraftDefinitionShaped():
- output(""), width(1), recipe(), replacements()
+ output(""), width(1), recipe(), hash_inited(false), replacements()
{}
CraftDefinitionShaped(
const std::string &output_,
unsigned int width_,
const std::vector<std::string> &recipe_,
const CraftReplacements &replacements_):
- output(output_), width(width_), recipe(recipe_), replacements(replacements_)
+ output(output_), width(width_), recipe(recipe_),
+ hash_inited(false), replacements(replacements_)
{}
virtual ~CraftDefinitionShaped(){}
@@ -169,6 +197,11 @@ public:
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
+ virtual CraftHashType getHashType() const;
+ virtual u64 getHash(CraftHashType type) const;
+
+ virtual void initHash(IGameDef *gamedef);
+
virtual std::string dump() const;
protected:
@@ -182,6 +215,10 @@ private:
unsigned int width;
// Recipe matrix (itemstrings)
std::vector<std::string> recipe;
+ // Recipe matrix (item names)
+ std::vector<std::string> recipe_names;
+ // bool indicating if initHash has been called already
+ bool hash_inited;
// Replacement items for decrementInput()
CraftReplacements replacements;
};
@@ -195,13 +232,14 @@ class CraftDefinitionShapeless: public CraftDefinition
{
public:
CraftDefinitionShapeless():
- output(""), recipe(), replacements()
+ output(""), recipe(), hash_inited(false), replacements()
{}
CraftDefinitionShapeless(
const std::string &output_,
const std::vector<std::string> &recipe_,
const CraftReplacements &replacements_):
- output(output_), recipe(recipe_), replacements(replacements_)
+ output(output_), recipe(recipe_),
+ hash_inited(false), replacements(replacements_)
{}
virtual ~CraftDefinitionShapeless(){}
@@ -211,6 +249,11 @@ public:
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
+ virtual CraftHashType getHashType() const;
+ virtual u64 getHash(CraftHashType type) const;
+
+ virtual void initHash(IGameDef *gamedef);
+
virtual std::string dump() const;
protected:
@@ -222,6 +265,10 @@ private:
std::string output;
// Recipe list (itemstrings)
std::vector<std::string> recipe;
+ // Recipe list (item names)
+ std::vector<std::string> recipe_names;
+ // bool indicating if initHash has been called already
+ bool hash_inited;
// Replacement items for decrementInput()
CraftReplacements replacements;
};
@@ -249,6 +296,11 @@ public:
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
+ virtual CraftHashType getHashType() const { return CRAFT_HASH_TYPE_COUNT; }
+ virtual u64 getHash(CraftHashType type) const { return 2; }
+
+ virtual void initHash(IGameDef *gamedef) {}
+
virtual std::string dump() const;
protected:
@@ -272,14 +324,15 @@ class CraftDefinitionCooking: public CraftDefinition
{
public:
CraftDefinitionCooking():
- output(""), recipe(""), cooktime()
+ output(""), recipe(""), hash_inited(false), cooktime()
{}
CraftDefinitionCooking(
const std::string &output_,
const std::string &recipe_,
float cooktime_,
const CraftReplacements &replacements_):
- output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_)
+ output(output_), recipe(recipe_), hash_inited(false),
+ cooktime(cooktime_), replacements(replacements_)
{}
virtual ~CraftDefinitionCooking(){}
@@ -289,6 +342,11 @@ public:
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
+ virtual CraftHashType getHashType() const;
+ virtual u64 getHash(CraftHashType type) const;
+
+ virtual void initHash(IGameDef *gamedef);
+
virtual std::string dump() const;
protected:
@@ -300,6 +358,10 @@ private:
std::string output;
// Recipe itemstring
std::string recipe;
+ // Recipe item name
+ std::string recipe_name;
+ // bool indicating if initHash has been called already
+ bool hash_inited;
// Time in seconds
float cooktime;
// Replacement items for decrementInput()
@@ -314,12 +376,12 @@ class CraftDefinitionFuel: public CraftDefinition
{
public:
CraftDefinitionFuel():
- recipe(""), burntime()
+ recipe(""), hash_inited(false), burntime()
{}
CraftDefinitionFuel(std::string recipe_,
float burntime_,
const CraftReplacements &replacements_):
- recipe(recipe_), burntime(burntime_), replacements(replacements_)
+ recipe(recipe_), hash_inited(false), burntime(burntime_), replacements(replacements_)
{}
virtual ~CraftDefinitionFuel(){}
@@ -329,6 +391,11 @@ public:
virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
+ virtual CraftHashType getHashType() const;
+ virtual u64 getHash(CraftHashType type) const;
+
+ virtual void initHash(IGameDef *gamedef);
+
virtual std::string dump() const;
protected:
@@ -338,6 +405,10 @@ protected:
private:
// Recipe itemstring
std::string recipe;
+ // Recipe item name
+ std::string recipe_name;
+ // bool indicating if initHash has been called already
+ bool hash_inited;
// Time in seconds
float burntime;
// Replacement items for decrementInput()
@@ -361,8 +432,6 @@ public:
// Print crafting recipes for debugging
virtual std::string dump() const=0;
-
- virtual void serialize(std::ostream &os) const=0;
};
class IWritableCraftDefManager : public ICraftDefManager
@@ -383,11 +452,12 @@ public:
// Add a crafting definition.
// After calling this, the pointer belongs to the manager.
virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) = 0;
+
// Delete all crafting definitions
virtual void clear()=0;
- virtual void serialize(std::ostream &os) const=0;
- virtual void deSerialize(std::istream &is, IGameDef *gamedef) = 0;
+ // To be called after all mods are loaded, so that we catch all aliases
+ virtual void initHashes(IGameDef *gamedef) = 0;
};
IWritableCraftDefManager* createCraftDefManager();