Blob Blame Raw
#ifndef GENERATOR_H
#define GENERATOR_H


#include <climits>
#include <map>

#include "surface.h"
#include "vector.h"


class Generator: public Shared {
public:
	struct CacheEntry;
	typedef std::map<ULongIntVector2, CacheEntry> Cache;
	
	struct CacheEntry {
		Cache::iterator next, previous;
		bool in_use;
		Vector4 value;
	};
	
	static inline ULongInt random(ULongInt x) {
		x ^= x << 13;
		x ^= x >> 7;
		x ^= x << 17;
		return x;
	}
	static inline Real random_to_real(ULongInt x)
		{ return Real(x)/Real(ULLONG_MAX); }

private:
	const ULongInt one;
	const int max_cache_count;
	
	mutable Cache m_cache;
	mutable Cache::iterator m_cache_top;
	mutable int m_cache_count;
	
	ULongInt m_seeds[2][4];

public:
	Generator();
	explicit Generator(ULongInt seed);
	
	inline const ULongInt* seeds_x() const { return m_seeds[0]; }
	inline const ULongInt* seeds_y() const { return m_seeds[1]; }
	inline ULongInt seed() const { return seeds_x()[0]; }
	void set_seed(ULongInt x);

	Real random(const ULongIntVector2 &coord, int index) const;
	Vector4 generate(const ULongIntVector2 &coord, bool shrink_cache = true) const;
	Vector4 generate(const Vector2 &coord, const Vector2 &precision) const;
	void generate(Surface &target, const Vector2 &lt, const Vector2 &rb) const;
};


#endif