You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-31 18:41:20 +00:00
Merge pull request #100446 from YYF233333/vmap
Replace `VMap` used in `VisualShader` with `HashMap` and remove `VMap`
This commit is contained in:
@@ -1,201 +0,0 @@
|
||||
/**************************************************************************/
|
||||
/* vmap.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/templates/cowdata.h"
|
||||
#include "core/typedefs.h"
|
||||
|
||||
template <typename T, typename V>
|
||||
class VMap {
|
||||
public:
|
||||
struct Pair {
|
||||
T key;
|
||||
V value;
|
||||
|
||||
_FORCE_INLINE_ Pair() {}
|
||||
|
||||
_FORCE_INLINE_ Pair(const T &p_key, const V &p_value) {
|
||||
key = p_key;
|
||||
value = p_value;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
CowData<Pair> _cowdata;
|
||||
|
||||
_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
|
||||
r_exact = false;
|
||||
if (_cowdata.is_empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int low = 0;
|
||||
int high = _cowdata.size() - 1;
|
||||
const Pair *a = _cowdata.ptr();
|
||||
int middle = 0;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (low > high) {
|
||||
ERR_PRINT("low > high, this may be a bug");
|
||||
}
|
||||
#endif
|
||||
while (low <= high) {
|
||||
middle = (low + high) / 2;
|
||||
|
||||
if (p_val < a[middle].key) {
|
||||
high = middle - 1; //search low end of array
|
||||
} else if (a[middle].key < p_val) {
|
||||
low = middle + 1; //search high end of array
|
||||
} else {
|
||||
r_exact = true;
|
||||
return middle;
|
||||
}
|
||||
}
|
||||
|
||||
//return the position where this would be inserted
|
||||
if (a[middle].key < p_val) {
|
||||
middle++;
|
||||
}
|
||||
return middle;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int _find_exact(const T &p_val) const {
|
||||
if (_cowdata.is_empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int low = 0;
|
||||
int high = _cowdata.size() - 1;
|
||||
int middle;
|
||||
const Pair *a = _cowdata.ptr();
|
||||
|
||||
while (low <= high) {
|
||||
middle = (low + high) / 2;
|
||||
|
||||
if (p_val < a[middle].key) {
|
||||
high = middle - 1; //search low end of array
|
||||
} else if (a[middle].key < p_val) {
|
||||
low = middle + 1; //search high end of array
|
||||
} else {
|
||||
return middle;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public:
|
||||
int insert(const T &p_key, const V &p_val) {
|
||||
bool exact;
|
||||
int pos = _find(p_key, exact);
|
||||
if (exact) {
|
||||
_cowdata.get_m(pos).value = p_val;
|
||||
return pos;
|
||||
}
|
||||
_cowdata.insert(pos, Pair(p_key, p_val));
|
||||
return pos;
|
||||
}
|
||||
|
||||
bool has(const T &p_val) const {
|
||||
return _find_exact(p_val) != -1;
|
||||
}
|
||||
|
||||
void erase(const T &p_val) {
|
||||
int pos = _find_exact(p_val);
|
||||
if (pos < 0) {
|
||||
return;
|
||||
}
|
||||
_cowdata.remove_at(pos);
|
||||
}
|
||||
|
||||
int find(const T &p_val) const {
|
||||
return _find_exact(p_val);
|
||||
}
|
||||
|
||||
int find_nearest(const T &p_val) const {
|
||||
if (_cowdata.is_empty()) {
|
||||
return -1;
|
||||
}
|
||||
bool exact;
|
||||
return _find(p_val, exact);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int size() const { return _cowdata.size(); }
|
||||
_FORCE_INLINE_ bool is_empty() const { return _cowdata.is_empty(); }
|
||||
|
||||
const Pair *get_array() const {
|
||||
return _cowdata.ptr();
|
||||
}
|
||||
|
||||
Pair *get_array() {
|
||||
return _cowdata.ptrw();
|
||||
}
|
||||
|
||||
const V &getv(int p_index) const {
|
||||
return _cowdata.get(p_index).value;
|
||||
}
|
||||
|
||||
V &getv(int p_index) {
|
||||
return _cowdata.get_m(p_index).value;
|
||||
}
|
||||
|
||||
const T &getk(int p_index) const {
|
||||
return _cowdata.get(p_index).key;
|
||||
}
|
||||
|
||||
T &getk(int p_index) {
|
||||
return _cowdata.get_m(p_index).key;
|
||||
}
|
||||
|
||||
inline const V &operator[](const T &p_key) const {
|
||||
int pos = _find_exact(p_key);
|
||||
|
||||
CRASH_COND(pos < 0);
|
||||
|
||||
return _cowdata.get(pos).value;
|
||||
}
|
||||
|
||||
inline V &operator[](const T &p_key) {
|
||||
int pos = _find_exact(p_key);
|
||||
if (pos < 0) {
|
||||
pos = insert(p_key, V());
|
||||
}
|
||||
|
||||
return _cowdata.get_m(pos).value;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ VMap() {}
|
||||
_FORCE_INLINE_ VMap(std::initializer_list<T> p_init) :
|
||||
_cowdata(p_init) {}
|
||||
_FORCE_INLINE_ VMap(const VMap &p_from) = default;
|
||||
|
||||
void operator=(const VMap &p_from) { _cowdata = p_from._cowdata; }
|
||||
};
|
||||
@@ -31,7 +31,6 @@
|
||||
#include "visual_shader.h"
|
||||
|
||||
#include "core/templates/rb_map.h"
|
||||
#include "core/templates/vmap.h"
|
||||
#include "core/variant/variant_utility.h"
|
||||
#include "servers/rendering/shader_types.h"
|
||||
#include "visual_shader_nodes.h"
|
||||
@@ -1516,16 +1515,9 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
|
||||
global_code += global_expressions;
|
||||
|
||||
//make it faster to go around through shader
|
||||
VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
|
||||
VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
|
||||
HashMap<ConnectionKey, const List<Connection>::Element *> input_connections;
|
||||
|
||||
for (const List<Connection>::Element *E = graph[p_type].connections.front(); E; E = E->next()) {
|
||||
ConnectionKey from_key;
|
||||
from_key.node = E->get().from_node;
|
||||
from_key.port = E->get().from_port;
|
||||
|
||||
output_connections.insert(from_key, E);
|
||||
|
||||
ConnectionKey to_key;
|
||||
to_key.node = E->get().to_node;
|
||||
to_key.port = E->get().to_port;
|
||||
@@ -1536,7 +1528,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
|
||||
shader_code += "\nvoid fragment() {\n";
|
||||
|
||||
HashSet<int> processed;
|
||||
Error err = _write_node(p_type, &global_code, &global_code_per_node, &global_code_per_func, shader_code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes);
|
||||
Error err = _write_node(p_type, &global_code, &global_code_per_node, &global_code_per_func, shader_code, default_tex_params, input_connections, p_node, processed, true, classes);
|
||||
ERR_FAIL_COND_V(err != OK, String());
|
||||
|
||||
switch (node->get_output_port_type(p_port)) {
|
||||
@@ -1955,7 +1947,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
|
||||
}
|
||||
}
|
||||
|
||||
Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringBuilder *p_global_code_per_node, HashMap<Type, StringBuilder> *p_global_code_per_func, StringBuilder &r_code, Vector<VisualShader::DefaultTextureParam> &r_def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &p_input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &p_output_connections, int p_node, HashSet<int> &r_processed, bool p_for_preview, HashSet<StringName> &r_classes) const {
|
||||
Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringBuilder *p_global_code_per_node, HashMap<Type, StringBuilder> *p_global_code_per_func, StringBuilder &r_code, Vector<VisualShader::DefaultTextureParam> &r_def_tex_params, const HashMap<ConnectionKey, const List<Connection>::Element *> &p_input_connections, int p_node, HashSet<int> &r_processed, bool p_for_preview, HashSet<StringName> &r_classes) const {
|
||||
const Ref<VisualShaderNode> vsnode = graph[type].nodes[p_node].node;
|
||||
|
||||
if (vsnode->is_disabled()) {
|
||||
@@ -1977,7 +1969,7 @@ Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringB
|
||||
continue;
|
||||
}
|
||||
|
||||
Error err = _write_node(type, p_global_code, p_global_code_per_node, p_global_code_per_func, r_code, r_def_tex_params, p_input_connections, p_output_connections, from_node, r_processed, p_for_preview, r_classes);
|
||||
Error err = _write_node(type, p_global_code, p_global_code_per_node, p_global_code_per_func, r_code, r_def_tex_params, p_input_connections, from_node, r_processed, p_for_preview, r_classes);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
@@ -2702,8 +2694,7 @@ void VisualShader::_update_shader() const {
|
||||
}
|
||||
|
||||
//make it faster to go around through shader
|
||||
VMap<ConnectionKey, const List<Connection>::Element *> input_connections;
|
||||
VMap<ConnectionKey, const List<Connection>::Element *> output_connections;
|
||||
HashMap<ConnectionKey, const List<Connection>::Element *> input_connections;
|
||||
|
||||
StringBuilder func_code;
|
||||
HashSet<int> processed;
|
||||
@@ -2764,12 +2755,6 @@ void VisualShader::_update_shader() const {
|
||||
}
|
||||
|
||||
for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) {
|
||||
ConnectionKey from_key;
|
||||
from_key.node = E->get().from_node;
|
||||
from_key.port = E->get().from_port;
|
||||
|
||||
output_connections.insert(from_key, E);
|
||||
|
||||
ConnectionKey to_key;
|
||||
to_key.node = E->get().to_node;
|
||||
to_key.port = E->get().to_port;
|
||||
@@ -2791,19 +2776,19 @@ void VisualShader::_update_shader() const {
|
||||
}
|
||||
insertion_pos.insert(i, shader_code.get_string_length() + func_code.get_string_length());
|
||||
|
||||
Error err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes);
|
||||
Error err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, NODE_ID_OUTPUT, processed, false, classes);
|
||||
ERR_FAIL_COND(err != OK);
|
||||
|
||||
if (varying_setters.has(i)) {
|
||||
for (int &E : varying_setters[i]) {
|
||||
err = _write_node(Type(i), &global_code, &global_code_per_node, nullptr, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes);
|
||||
err = _write_node(Type(i), &global_code, &global_code_per_node, nullptr, func_code, default_tex_params, input_connections, E, processed, false, classes);
|
||||
ERR_FAIL_COND(err != OK);
|
||||
}
|
||||
}
|
||||
|
||||
if (emitters.has(i)) {
|
||||
for (int &E : emitters[i]) {
|
||||
err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, output_connections, E, processed, false, classes);
|
||||
err = _write_node(Type(i), &global_code, &global_code_per_node, &global_code_per_func, func_code, default_tex_params, input_connections, E, processed, false, classes);
|
||||
ERR_FAIL_COND(err != OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,12 +156,11 @@ private:
|
||||
uint64_t port : 32;
|
||||
};
|
||||
uint64_t key = 0;
|
||||
bool operator<(const ConnectionKey &p_key) const {
|
||||
return key < p_key.key;
|
||||
}
|
||||
// This is used to apply default equal and hash methods for uint64_t to ConnectionKey.
|
||||
operator uint64_t() const { return key; }
|
||||
};
|
||||
|
||||
Error _write_node(Type p_type, StringBuilder *p_global_code, StringBuilder *p_global_code_per_node, HashMap<Type, StringBuilder> *p_global_code_per_func, StringBuilder &r_code, Vector<DefaultTextureParam> &r_def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &p_input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &p_output_connections, int p_node, HashSet<int> &r_processed, bool p_for_preview, HashSet<StringName> &r_classes) const;
|
||||
Error _write_node(Type p_type, StringBuilder *p_global_code, StringBuilder *p_global_code_per_node, HashMap<Type, StringBuilder> *p_global_code_per_func, StringBuilder &r_code, Vector<DefaultTextureParam> &r_def_tex_params, const HashMap<ConnectionKey, const List<Connection>::Element *> &p_input_connections, int p_node, HashSet<int> &r_processed, bool p_for_preview, HashSet<StringName> &r_classes) const;
|
||||
|
||||
void _input_type_changed(Type p_type, int p_id);
|
||||
bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const;
|
||||
|
||||
Reference in New Issue
Block a user