summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJedidiah Barber <contact@jedbarber.id.au>2024-10-13 03:33:38 +1300
committerJedidiah Barber <contact@jedbarber.id.au>2024-10-13 03:33:38 +1300
commitb4090a7acddf951088b75fcce0d6edb721bbbf45 (patch)
tree6770ea43f82e114c188538213f77e76b4eb5da10 /src
parent87671a2f2423efacd0b0c4ad0c34c244680ef565 (diff)
Fixed bug with Text_Buffers not being deallocated correctly if declared after the Text_Display they are attached to
Diffstat (limited to 'src')
-rw-r--r--src/c_fl_text_buffer.cpp21
-rw-r--r--src/c_fl_text_buffer.h1
-rw-r--r--src/fltk-widgets-groups-text_displays-text_editors.adb1
-rw-r--r--src/fltk-widgets-groups-text_displays.adb6
-rw-r--r--src/fltk-widgets-groups-text_displays.ads16
5 files changed, 43 insertions, 2 deletions
diff --git a/src/c_fl_text_buffer.cpp b/src/c_fl_text_buffer.cpp
index 2df65f6..4a681e8 100644
--- a/src/c_fl_text_buffer.cpp
+++ b/src/c_fl_text_buffer.cpp
@@ -6,13 +6,30 @@
+class My_Text_Buffer : public Fl_Text_Buffer {
+ public:
+ using Fl_Text_Buffer::Fl_Text_Buffer;
+ int reference_count = 0;
+};
+
+
+
+
TEXTBUFFER new_fl_text_buffer(int rs, int pgs) {
- Fl_Text_Buffer *tb = new Fl_Text_Buffer(rs, pgs);
+ My_Text_Buffer *tb = new My_Text_Buffer(rs, pgs);
return tb;
}
+void upref_fl_text_buffer(TEXTBUFFER tb) {
+ reinterpret_cast<My_Text_Buffer*>(tb)->reference_count += 1;
+}
+
void free_fl_text_buffer(TEXTBUFFER tb) {
- delete reinterpret_cast<Fl_Text_Buffer*>(tb);
+ if (reinterpret_cast<My_Text_Buffer*>(tb)->reference_count <= 0) {
+ delete reinterpret_cast<My_Text_Buffer*>(tb);
+ } else {
+ reinterpret_cast<My_Text_Buffer*>(tb)->reference_count -= 1;
+ }
}
diff --git a/src/c_fl_text_buffer.h b/src/c_fl_text_buffer.h
index 7258006..d808f44 100644
--- a/src/c_fl_text_buffer.h
+++ b/src/c_fl_text_buffer.h
@@ -12,6 +12,7 @@ typedef void* TEXTBUFFER;
extern "C" TEXTBUFFER new_fl_text_buffer(int rs, int pgs);
+extern "C" void upref_fl_text_buffer(TEXTBUFFER tb);
extern "C" void free_fl_text_buffer(TEXTBUFFER tb);
diff --git a/src/fltk-widgets-groups-text_displays-text_editors.adb b/src/fltk-widgets-groups-text_displays-text_editors.adb
index e0d4588..98175a6 100644
--- a/src/fltk-widgets-groups-text_displays-text_editors.adb
+++ b/src/fltk-widgets-groups-text_displays-text_editors.adb
@@ -388,6 +388,7 @@ package body FLTK.Widgets.Groups.Text_Displays.Text_Editors is
then
This.Clear;
free_fl_text_editor (This.Void_Ptr);
+ free_fl_text_buffer (This.Raw_Buffer);
This.Void_Ptr := Null_Pointer;
end if;
Finalize (Text_Display (This));
diff --git a/src/fltk-widgets-groups-text_displays.adb b/src/fltk-widgets-groups-text_displays.adb
index 59efc55..3dd9f6d 100644
--- a/src/fltk-widgets-groups-text_displays.adb
+++ b/src/fltk-widgets-groups-text_displays.adb
@@ -470,6 +470,7 @@ package body FLTK.Widgets.Groups.Text_Displays is
then
This.Clear;
free_fl_text_display (This.Void_Ptr);
+ free_fl_text_buffer (This.Raw_Buffer);
This.Void_Ptr := Null_Pointer;
end if;
Finalize (Group (This));
@@ -546,6 +547,11 @@ package body FLTK.Widgets.Groups.Text_Displays is
begin
This.Buffer := Buff'Unchecked_Access;
fl_text_display_set_buffer (This.Void_Ptr, Wrapper (Buff).Void_Ptr);
+ if This.Raw_Buffer /= Null_Pointer then
+ free_fl_text_buffer (This.Raw_Buffer);
+ end if;
+ This.Raw_Buffer := Wrapper (Buff).Void_Ptr;
+ upref_fl_text_buffer (This.Raw_Buffer);
end Set_Buffer;
diff --git a/src/fltk-widgets-groups-text_displays.ads b/src/fltk-widgets-groups-text_displays.ads
index 609561e..76cff42 100644
--- a/src/fltk-widgets-groups-text_displays.ads
+++ b/src/fltk-widgets-groups-text_displays.ads
@@ -359,6 +359,7 @@ private
type Text_Display is new Group with
record
Buffer : access FLTK.Text_Buffers.Text_Buffer;
+ Raw_Buffer : Storage.Integer_Address := Null_Pointer;
Style_Callback : Styles.Unfinished_Style_Callback;
end record;
@@ -373,6 +374,21 @@ private
+ -- Adds some basic reference counting on the C side to help ensure any Text_Buffers
+ -- do not get deallocated before all Text_Displays they might be attached to.
+ procedure upref_fl_text_buffer
+ (TB : in Storage.Integer_Address);
+ pragma Import (C, upref_fl_text_buffer, "upref_fl_text_buffer");
+ pragma Inline (upref_fl_text_buffer);
+
+ procedure free_fl_text_buffer
+ (TB : in Storage.Integer_Address);
+ pragma Import (C, free_fl_text_buffer, "free_fl_text_buffer");
+ pragma Inline (free_fl_text_buffer);
+
+
+
+
pragma Inline (Get_Buffer);
pragma Inline (Set_Buffer);