mirror of
https://github.com/fltk/fltk.git
synced 2026-09-24 00:03:48 +08:00
Fluid: extend mergeback to custom code (#1322)
Build and Test / build-linux (push) Canceled after 0s
Build and Test / build-wayland (push) Canceled after 0s
Build and Test / build-wayland-arm64 (push) Canceled after 0s
Build and Test / build-macos (push) Canceled after 0s
Build and Test / build-windows (push) Canceled after 0s
Build and Test / build-windows-arm (push) Canceled after 0s
Build and Test / build-linux (push) Canceled after 0s
Build and Test / build-wayland (push) Canceled after 0s
Build and Test / build-wayland-arm64 (push) Canceled after 0s
Build and Test / build-macos (push) Canceled after 0s
Build and Test / build-windows (push) Canceled after 0s
Build and Test / build-windows-arm (push) Canceled after 0s
This commit is contained in:
@@ -832,7 +832,9 @@ void Widget_Node::write_code1(fluid::io::Code_Writer& f) {
|
||||
write_widget_code(f);
|
||||
|
||||
if (!extra_code(2).empty()) {
|
||||
f.tag(Mergeback::Tag::GENERIC, Mergeback::Tag::SETUP, 0);
|
||||
f.write_c_indented(extra_code(2), 0, '\n');
|
||||
f.tag(Mergeback::Tag::SETUP, Mergeback::Tag::GENERIC, get_uid());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1066,7 +1068,9 @@ void Widget_Node::write_block_close(fluid::io::Code_Writer& f) {
|
||||
|
||||
void Widget_Node::write_code2(fluid::io::Code_Writer& f) {
|
||||
if (!extra_code(3).empty()) {
|
||||
f.tag(Mergeback::Tag::GENERIC, Mergeback::Tag::FINALIZE, 0);
|
||||
f.write_c_indented(extra_code(3), 0, '\n');
|
||||
f.tag(Mergeback::Tag::FINALIZE, Mergeback::Tag::GENERIC, get_uid());
|
||||
}
|
||||
write_block_close(f);
|
||||
}
|
||||
|
||||
@@ -281,6 +281,29 @@ void Mergeback::analyse_code(unsigned long code_crc, unsigned long tag_crc, int
|
||||
}
|
||||
}
|
||||
|
||||
/** Analyse the block and its corresponding Code Type.
|
||||
Return findings in num_changed_code, num_changed_code, and num_uid_not_found.
|
||||
*/
|
||||
void Mergeback::analyse_extra_code(int index, unsigned long code_crc, unsigned long tag_crc, int uid) {
|
||||
Node *tp = proj_.tree.find_by_uid(uid);
|
||||
Widget_Node *wp = dynamic_cast<Widget_Node*>(tp);
|
||||
if (wp) {
|
||||
std::string code = wp->extra_code(index); code += "\n";
|
||||
unsigned long project_crc = fluid::CRC32::block(code);
|
||||
// check if the code and project crc are the same, so this modification was already applied
|
||||
if (project_crc!=code_crc) {
|
||||
num_changed_code++;
|
||||
// check if the block change on the project side as well, so we may override changes
|
||||
if (project_crc!=tag_crc) {
|
||||
num_possible_override++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
num_changed_code++;
|
||||
num_uid_not_found++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Decode a 22 bytes string of three distinct characters into a 32 bit integer.
|
||||
\param[in] text at least 22 characters '-', '~', and '='
|
||||
@@ -372,7 +395,16 @@ void Mergeback::print_tag(FILE *out, Tag prev_type, Tag next_type, uint16_t uid,
|
||||
\return The formatted tag string.
|
||||
*/
|
||||
std::string Mergeback::format_tag(Tag prev_type, Tag next_type, uint16_t uid, uint32_t crc) {
|
||||
static const char *tag_lut[] = { "----------", "-- code --", " callback ", " callback " };
|
||||
static const char *tag_lut[] = {
|
||||
"----------",
|
||||
"-- code --",
|
||||
" callback ",
|
||||
" callback ",
|
||||
"- code 0 -",
|
||||
"- code 1 -",
|
||||
"- setup --",
|
||||
" finalize "
|
||||
};
|
||||
static const char *lut[] = { "--", "-~", "~-", "~~", "-=", "=-", "~=", "=~" };
|
||||
std::string result;
|
||||
result += "//fl "; // Distinct start of tag using utf8
|
||||
@@ -390,14 +422,14 @@ std::string Mergeback::format_tag(Tag prev_type, Tag next_type, uint16_t uid, ui
|
||||
// Write a string indicating the type of editable text
|
||||
#if 0
|
||||
if ( next_type != Tag::GENERIC) {
|
||||
result += tag_lut[(nt%4)];
|
||||
result += tag_lut[(nt%((int)Tag::END_OF_LIST_))];
|
||||
} else if (prev_type != Tag::GENERIC) {
|
||||
result += tag_lut[(pt%4)];
|
||||
result += tag_lut[(pt%((int)Tag::END_OF_LIST_))];
|
||||
} else {
|
||||
result += tag_lut[0];
|
||||
}
|
||||
#else
|
||||
result += tag_lut[(nt%4)];
|
||||
result += tag_lut[(nt%((int)Tag::END_OF_LIST_))];
|
||||
#endif
|
||||
// Write the second 32 bit word as an encoded divider line
|
||||
for (int i=30; i>=0; i-=3) result += lut[(crc>>i)&7];
|
||||
@@ -473,6 +505,12 @@ int Mergeback::analyse() {
|
||||
case Tag::CODE:
|
||||
analyse_code(crc.value(), tag_crc, uid);
|
||||
break;
|
||||
case Tag::CODE0:
|
||||
case Tag::CODE1:
|
||||
case Tag::SETUP:
|
||||
case Tag::FINALIZE:
|
||||
analyse_extra_code(((int)tag_type)-((int)Tag::CODE0), crc.value(), tag_crc, uid);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -515,6 +553,23 @@ int Mergeback::apply_code(long block_end, long block_start, unsigned long code_c
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Apply callback mergebacks from the code file to the project.
|
||||
\return 1 if the project changed
|
||||
*/
|
||||
int Mergeback::apply_extra_code(int index, long block_end, long block_start, unsigned long code_crc, int uid) {
|
||||
Node *tp = proj_.tree.find_by_uid(uid);
|
||||
Widget_Node *wp = dynamic_cast<Widget_Node*>(tp);
|
||||
if (wp) {
|
||||
std::string cb = wp->extra_code(index); cb += "\n";
|
||||
uint32_t project_crc = fluid::CRC32::block(cb);
|
||||
if (project_crc!=code_crc) {
|
||||
wp->extra_code(index, read_and_unindent_block(block_start, block_end).c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Apply all possible mergebacks from the code file to the project.
|
||||
The code file must be open for reading already.
|
||||
\return -1 if reading a tag failed, 0 if nothing changed, 1 if the project changed
|
||||
@@ -557,6 +612,8 @@ int Mergeback::apply() {
|
||||
changed |= apply_callback(block_end, block_start, crc.value(), uid);
|
||||
} else if (tag_type==Tag::CODE) {
|
||||
changed |= apply_code(block_end, block_start, crc.value(), uid);
|
||||
} else if (tag_type==Tag::CODE0 || tag_type==Tag::CODE1 || tag_type==Tag::SETUP || tag_type==Tag::FINALIZE) {
|
||||
changed |= apply_extra_code(((int)tag_type)-((int)Tag::CODE0), block_end, block_start, crc.value(), uid);
|
||||
}
|
||||
}
|
||||
// reset everything for the next block
|
||||
|
||||
+11
-1
@@ -37,7 +37,15 @@ class Mergeback
|
||||
{
|
||||
public:
|
||||
enum class Tag {
|
||||
GENERIC = 0, CODE, MENU_CALLBACK, WIDGET_CALLBACK, UNUSED_
|
||||
GENERIC = 0, // Code that is auto generated and can not be edited
|
||||
CODE, // Code blocks in the Function_Node
|
||||
MENU_CALLBACK, // Code that is generated for a menu callback function
|
||||
WIDGET_CALLBACK, // Code for all other widget callbacks
|
||||
CODE0, CODE1, // Not used
|
||||
SETUP, // Code that is added at instantiation before children
|
||||
FINALIZE, // Code that is added at instantiation after children
|
||||
UNUSED_, // Mark a tag that is not used
|
||||
END_OF_LIST_ = UNUSED_
|
||||
};
|
||||
enum class Task {
|
||||
ANALYSE = 0, INTERACTIVE, APPLY, APPLY_IF_SAFE
|
||||
@@ -65,8 +73,10 @@ protected:
|
||||
std::string read_and_unindent_block(long start, long end);
|
||||
void analyse_callback(unsigned long code_crc, unsigned long tag_crc, int uid);
|
||||
void analyse_code(unsigned long code_crc, unsigned long tag_crc, int uid);
|
||||
void analyse_extra_code(int index, unsigned long code_crc, unsigned long tag_crc, int uid);
|
||||
int apply_callback(long block_end, long block_start, unsigned long code_crc, int uid);
|
||||
int apply_code(long block_end, long block_start, unsigned long code_crc, int uid);
|
||||
int apply_extra_code(int index, long block_end, long block_start, unsigned long code_crc, int uid);
|
||||
|
||||
static uint32_t decode_trichar32(const char *text);
|
||||
static void print_trichar32(FILE *out, uint32_t value);
|
||||
|
||||
Reference in New Issue
Block a user