Implement coloring for disabled branches in the shader editor
This commit is contained in:
parent
f2a6168414
commit
22df2c527b
@ -47,6 +47,50 @@
|
|||||||
#include "servers/rendering/shader_preprocessor.h"
|
#include "servers/rendering/shader_preprocessor.h"
|
||||||
#include "servers/rendering/shader_types.h"
|
#include "servers/rendering/shader_types.h"
|
||||||
|
|
||||||
|
/*** SHADER SYNTAX HIGHLIGHTER ****/
|
||||||
|
|
||||||
|
Dictionary GDShaderSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
|
||||||
|
Dictionary color_map;
|
||||||
|
|
||||||
|
for (const Point2i ®ion : disabled_branch_regions) {
|
||||||
|
if (p_line >= region.x && p_line <= region.y) {
|
||||||
|
Dictionary highlighter_info;
|
||||||
|
highlighter_info["color"] = disabled_branch_color;
|
||||||
|
|
||||||
|
color_map[0] = highlighter_info;
|
||||||
|
return color_map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CodeHighlighter::_get_line_syntax_highlighting_impl(p_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDShaderSyntaxHighlighter::add_disabled_branch_region(const Point2i &p_region) {
|
||||||
|
ERR_FAIL_COND(p_region.x < 0);
|
||||||
|
ERR_FAIL_COND(p_region.y < 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < disabled_branch_regions.size(); i++) {
|
||||||
|
ERR_FAIL_COND_MSG(disabled_branch_regions[i].x == p_region.x, "Branch region with a start line '" + itos(p_region.x) + "' already exists.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2i disabled_branch_region;
|
||||||
|
disabled_branch_region.x = p_region.x;
|
||||||
|
disabled_branch_region.y = p_region.y;
|
||||||
|
disabled_branch_regions.push_back(disabled_branch_region);
|
||||||
|
|
||||||
|
clear_highlighting_cache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDShaderSyntaxHighlighter::clear_disabled_branch_regions() {
|
||||||
|
disabled_branch_regions.clear();
|
||||||
|
clear_highlighting_cache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDShaderSyntaxHighlighter::set_disabled_branch_color(const Color &p_color) {
|
||||||
|
disabled_branch_color = p_color;
|
||||||
|
clear_highlighting_cache();
|
||||||
|
}
|
||||||
|
|
||||||
/*** SHADER SCRIPT EDITOR ****/
|
/*** SHADER SCRIPT EDITOR ****/
|
||||||
|
|
||||||
static bool saved_warnings_enabled = false;
|
static bool saved_warnings_enabled = false;
|
||||||
@ -264,6 +308,7 @@ void ShaderTextEditor::_load_theme_settings() {
|
|||||||
syntax_highlighter->clear_color_regions();
|
syntax_highlighter->clear_color_regions();
|
||||||
syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
|
syntax_highlighter->add_color_region("/*", "*/", comment_color, false);
|
||||||
syntax_highlighter->add_color_region("//", "", comment_color, true);
|
syntax_highlighter->add_color_region("//", "", comment_color, true);
|
||||||
|
syntax_highlighter->set_disabled_branch_color(comment_color);
|
||||||
|
|
||||||
text_editor->clear_comment_delimiters();
|
text_editor->clear_comment_delimiters();
|
||||||
text_editor->add_comment_delimiter("/*", "*/", false);
|
text_editor->add_comment_delimiter("/*", "*/", false);
|
||||||
@ -346,7 +391,7 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptLa
|
|||||||
if (!complete_from_path.ends_with("/")) {
|
if (!complete_from_path.ends_with("/")) {
|
||||||
complete_from_path += "/";
|
complete_from_path += "/";
|
||||||
}
|
}
|
||||||
preprocessor.preprocess(p_code, code, nullptr, nullptr, nullptr, &pp_options, _complete_include_paths);
|
preprocessor.preprocess(p_code, "", code, nullptr, nullptr, nullptr, nullptr, &pp_options, _complete_include_paths);
|
||||||
complete_from_path = String();
|
complete_from_path = String();
|
||||||
if (pp_options.size()) {
|
if (pp_options.size()) {
|
||||||
for (const ScriptLanguage::CodeCompletionOption &E : pp_options) {
|
for (const ScriptLanguage::CodeCompletionOption &E : pp_options) {
|
||||||
@ -392,11 +437,29 @@ void ShaderTextEditor::_validate_script() {
|
|||||||
String code_pp;
|
String code_pp;
|
||||||
String error_pp;
|
String error_pp;
|
||||||
List<ShaderPreprocessor::FilePosition> err_positions;
|
List<ShaderPreprocessor::FilePosition> err_positions;
|
||||||
last_compile_result = preprocessor.preprocess(code, code_pp, &error_pp, &err_positions);
|
List<ShaderPreprocessor::Region> regions;
|
||||||
|
String filename;
|
||||||
|
if (shader.is_valid()) {
|
||||||
|
filename = shader->get_path();
|
||||||
|
} else if (shader_inc.is_valid()) {
|
||||||
|
filename = shader_inc->get_path();
|
||||||
|
}
|
||||||
|
last_compile_result = preprocessor.preprocess(code, filename, code_pp, &error_pp, &err_positions, ®ions);
|
||||||
|
|
||||||
for (int i = 0; i < get_text_editor()->get_line_count(); i++) {
|
for (int i = 0; i < get_text_editor()->get_line_count(); i++) {
|
||||||
get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0));
|
get_text_editor()->set_line_background_color(i, Color(0, 0, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syntax_highlighter->clear_disabled_branch_regions();
|
||||||
|
for (const ShaderPreprocessor::Region ®ion : regions) {
|
||||||
|
if (!region.enabled) {
|
||||||
|
if (filename != region.file) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
syntax_highlighter->add_disabled_branch_region(Point2i(region.from_line, region.to_line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set_error("");
|
set_error("");
|
||||||
set_error_count(0);
|
set_error_count(0);
|
||||||
|
|
||||||
|
@ -48,6 +48,21 @@ class VisualShaderEditor;
|
|||||||
class HSplitContainer;
|
class HSplitContainer;
|
||||||
class ShaderCreateDialog;
|
class ShaderCreateDialog;
|
||||||
|
|
||||||
|
class GDShaderSyntaxHighlighter : public CodeHighlighter {
|
||||||
|
GDCLASS(GDShaderSyntaxHighlighter, CodeHighlighter)
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<Point2i> disabled_branch_regions;
|
||||||
|
Color disabled_branch_color;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override;
|
||||||
|
|
||||||
|
void add_disabled_branch_region(const Point2i &p_region);
|
||||||
|
void clear_disabled_branch_regions();
|
||||||
|
void set_disabled_branch_color(const Color &p_color);
|
||||||
|
};
|
||||||
|
|
||||||
class ShaderTextEditor : public CodeTextEditor {
|
class ShaderTextEditor : public CodeTextEditor {
|
||||||
GDCLASS(ShaderTextEditor, CodeTextEditor);
|
GDCLASS(ShaderTextEditor, CodeTextEditor);
|
||||||
|
|
||||||
@ -57,7 +72,7 @@ class ShaderTextEditor : public CodeTextEditor {
|
|||||||
_ALWAYS_INLINE_ bool operator()(const ShaderWarning &p_a, const ShaderWarning &p_b) const { return (p_a.get_line() < p_b.get_line()); }
|
_ALWAYS_INLINE_ bool operator()(const ShaderWarning &p_a, const ShaderWarning &p_b) const { return (p_a.get_line() < p_b.get_line()); }
|
||||||
};
|
};
|
||||||
|
|
||||||
Ref<CodeHighlighter> syntax_highlighter;
|
Ref<GDShaderSyntaxHighlighter> syntax_highlighter;
|
||||||
RichTextLabel *warnings_panel = nullptr;
|
RichTextLabel *warnings_panel = nullptr;
|
||||||
Ref<Shader> shader;
|
Ref<Shader> shader;
|
||||||
Ref<ShaderInclude> shader_inc;
|
Ref<ShaderInclude> shader_inc;
|
||||||
|
@ -82,7 +82,7 @@ void Shader::set_code(const String &p_code) {
|
|||||||
// 1) Need to keep track of include dependencies at resource level
|
// 1) Need to keep track of include dependencies at resource level
|
||||||
// 2) Server does not do interaction with Resource filetypes, this is a scene level feature.
|
// 2) Server does not do interaction with Resource filetypes, this is a scene level feature.
|
||||||
ShaderPreprocessor preprocessor;
|
ShaderPreprocessor preprocessor;
|
||||||
preprocessor.preprocess(p_code, pp_code, nullptr, nullptr, &new_include_dependencies);
|
preprocessor.preprocess(p_code, "", pp_code, nullptr, nullptr, nullptr, &new_include_dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
|
// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
|
||||||
|
@ -47,7 +47,7 @@ void ShaderInclude::set_code(const String &p_code) {
|
|||||||
{
|
{
|
||||||
String pp_code;
|
String pp_code;
|
||||||
ShaderPreprocessor preprocessor;
|
ShaderPreprocessor preprocessor;
|
||||||
preprocessor.preprocess(p_code, pp_code, nullptr, nullptr, &new_dependencies);
|
preprocessor.preprocess(p_code, "", pp_code, nullptr, nullptr, nullptr, &new_dependencies);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
|
// This ensures previous include resources are not freed and then re-loaded during parse (which would make compiling slower)
|
||||||
|
@ -416,16 +416,22 @@ void ShaderPreprocessor::process_define(Tokenizer *p_tokenizer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) {
|
void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) {
|
||||||
|
const int line = p_tokenizer->get_line();
|
||||||
|
|
||||||
if (state->skip_stack_else.is_empty()) {
|
if (state->skip_stack_else.is_empty()) {
|
||||||
set_error(RTR("Unmatched else."), p_tokenizer->get_line());
|
set_error(RTR("Unmatched else."), line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (state->previous_region != nullptr) {
|
||||||
|
state->previous_region->to_line = line - 1;
|
||||||
|
}
|
||||||
|
|
||||||
p_tokenizer->advance('\n');
|
p_tokenizer->advance('\n');
|
||||||
|
|
||||||
bool skip = state->skip_stack_else[state->skip_stack_else.size() - 1];
|
bool skip = state->skip_stack_else[state->skip_stack_else.size() - 1];
|
||||||
state->skip_stack_else.remove_at(state->skip_stack_else.size() - 1);
|
state->skip_stack_else.remove_at(state->skip_stack_else.size() - 1);
|
||||||
|
|
||||||
Vector<SkippedCondition *> vec = state->skipped_conditions[state->current_include];
|
Vector<SkippedCondition *> vec = state->skipped_conditions[state->current_filename];
|
||||||
int index = vec.size() - 1;
|
int index = vec.size() - 1;
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
SkippedCondition *cond = vec[index];
|
SkippedCondition *cond = vec[index];
|
||||||
@ -434,6 +440,10 @@ void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state->save_regions) {
|
||||||
|
add_region(line + 1, !skip, state->previous_region->parent);
|
||||||
|
}
|
||||||
|
|
||||||
if (skip) {
|
if (skip) {
|
||||||
Vector<String> ends;
|
Vector<String> ends;
|
||||||
ends.push_back("endif");
|
ends.push_back("endif");
|
||||||
@ -447,8 +457,12 @@ void ShaderPreprocessor::process_endif(Tokenizer *p_tokenizer) {
|
|||||||
set_error(RTR("Unmatched endif."), p_tokenizer->get_line());
|
set_error(RTR("Unmatched endif."), p_tokenizer->get_line());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (state->previous_region != nullptr) {
|
||||||
|
state->previous_region->to_line = p_tokenizer->get_line() - 1;
|
||||||
|
state->previous_region = state->previous_region->parent;
|
||||||
|
}
|
||||||
|
|
||||||
Vector<SkippedCondition *> vec = state->skipped_conditions[state->current_include];
|
Vector<SkippedCondition *> vec = state->skipped_conditions[state->current_filename];
|
||||||
int index = vec.size() - 1;
|
int index = vec.size() - 1;
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
SkippedCondition *cond = vec[index];
|
SkippedCondition *cond = vec[index];
|
||||||
@ -461,7 +475,7 @@ void ShaderPreprocessor::process_endif(Tokenizer *p_tokenizer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ShaderPreprocessor::process_if(Tokenizer *p_tokenizer) {
|
void ShaderPreprocessor::process_if(Tokenizer *p_tokenizer) {
|
||||||
int line = p_tokenizer->get_line();
|
const int line = p_tokenizer->get_line();
|
||||||
|
|
||||||
String body = tokens_to_string(p_tokenizer->advance('\n')).strip_edges();
|
String body = tokens_to_string(p_tokenizer->advance('\n')).strip_edges();
|
||||||
if (body.is_empty()) {
|
if (body.is_empty()) {
|
||||||
@ -490,6 +504,10 @@ void ShaderPreprocessor::process_if(Tokenizer *p_tokenizer) {
|
|||||||
|
|
||||||
bool success = v.booleanize();
|
bool success = v.booleanize();
|
||||||
start_branch_condition(p_tokenizer, success);
|
start_branch_condition(p_tokenizer, success);
|
||||||
|
|
||||||
|
if (state->save_regions) {
|
||||||
|
add_region(line + 1, success, state->previous_region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderPreprocessor::process_ifdef(Tokenizer *p_tokenizer) {
|
void ShaderPreprocessor::process_ifdef(Tokenizer *p_tokenizer) {
|
||||||
@ -510,6 +528,10 @@ void ShaderPreprocessor::process_ifdef(Tokenizer *p_tokenizer) {
|
|||||||
|
|
||||||
bool success = state->defines.has(label);
|
bool success = state->defines.has(label);
|
||||||
start_branch_condition(p_tokenizer, success);
|
start_branch_condition(p_tokenizer, success);
|
||||||
|
|
||||||
|
if (state->save_regions) {
|
||||||
|
add_region(line + 1, success, state->previous_region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderPreprocessor::process_ifndef(Tokenizer *p_tokenizer) {
|
void ShaderPreprocessor::process_ifndef(Tokenizer *p_tokenizer) {
|
||||||
@ -530,6 +552,10 @@ void ShaderPreprocessor::process_ifndef(Tokenizer *p_tokenizer) {
|
|||||||
|
|
||||||
bool success = !state->defines.has(label);
|
bool success = !state->defines.has(label);
|
||||||
start_branch_condition(p_tokenizer, success);
|
start_branch_condition(p_tokenizer, success);
|
||||||
|
|
||||||
|
if (state->save_regions) {
|
||||||
|
add_region(line + 1, success, state->previous_region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {
|
void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {
|
||||||
@ -594,15 +620,15 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String old_include = state->current_include;
|
String old_filename = state->current_filename;
|
||||||
state->current_include = real_path;
|
state->current_filename = real_path;
|
||||||
ShaderPreprocessor processor;
|
ShaderPreprocessor processor;
|
||||||
|
|
||||||
int prev_condition_depth = state->condition_depth;
|
int prev_condition_depth = state->condition_depth;
|
||||||
state->condition_depth = 0;
|
state->condition_depth = 0;
|
||||||
|
|
||||||
FilePosition fp;
|
FilePosition fp;
|
||||||
fp.file = state->current_include;
|
fp.file = state->current_filename;
|
||||||
fp.line = line;
|
fp.line = line;
|
||||||
state->include_positions.push_back(fp);
|
state->include_positions.push_back(fp);
|
||||||
|
|
||||||
@ -614,7 +640,7 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) {
|
|||||||
|
|
||||||
// Reset to last include if there are no errors. We want to use this as context.
|
// Reset to last include if there are no errors. We want to use this as context.
|
||||||
if (state->error.is_empty()) {
|
if (state->error.is_empty()) {
|
||||||
state->current_include = old_include;
|
state->current_filename = old_filename;
|
||||||
state->include_positions.pop_back();
|
state->include_positions.pop_back();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
@ -668,6 +694,15 @@ void ShaderPreprocessor::process_undef(Tokenizer *p_tokenizer) {
|
|||||||
state->defines.erase(label);
|
state->defines.erase(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderPreprocessor::add_region(int p_line, bool p_enabled, Region *p_parent_region) {
|
||||||
|
Region region;
|
||||||
|
region.file = state->current_filename;
|
||||||
|
region.enabled = p_enabled;
|
||||||
|
region.from_line = p_line;
|
||||||
|
region.parent = p_parent_region;
|
||||||
|
state->previous_region = &state->regions[region.file].push_back(region)->get();
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderPreprocessor::start_branch_condition(Tokenizer *p_tokenizer, bool p_success) {
|
void ShaderPreprocessor::start_branch_condition(Tokenizer *p_tokenizer, bool p_success) {
|
||||||
state->condition_depth++;
|
state->condition_depth++;
|
||||||
|
|
||||||
@ -676,7 +711,7 @@ void ShaderPreprocessor::start_branch_condition(Tokenizer *p_tokenizer, bool p_s
|
|||||||
} else {
|
} else {
|
||||||
SkippedCondition *cond = memnew(SkippedCondition());
|
SkippedCondition *cond = memnew(SkippedCondition());
|
||||||
cond->start_line = p_tokenizer->get_line();
|
cond->start_line = p_tokenizer->get_line();
|
||||||
state->skipped_conditions[state->current_include].push_back(cond);
|
state->skipped_conditions[state->current_filename].push_back(cond);
|
||||||
|
|
||||||
Vector<String> ends;
|
Vector<String> ends;
|
||||||
ends.push_back("else");
|
ends.push_back("else");
|
||||||
@ -969,8 +1004,12 @@ Error ShaderPreprocessor::preprocess(State *p_state, const String &p_code, Strin
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error ShaderPreprocessor::preprocess(const String &p_code, String &r_result, String *r_error_text, List<FilePosition> *r_error_position, HashSet<Ref<ShaderInclude>> *r_includes, List<ScriptLanguage::CodeCompletionOption> *r_completion_options, IncludeCompletionFunction p_include_completion_func) {
|
Error ShaderPreprocessor::preprocess(const String &p_code, const String &p_filename, String &r_result, String *r_error_text, List<FilePosition> *r_error_position, List<Region> *r_regions, HashSet<Ref<ShaderInclude>> *r_includes, List<ScriptLanguage::CodeCompletionOption> *r_completion_options, IncludeCompletionFunction p_include_completion_func) {
|
||||||
State pp_state;
|
State pp_state;
|
||||||
|
if (!p_filename.is_empty()) {
|
||||||
|
pp_state.current_filename = p_filename;
|
||||||
|
pp_state.save_regions = r_regions != nullptr;
|
||||||
|
}
|
||||||
Error err = preprocess(&pp_state, p_code, r_result);
|
Error err = preprocess(&pp_state, p_code, r_result);
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
if (r_error_text) {
|
if (r_error_text) {
|
||||||
@ -980,6 +1019,9 @@ Error ShaderPreprocessor::preprocess(const String &p_code, String &r_result, Str
|
|||||||
*r_error_position = pp_state.include_positions;
|
*r_error_position = pp_state.include_positions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (r_regions) {
|
||||||
|
*r_regions = pp_state.regions[p_filename];
|
||||||
|
}
|
||||||
if (r_includes) {
|
if (r_includes) {
|
||||||
*r_includes = pp_state.shader_includes;
|
*r_includes = pp_state.shader_includes;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,14 @@ public:
|
|||||||
int line = 0;
|
int line = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Region {
|
||||||
|
String file;
|
||||||
|
int from_line = -1;
|
||||||
|
int to_line = -1;
|
||||||
|
bool enabled = false;
|
||||||
|
Region *parent = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Token {
|
struct Token {
|
||||||
char32_t text;
|
char32_t text;
|
||||||
@ -134,10 +142,13 @@ private:
|
|||||||
RBSet<String> includes;
|
RBSet<String> includes;
|
||||||
List<uint64_t> cyclic_include_hashes; // Holds code hash of includes.
|
List<uint64_t> cyclic_include_hashes; // Holds code hash of includes.
|
||||||
int include_depth = 0;
|
int include_depth = 0;
|
||||||
String current_include;
|
String current_filename;
|
||||||
String current_shader_type;
|
String current_shader_type;
|
||||||
String error;
|
String error;
|
||||||
List<FilePosition> include_positions;
|
List<FilePosition> include_positions;
|
||||||
|
bool save_regions = false;
|
||||||
|
RBMap<String, List<Region>> regions;
|
||||||
|
Region *previous_region = nullptr;
|
||||||
RBMap<String, Vector<SkippedCondition *>> skipped_conditions;
|
RBMap<String, Vector<SkippedCondition *>> skipped_conditions;
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
CompletionType completion_type = COMPLETION_TYPE_NONE;
|
CompletionType completion_type = COMPLETION_TYPE_NONE;
|
||||||
@ -167,6 +178,7 @@ private:
|
|||||||
void process_pragma(Tokenizer *p_tokenizer);
|
void process_pragma(Tokenizer *p_tokenizer);
|
||||||
void process_undef(Tokenizer *p_tokenizer);
|
void process_undef(Tokenizer *p_tokenizer);
|
||||||
|
|
||||||
|
void add_region(int p_line, bool p_enabled, Region *p_parent_region);
|
||||||
void start_branch_condition(Tokenizer *p_tokenizer, bool p_success);
|
void start_branch_condition(Tokenizer *p_tokenizer, bool p_success);
|
||||||
|
|
||||||
void expand_output_macros(int p_start, int p_line);
|
void expand_output_macros(int p_start, int p_line);
|
||||||
@ -188,7 +200,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
typedef void (*IncludeCompletionFunction)(List<ScriptLanguage::CodeCompletionOption> *);
|
typedef void (*IncludeCompletionFunction)(List<ScriptLanguage::CodeCompletionOption> *);
|
||||||
|
|
||||||
Error preprocess(const String &p_code, String &r_result, String *r_error_text = nullptr, List<FilePosition> *r_error_position = nullptr, HashSet<Ref<ShaderInclude>> *r_includes = nullptr, List<ScriptLanguage::CodeCompletionOption> *r_completion_options = nullptr, IncludeCompletionFunction p_include_completion_func = nullptr);
|
Error preprocess(const String &p_code, const String &p_filename, String &r_result, String *r_error_text = nullptr, List<FilePosition> *r_error_position = nullptr, List<Region> *r_regions = nullptr, HashSet<Ref<ShaderInclude>> *r_includes = nullptr, List<ScriptLanguage::CodeCompletionOption> *r_completion_options = nullptr, IncludeCompletionFunction p_include_completion_func = nullptr);
|
||||||
|
|
||||||
static void get_keyword_list(List<String> *r_keywords, bool p_include_shader_keywords);
|
static void get_keyword_list(List<String> *r_keywords, bool p_include_shader_keywords);
|
||||||
static void get_pragma_list(List<String> *r_pragmas);
|
static void get_pragma_list(List<String> *r_pragmas);
|
||||||
|
Loading…
Reference in New Issue
Block a user