aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremias Stotter <jeremias@stotter.eu>2024-01-01 23:03:58 +0100
committerJeremias Stotter <jeremias@stotter.eu>2024-01-01 23:03:58 +0100
commit547f8cbd600ccb6cf7991a66dac7abcc784f949a (patch)
treeadaade22369af25da37507266b07e04a5f3cbbd3
parent3cf277161a376bf3257731edcf9981be413d2df2 (diff)
downloadnetwork-simulator-547f8cbd600ccb6cf7991a66dac7abcc784f949a.tar.gz
network-simulator-547f8cbd600ccb6cf7991a66dac7abcc784f949a.tar.bz2
network-simulator-547f8cbd600ccb6cf7991a66dac7abcc784f949a.zip
Added the ability to reaload the devices kernel on the fly
Used to have to recreate the devices or restart the program, biw can be done in the menu bar under "Development"
-rw-r--r--device.c60
-rw-r--r--device.h1
-rw-r--r--gui.c16
-rw-r--r--shared.h2
4 files changed, 56 insertions, 23 deletions
diff --git a/device.c b/device.c
index 0a82bb4..ca1e646 100644
--- a/device.c
+++ b/device.c
@@ -31,10 +31,10 @@
struct device* start_device = NULL;
-void dev_register_lua_function(struct device* dev, char* name, lua_CFunction fn) {
- lua_pushlightuserdata(dev->lua_vm, dev);
- lua_pushcclosure(dev->lua_vm, fn, 1);
- lua_setglobal(dev->lua_vm, name);
+void dev_register_lua_function(lua_State* lua_vm, struct device* dev, char* name, lua_CFunction fn) {
+ lua_pushlightuserdata(lua_vm, dev);
+ lua_pushcclosure(lua_vm, fn, 1);
+ lua_setglobal(lua_vm, name);
}
void rename_device(struct device* dev, const char* name) {
@@ -154,9 +154,9 @@ int lua_append_cmdline(lua_State* lua_vm) {
// Setup all the device specific lua stuff
void setup_dev_lua(lua_State *lua_vm, struct device* setup_device) {
- dev_register_lua_function(setup_device, "send_frame", device_send_frame_lua);
- dev_register_lua_function(setup_device, "get_interface", device_get_interface);
- dev_register_lua_function(setup_device, "nsprint", lua_append_cmdline);
+ dev_register_lua_function(lua_vm, setup_device, "send_frame", device_send_frame_lua);
+ dev_register_lua_function(lua_vm, setup_device, "get_interface", device_get_interface);
+ dev_register_lua_function(lua_vm, setup_device, "nsprint", lua_append_cmdline);
lua_pushinteger(lua_vm, setup_device->template->slots);
lua_setglobal(lua_vm, "NS_SLOTS_N");
}
@@ -202,6 +202,19 @@ struct device* new_device_from_template_name(struct device** start, char* device
return new_device(start, device_name, cur_template, create_interfaces);
}
+lua_State* init_dev_lua_state(struct device* dev) {
+ lua_State *lua_vm = luaL_newstate();
+ luaL_openlibs(lua_vm);
+ setup_dev_lua(lua_vm, dev);
+ register_lua_helpers(lua_vm);
+ if(!dev->template->kernel) {
+ fprintf(stderr, "This device has no kernel\n");
+ } else if(luaL_dofile(lua_vm, dev->template->kernel) != 0) {
+ fprintf(stderr, "LUA ERROR: %s\n", lua_tostring(lua_vm, -1));
+ }
+ return lua_vm;
+}
+
// Make sure that when this function is called device_name will stay allocated
// start_device is the first device in the linked list of all devices or 0 when
// this is the first device
@@ -243,17 +256,8 @@ struct device* new_device(struct device** start, char* device_name, struct dev_t
append_device(start, new_device);
// initiate lua vm for this device
- lua_State *lua_vm = luaL_newstate();
- new_device->lua_vm = lua_vm;
- luaL_openlibs(lua_vm);
- setup_dev_lua(lua_vm, new_device);
- register_lua_helpers(lua_vm);
- if(!new_device->template->kernel) {
- fprintf(stderr, "This device has no kernel\n");
- } else if(luaL_dofile(lua_vm, new_device->template->kernel) != 0) {
- fprintf(stderr, "LUA ERROR: %s\n", lua_tostring(lua_vm, -1));
- }
-
+ new_device->lua_vm = init_dev_lua_state(new_device);
+
return new_device;
}
@@ -344,3 +348,23 @@ struct device* dev_from_name(struct device* start, const char* name) {
}
return NULL;
}
+
+// Reload all the templates lua files
+void reload_templates() {
+ LL_FOR(struct device, start_device, dev) {
+ // Ask the device to save
+ if(my_lua_call(dev->lua_vm, "save_state", 1, -1)) {
+ size_t state_len = 0;
+ const char* state = lua_tolstring(dev->lua_vm, -1, &state_len);
+
+ // Destroy the lua vm
+ lua_close(dev->lua_vm);
+ // Create the new vm
+ dev->lua_vm = init_dev_lua_state(dev);
+ // Load the state in
+
+ my_lua_call(dev->lua_vm, "load_state", 1, LUA_TSTRING, state_len, state, -1);
+ }
+ }
+ // @todo also add something like this for interfaces
+}
diff --git a/device.h b/device.h
index 9af6cd9..23e85ac 100644
--- a/device.h
+++ b/device.h
@@ -28,4 +28,5 @@ int device_cmdline(struct device* target_device, const char* cmdline);
void append_cmdline(struct device* dev, const char* in_string, int in_string_len);
struct device* dev_from_name(struct device* start, const char* name);
void append_cmd_history(struct device* dev, const char* text);
+void reload_templates();
#endif
diff --git a/gui.c b/gui.c
index e3d9c88..09bca3a 100644
--- a/gui.c
+++ b/gui.c
@@ -1553,6 +1553,10 @@ void gui_toggle_interface_nums_action(GSimpleAction* action, GVariant* value, gp
gtk_widget_queue_draw(main_drawing_area);
}
+void gui_reload_templates(GSimpleAction* action, GVariant* value, gpointer user_data) {
+ reload_templates();
+}
+
void packet_list_item_text_factory_bind(GtkSignalListItemFactory* self, GObject* object, gpointer user_data) {
gtk_list_item_set_child(GTK_LIST_ITEM(object), gtk_label_new(g_object_get_data(gtk_list_item_get_item(GTK_LIST_ITEM(object)), user_data)));
}
@@ -1683,9 +1687,9 @@ void activate_main_window(GtkApplication* app, gpointer user_data) {
{ "select-all", gui_select_all_action, NULL, NULL, NULL},
{ "print", gui_print_action, NULL, NULL, NULL },
// View menu entries
- { "toggle-interface-nums", gui_toggle_interface_nums_action, NULL, "true", NULL}
-
-
+ { "toggle-interface-nums", gui_toggle_interface_nums_action, NULL, "true", NULL},
+ // Dev menu entries
+ { "reload-templates", gui_reload_templates, NULL, NULL, NULL}
};
g_action_map_add_action_entries(G_ACTION_MAP(window), netsim_actions, G_N_ELEMENTS(netsim_actions), NULL);
@@ -1707,6 +1711,9 @@ void activate_main_window(GtkApplication* app, gpointer user_data) {
g_menu_append(G_MENU(view_menu), "Show interface indexes", "win.toggle-interface-nums");
+ GMenu* dev_menu = g_menu_new();
+ g_menu_append(G_MENU(dev_menu), "Reload Templates", "win.reload-templates");
+
struct {
const char* action;
const char* keys[2];
@@ -1729,7 +1736,8 @@ void activate_main_window(GtkApplication* app, gpointer user_data) {
GMenu* menu_bar_menu = g_menu_new();
g_menu_append_submenu(G_MENU(menu_bar_menu), "File", G_MENU_MODEL(file_menu));
g_menu_append_submenu(G_MENU(menu_bar_menu), "View", G_MENU_MODEL(view_menu));
-
+ g_menu_append_submenu(G_MENU(menu_bar_menu), "Development", G_MENU_MODEL(dev_menu));
+
GtkWidget* menu_bar = gtk_popover_menu_bar_new_from_model(G_MENU_MODEL(menu_bar_menu));
gtk_box_append(GTK_BOX(window_box), menu_bar);
diff --git a/shared.h b/shared.h
index 09c38fb..f02c0a4 100644
--- a/shared.h
+++ b/shared.h
@@ -84,7 +84,7 @@ struct dev_template {
int slots;
// The default interfaces, an array of strings containing the names with the size slots
char** interfaces;
- // The code of the device loaded in memory
+ // The path to the lua file
const char* kernel;
// The path of the icon
char* icon_path;
Jeremias Stotters git repositories generated by CGIT