Skip to content

Commit

Permalink
Implement hot-reloading support for ELFScript
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Oct 26, 2024
1 parent 5383d75 commit 9303b02
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 5 deletions.
17 changes: 14 additions & 3 deletions src/elf/script_elf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,27 @@ String ELFScript::get_elf_programming_language() const {

void ELFScript::set_file(const String &p_path) {
path = p_path;
source_code = FileAccess::get_file_as_bytes(path);
PackedByteArray new_source_code = FileAccess::get_file_as_bytes(path);
if (new_source_code == source_code) {
if constexpr (VERBOSE_ELFSCRIPT) {
printf("ELFScript::set_file: No changes in %s\n", path.utf8().ptr());
}
return;
}
source_code = std::move(new_source_code);

global_name = "Sandbox_" + path.get_basename().replace("res://", "").replace("/", "_").replace("-", "_").capitalize().replace(" ", "");
Sandbox::BinaryInfo info = Sandbox::get_program_info_from_binary(source_code);
info.functions.sort();
this->functions = std::move(info.functions);
this->elf_programming_language = info.language;
this->elf_api_version = info.version;

for (ELFScriptInstance *instance : instances) {
instance->reload(this);
if constexpr (VERBOSE_ELFSCRIPT) {
printf("ELFScript::set_file: %s Sandbox instances: %d\n", path.utf8().ptr(), sandbox_map[path].size());
}
for (Sandbox *sandbox : sandbox_map[path]) {
sandbox->set_program(Ref<ELFScript>(this));
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/elf/script_elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class ELFScript : public ScriptExtension {
mutable HashSet<ELFScriptInstance *> instances;
friend class ELFScriptInstance;

static inline HashMap<String, HashSet<Sandbox *>> sandbox_map;

public:
PackedStringArray functions;
String get_elf_programming_language() const;
Expand All @@ -47,6 +49,9 @@ class ELFScript : public ScriptExtension {
/// @return An ELF program as a byte array.
const PackedByteArray &get_content();

void register_instance(Sandbox *p_sandbox) { sandbox_map[path].insert(p_sandbox); }
void unregister_instance(Sandbox *p_sandbox) { sandbox_map[path].erase(p_sandbox); }

virtual bool _editor_can_reload_from_file() override;
virtual void _placeholder_erased(void *p_placeholder) override;
virtual bool _can_instantiate() const override;
Expand Down
16 changes: 14 additions & 2 deletions src/sandbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ Sandbox::~Sandbox() {
ERR_PRINT("Sandbox instance destroyed while a VM call is in progress.");
}
this->m_global_instance_count -= 1;
this->set_program_data_internal(nullptr);
try {
if (this->m_machine != dummy_machine)
delete this->m_machine;
Expand Down Expand Up @@ -244,7 +245,7 @@ void Sandbox::set_program(Ref<ELFScript> program) {
property_values.push_back(value);
}

this->m_program_data = program;
this->set_program_data_internal(program);
this->m_program_bytes = {};

// Unload program and reset the machine
Expand Down Expand Up @@ -273,6 +274,17 @@ void Sandbox::set_program(Ref<ELFScript> program) {
}
}
}
void Sandbox::set_program_data_internal(Ref<ELFScript> program) {
if (this->m_program_data.is_valid()) {
//printf("Sandbox %p: Program *unset* from %s\n", this, this->m_program_data->get_path().utf8().ptr());
this->m_program_data->unregister_instance(this);
}
this->m_program_data = program;
if (this->m_program_data.is_valid()) {
//printf("Sandbox %p: Program set to %s\n", this, this->m_program_data->get_path().utf8().ptr());
this->m_program_data->register_instance(this);
}
}
Ref<ELFScript> Sandbox::get_program() {
return m_program_data;
}
Expand All @@ -284,7 +296,7 @@ void Sandbox::load_buffer(const PackedByteArray &buffer) {
return;
}

this->m_program_data.unref();
this->set_program_data_internal(nullptr);
this->m_program_bytes = buffer;
this->load(&this->m_program_bytes);
}
Expand Down
1 change: 1 addition & 0 deletions src/sandbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ class Sandbox : public Node {
void constructor_initialize();
void full_reset();
void reset_machine();
void set_program_data_internal(Ref<ELFScript> program);
bool load(const PackedByteArray *vbuf, const std::vector<std::string> *argv = nullptr);
void read_program_properties(bool editor) const;
void handle_exception(gaddr_t);
Expand Down

0 comments on commit 9303b02

Please sign in to comment.