mirror of
https://github.com/enduro2d/enduro2d.git
synced 2026-01-05 01:51:02 +07:00
sorted vector instead hash map for property block
This commit is contained in:
@@ -615,13 +615,49 @@ namespace e2d
|
||||
v2f, v3f, v4f,
|
||||
m2f, m3f, m4f>;
|
||||
|
||||
template < typename T >
|
||||
class property_map final {
|
||||
public:
|
||||
property_map() = default;
|
||||
|
||||
property_map(property_map&& other) = default;
|
||||
property_map& operator=(property_map&& other) = default;
|
||||
|
||||
property_map(const property_map& other) = default;
|
||||
property_map& operator=(const property_map& other) = default;
|
||||
|
||||
T* find(str_hash key) noexcept;
|
||||
const T* find(str_hash key) const noexcept;
|
||||
|
||||
void assign(str_hash key, T&& value);
|
||||
void assign(str_hash key, const T& value);
|
||||
|
||||
void clear() noexcept;
|
||||
std::size_t size() const noexcept;
|
||||
|
||||
template < typename F >
|
||||
void foreach(F&& f) const;
|
||||
void merge(const property_map& other);
|
||||
bool equals(const property_map& other) const noexcept;
|
||||
private:
|
||||
struct entry {
|
||||
str_hash key;
|
||||
T value;
|
||||
public:
|
||||
entry(str_hash k, T&& v);
|
||||
entry(str_hash k, const T& v);
|
||||
bool operator==(const entry& other) const;
|
||||
};
|
||||
vector<entry> entries_;
|
||||
};
|
||||
|
||||
class property_block final {
|
||||
public:
|
||||
property_block() = default;
|
||||
~property_block() noexcept = default;
|
||||
|
||||
property_block(property_block&&) noexcept = default;
|
||||
property_block& operator=(property_block&&) noexcept = default;
|
||||
property_block(property_block&&) = default;
|
||||
property_block& operator=(property_block&&) = default;
|
||||
|
||||
property_block(const property_block&) = default;
|
||||
property_block& operator=(const property_block&) = default;
|
||||
@@ -652,8 +688,8 @@ namespace e2d
|
||||
std::size_t sampler_count() const noexcept;
|
||||
std::size_t property_count() const noexcept;
|
||||
private:
|
||||
hash_map<str_hash, sampler_state> samplers_;
|
||||
hash_map<str_hash, property_value> properties_;
|
||||
property_map<sampler_state> samplers_;
|
||||
property_map<property_value> properties_;
|
||||
};
|
||||
|
||||
class pass_state final {
|
||||
|
||||
@@ -75,36 +75,138 @@ namespace e2d
|
||||
|
||||
#undef DEFINE_ADD_ATTRIBUTE_SPECIALIZATION
|
||||
|
||||
//
|
||||
// render::property_map::entry
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
render::property_map<T>::entry::entry(str_hash k, T&& v)
|
||||
: key(k), value(std::move(v)) {}
|
||||
|
||||
template < typename T >
|
||||
render::property_map<T>::entry::entry(str_hash k, const T& v)
|
||||
: key(k), value(v) {}
|
||||
|
||||
template < typename T >
|
||||
bool render::property_map<T>::entry::operator==(const entry& other) const {
|
||||
return key == other.key
|
||||
&& value == other.value;
|
||||
}
|
||||
|
||||
//
|
||||
// render::property_map
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
T* render::property_map<T>::find(str_hash key) noexcept {
|
||||
const auto iter = std::lower_bound(
|
||||
entries_.begin(), entries_.end(), key,
|
||||
[](const entry& e, str_hash key){
|
||||
return e.key < key;
|
||||
});
|
||||
if ( iter != entries_.end() && iter->key == key ) {
|
||||
return &iter->value;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const T* render::property_map<T>::find(str_hash key) const noexcept {
|
||||
const auto iter = std::lower_bound(
|
||||
entries_.begin(), entries_.end(), key,
|
||||
[](const entry& e, str_hash key){
|
||||
return e.key < key;
|
||||
});
|
||||
if ( iter != entries_.end() && iter->key == key ) {
|
||||
return &iter->value;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void render::property_map<T>::assign(str_hash key, T&& value) {
|
||||
const auto iter = std::lower_bound(
|
||||
entries_.begin(), entries_.end(), key,
|
||||
[](const entry& e, str_hash key){
|
||||
return e.key < key;
|
||||
});
|
||||
if ( iter != entries_.end() && iter->key == key ) {
|
||||
iter->value = std::move(value);
|
||||
} else {
|
||||
entries_.emplace(iter, key, std::move(value));
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void render::property_map<T>::assign(str_hash key, const T& value) {
|
||||
const auto iter = std::lower_bound(
|
||||
entries_.begin(), entries_.end(), key,
|
||||
[](const entry& e, str_hash key){
|
||||
return e.key < key;
|
||||
});
|
||||
if ( iter != entries_.end() && iter->key == key ) {
|
||||
iter->value = value;
|
||||
} else {
|
||||
entries_.emplace(iter, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void render::property_map<T>::clear() noexcept {
|
||||
entries_.clear();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
std::size_t render::property_map<T>::size() const noexcept {
|
||||
return entries_.size();
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
template < typename F >
|
||||
void render::property_map<T>::foreach(F&& f) const {
|
||||
for ( std::size_t i = 0, e = entries_.size(); i < e; ++i ) {
|
||||
f(entries_[i].key, entries_[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
void render::property_map<T>::merge(const property_map& other) {
|
||||
other.foreach([this](str_hash name, const T& value){
|
||||
assign(name, value);
|
||||
});
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
bool render::property_map<T>::equals(const property_map& other) const noexcept {
|
||||
return entries_ == other.entries_;
|
||||
}
|
||||
|
||||
//
|
||||
// render::property_block
|
||||
//
|
||||
|
||||
template < typename T >
|
||||
render::property_block& render::property_block::property(str_hash name, T&& v) {
|
||||
properties_[name] = std::forward<T>(v);
|
||||
properties_.assign(name, std::forward<T>(v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template < typename T >
|
||||
const T* render::property_block::property(str_hash name) const noexcept {
|
||||
const auto iter = properties_.find(name);
|
||||
return iter != properties_.end()
|
||||
? stdex::get_if<T>(&iter->second)
|
||||
const property_value* prop = properties_.find(name);
|
||||
return prop
|
||||
? stdex::get_if<T>(*prop)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
template < typename F >
|
||||
void render::property_block::foreach_by_samplers(F&& f) const {
|
||||
for ( const auto& p : samplers_ ) {
|
||||
stdex::invoke(f, p.first, p.second);
|
||||
}
|
||||
samplers_.foreach(std::forward<F>(f));
|
||||
}
|
||||
|
||||
template < typename F >
|
||||
void render::property_block::foreach_by_properties(F&& f) const {
|
||||
for ( const auto& p : properties_ ) {
|
||||
stdex::invoke(f, p.first, p.second);
|
||||
}
|
||||
properties_.foreach(std::forward<F>(f));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -717,56 +717,46 @@ namespace e2d
|
||||
}
|
||||
|
||||
render::property_block& render::property_block::merge(const property_block& pb) {
|
||||
pb.foreach_by_properties([this](str_hash name, const property_value& v){
|
||||
property(name, v);
|
||||
});
|
||||
pb.foreach_by_samplers([this](str_hash name, const sampler_state& s){
|
||||
sampler(name, s);
|
||||
});
|
||||
properties_.merge(pb.properties_);
|
||||
samplers_.merge(pb.samplers_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool render::property_block::equals(const property_block& other) const noexcept {
|
||||
return properties_ == other.properties_
|
||||
&& samplers_ == other.samplers_;
|
||||
if ( properties_.size() != other.properties_.size() ) {
|
||||
return false;
|
||||
}
|
||||
if ( samplers_.size() != other.samplers_.size() ) {
|
||||
return false;
|
||||
}
|
||||
return properties_.equals(other.properties_)
|
||||
&& samplers_.equals(other.samplers_);
|
||||
}
|
||||
|
||||
render::property_block& render::property_block::sampler(str_hash name, const sampler_state& s) {
|
||||
samplers_[name] = s;
|
||||
samplers_.assign(name, s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
render::sampler_state* render::property_block::sampler(str_hash name) noexcept {
|
||||
const auto iter = samplers_.find(name);
|
||||
return iter != samplers_.end()
|
||||
? &iter->second
|
||||
: nullptr;
|
||||
return samplers_.find(name);
|
||||
}
|
||||
|
||||
const render::sampler_state* render::property_block::sampler(str_hash name) const noexcept {
|
||||
const auto iter = samplers_.find(name);
|
||||
return iter != samplers_.end()
|
||||
? &iter->second
|
||||
: nullptr;
|
||||
return samplers_.find(name);
|
||||
}
|
||||
|
||||
render::property_block& render::property_block::property(str_hash name, const property_value& v) {
|
||||
properties_[name] = v;
|
||||
properties_.assign(name, v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
render::property_value* render::property_block::property(str_hash name) noexcept {
|
||||
const auto iter = properties_.find(name);
|
||||
return iter != properties_.end()
|
||||
? &iter->second
|
||||
: nullptr;
|
||||
return properties_.find(name);
|
||||
}
|
||||
|
||||
const render::property_value* render::property_block::property(str_hash name) const noexcept {
|
||||
const auto iter = properties_.find(name);
|
||||
return iter != properties_.end()
|
||||
? &iter->second
|
||||
: nullptr;
|
||||
return properties_.find(name);
|
||||
}
|
||||
|
||||
std::size_t render::property_block::sampler_count() const noexcept {
|
||||
|
||||
Reference in New Issue
Block a user