diff --git a/.gitignore b/.gitignore index b3d95c0..c68b731 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ out/ splashkit/ generated/ __pycache__/ +_framework/ \ No newline at end of file diff --git a/Browser_IDE/CSharpWasm/bin/CSharpWasm.dll b/Browser_IDE/CSharpWasm/bin/CSharpWasm.dll new file mode 100644 index 0000000..3c0fa1d Binary files /dev/null and b/Browser_IDE/CSharpWasm/bin/CSharpWasm.dll differ diff --git a/Browser_IDE/CSharpWasm/bin/System.Console.dll b/Browser_IDE/CSharpWasm/bin/System.Console.dll new file mode 100755 index 0000000..486ae0f Binary files /dev/null and b/Browser_IDE/CSharpWasm/bin/System.Console.dll differ diff --git a/Browser_IDE/CSharpWasm/bin/System.Private.CoreLib.dll b/Browser_IDE/CSharpWasm/bin/System.Private.CoreLib.dll new file mode 100755 index 0000000..ffa92d2 Binary files /dev/null and b/Browser_IDE/CSharpWasm/bin/System.Private.CoreLib.dll differ diff --git a/Browser_IDE/CSharpWasm/bin/System.Runtime.dll b/Browser_IDE/CSharpWasm/bin/System.Runtime.dll new file mode 100755 index 0000000..0e2db79 Binary files /dev/null and b/Browser_IDE/CSharpWasm/bin/System.Runtime.dll differ diff --git a/Browser_IDE/CSharpWasm/bin/mscorlib.dll b/Browser_IDE/CSharpWasm/bin/mscorlib.dll new file mode 100755 index 0000000..f79abde Binary files /dev/null and b/Browser_IDE/CSharpWasm/bin/mscorlib.dll differ diff --git a/Browser_IDE/CSharpWasm/bin/netstandard.dll b/Browser_IDE/CSharpWasm/bin/netstandard.dll new file mode 100755 index 0000000..fd34bf9 Binary files /dev/null and b/Browser_IDE/CSharpWasm/bin/netstandard.dll differ diff --git a/Browser_IDE/CSharpWasm/main.js b/Browser_IDE/CSharpWasm/main.js new file mode 100644 index 0000000..b8b414d --- /dev/null +++ b/Browser_IDE/CSharpWasm/main.js @@ -0,0 +1,71 @@ +import { dotnet } from "./wwwroot/_framework/dotnet.js"; +import methods from "./splashKitMethods.generated.js"; + +const parseMethods = (methods) => { + const methodList = methods + .split(",") + .map((method) => method.trim().replace("\n", "")) + .filter(Boolean); + + const bindingsFunctions = {}; + + for (const name of methodList) { + try { + bindingsFunctions[name] = eval(name); + } catch (e) { + console.warn(e); + } + } + + return bindingsFunctions; +}; + +const loadDotNet = async () => { + const { setModuleImports, getAssemblyExports, getConfig } = await dotnet + .withDiagnosticTracing(false) + .withApplicationArgumentsFromQuery() + .create(); + + const skFunctions = parseMethods(methods); + + setModuleImports("main.js", { + window: { + location: { + href: () => globalThis.window.location.href, + }, + }, + SplashKitBackendWASM: skFunctions, + }); + + const config = getConfig(); + const exports = await getAssemblyExports(config.mainAssemblyName); + return exports; +}; + +const CompileAndRun = async (code, reportError) => { + try { + const exports = await loadDotNet(); + const result = await exports.CSharpCodeRunner.CompileAndRun(code); + if (result.includes("Compilation failed")) { + const errors = result.split(":"); + const errorLine = errors[1].split("Line"); + + const indexCorrector = 1; + const filePath = "__USERCODE__/code/main.cs"; + reportError( + filePath, + result, + Number(errorLine[1]) + indexCorrector, + null, + true, + ); + } + } catch (error) { + console.error("Error during code execution:", error); + } +}; + +// This event will be trigger by the csharp compiler +document.addEventListener("compileAndRun", (ev) => { + CompileAndRun(ev.detail.program[0].source, ev.detail.reportError); +}); diff --git a/Browser_IDE/CSharpWasm/splashKitMethods.generated.js b/Browser_IDE/CSharpWasm/splashKitMethods.generated.js new file mode 100644 index 0000000..4e41d20 --- /dev/null +++ b/Browser_IDE/CSharpWasm/splashKitMethods.generated.js @@ -0,0 +1,912 @@ +const methods = ` + accept_all_new_connections, + accept_new_connection, + add_column, + add_column_relative, + alpha_of, + angle_between, + animation_count, + animation_current_cell, + animation_current_vector, + animation_ended, + animation_entered_frame, + animation_frame_time, + animation_index, + animation_name, + animation_script_name, + animation_script_named, + any_key_pressed, + apply_matrix, + assign_animation, + audio_ready, + base64_decode, + base64_encode, + bin_to_dec, + bin_to_hex, + bin_to_oct, + bitmap_bounding_circle, + bitmap_bounding_rectangle, + bitmap_button, + bitmap_cell_center, + bitmap_cell_circle, + bitmap_cell_columns, + bitmap_cell_count, + bitmap_cell_height, + bitmap_cell_offset, + bitmap_cell_rectangle, + bitmap_cell_rows, + bitmap_cell_width, + bitmap_center, + bitmap_circle_collision, + bitmap_collision, + bitmap_filename, + bitmap_height, + bitmap_name, + bitmap_named, + bitmap_point_collision, + bitmap_quad_collision, + bitmap_ray_collision, + bitmap_rectangle_collision, + bitmap_rectangle_of_cell, + bitmap_set_cell_details, + bitmap_triangle_collision, + bitmap_valid, + bitmap_width, + blue_of, + brightness_of, + broadcast_message, + button, + calculate_collision_direction, + call_for_all_sprites, + call_on_sprite_event, + camera_position, + camera_x, + camera_y, + center_camera_on, + center_point, + check_network_activity, + checkbox, + circle_at, + circle_quad_intersect, + circle_radius, + circle_ray_intersection, + circle_triangle_intersect, + circle_x, + circle_y, + circles_intersect, + clear_bitmap, + clear_messages, + clear_screen, + clear_window, + close_all_connections, + close_all_servers, + close_all_windows, + close_audio, + close_connection, + close_current_window, + close_log_process, + close_message, + close_server, + close_window, + closest_point_on_circle, + closest_point_on_line, + closest_point_on_line_from_circle, + closest_point_on_lines, + closest_point_on_rect_from_circle, + closest_point_on_triangle_from_circle, + color_alice_blue, + color_antique_white, + color_aqua, + color_aquamarine, + color_azure, + color_beige, + color_bisque, + color_black, + color_blanched_almond, + color_blue, + color_blue_violet, + color_bright_green, + color_brown, + color_burly_wood, + color_cadet_blue, + color_chartreuse, + color_chocolate, + color_coral, + color_cornflower_blue, + color_cornsilk, + color_crimson, + color_cyan, + color_dark_blue, + color_dark_cyan, + color_dark_goldenrod, + color_dark_gray, + color_dark_green, + color_dark_khaki, + color_dark_magenta, + color_dark_olive_green, + color_dark_orange, + color_dark_orchid, + color_dark_red, + color_dark_salmon, + color_dark_sea_green, + color_dark_slate_blue, + color_dark_slate_gray, + color_dark_turquoise, + color_dark_violet, + color_deep_pink, + color_deep_sky_blue, + color_dim_gray, + color_dodger_blue, + color_firebrick, + color_floral_white, + color_forest_green, + color_fuchsia, + color_gainsboro, + color_ghost_white, + color_gold, + color_goldenrod, + color_gray, + color_green, + color_green_yellow, + color_honeydew, + color_hot_pink, + color_indian_red, + color_indigo, + color_ivory, + color_khaki, + color_lavender, + color_lavender_blush, + color_lawn_green, + color_lemon_chiffon, + color_light_blue, + color_light_coral, + color_light_cyan, + color_light_goldenrod_yellow, + color_light_gray, + color_light_green, + color_light_pink, + color_light_salmon, + color_light_sea_green, + color_light_sky_blue, + color_light_slate_gray, + color_light_steel_blue, + color_light_yellow, + color_lime, + color_lime_green, + color_linen, + color_magenta, + color_maroon, + color_medium_aquamarine, + color_medium_blue, + color_medium_orchid, + color_medium_purple, + color_medium_sea_green, + color_medium_slate_blue, + color_medium_spring_green, + color_medium_turquoise, + color_medium_violet_red, + color_midnight_blue, + color_mint_cream, + color_misty_rose, + color_moccasin, + color_navajo_white, + color_navy, + color_old_lace, + color_olive, + color_olive_drab, + color_orange, + color_orange_red, + color_orchid, + color_pale_goldenrod, + color_pale_green, + color_pale_turquoise, + color_pale_violet_red, + color_papaya_whip, + color_peach_puff, + color_peru, + color_pink, + color_plum, + color_powder_blue, + color_purple, + color_red, + color_rosy_brown, + color_royal_blue, + color_saddle_brown, + color_salmon, + color_sandy_brown, + color_sea_green, + color_sea_shell, + color_sienna, + color_silver, + color_sky_blue, + color_slate_blue, + color_slate_gray, + color_slider, + color_snow, + color_spring_green, + color_steel_blue, + color_swinburne_red, + color_tan, + color_teal, + color_thistle, + color_to_string, + color_tomato, + color_transparent, + color_turquoise, + color_violet, + color_wheat, + color_white, + color_white_smoke, + color_yellow, + color_yellow_green, + connection_count, + connection_ip, + connection_named, + connection_port, + contains, + convert_to_double, + convert_to_integer, + cosine, + create_animation, + create_bitmap, + create_json, + create_server, + create_sprite, + create_sprite_pack, + create_timer, + current_clip, + current_sprite_pack, + current_ticks, + current_window, + current_window_has_border, + current_window_height, + current_window_is_fullscreen, + current_window_position, + current_window_toggle_border, + current_window_toggle_fullscreen, + current_window_width, + current_window_x, + current_window_y, + dec_to_bin, + dec_to_hex, + dec_to_ipv4, + dec_to_oct, + delay, + deregister_callback_on_key_down, + deregister_callback_on_key_typed, + deregister_callback_on_key_up, + deregister_free_notifier, + disable_interface, + display_details, + display_dialog, + display_height, + display_name, + display_width, + display_x, + display_y, + distant_point_on_circle, + distant_point_on_circle_heading, + dot_product, + download_bitmap, + download_font, + download_music, + download_sound_effect, + draw_all_sprites, + draw_bitmap, + draw_bitmap_on_bitmap, + draw_bitmap_on_window, + draw_circle, + draw_circle_on_bitmap, + draw_circle_on_window, + draw_collected_text, + draw_ellipse, + draw_ellipse_on_bitmap, + draw_ellipse_on_window, + draw_interface, + draw_line, + draw_line_on_bitmap, + draw_line_on_window, + draw_pixel, + draw_pixel_on_bitmap, + draw_pixel_on_window, + draw_quad, + draw_quad_on_bitmap, + draw_quad_on_window, + draw_rectangle, + draw_rectangle_on_bitmap, + draw_rectangle_on_window, + draw_sprite, + draw_text, + draw_text_on_bitmap, + draw_text_on_window, + draw_triangle, + draw_triangle_on_bitmap, + draw_triangle_on_window, + enable_interface, + end_inset, + end_panel, + end_popup, + end_reading_text, + end_treenode, + enter_column, + fade_all_sound_effects_out, + fade_music_in, + fade_music_out, + fade_sound_effect_out, + fetch_new_connection, + file_as_string, + fill_circle, + fill_circle_on_bitmap, + fill_circle_on_window, + fill_ellipse, + fill_ellipse_on_bitmap, + fill_ellipse_on_window, + fill_quad, + fill_quad_on_bitmap, + fill_quad_on_window, + fill_rectangle, + fill_rectangle_on_bitmap, + fill_rectangle_on_window, + fill_triangle, + fill_triangle_on_bitmap, + fill_triangle_on_window, + font_has_size, + font_load_size, + font_named, + free_all_animation_scripts, + free_all_bitmaps, + free_all_fonts, + free_all_json, + free_all_music, + free_all_sound_effects, + free_all_sprites, + free_all_timers, + free_animation, + free_animation_script, + free_bitmap, + free_font, + free_json, + free_music, + free_resource_bundle, + free_response, + free_sound_effect, + free_sprite, + free_sprite_pack, + free_timer, + get_font_style, + get_interface_label_width, + get_pixel, + get_pixel_from_window, + get_system_font, + greatest_common_divisor, + green_of, + has_animation_named, + has_animation_script, + has_bitmap, + has_connection, + has_font, + has_gpio, + has_incoming_requests, + has_messages, + has_music, + has_new_connections, + has_resource_bundle, + has_server, + has_sound_effect, + has_sprite, + has_sprite_pack, + has_timer, + has_window, + header, + hex_str_to_ipv4, + hex_to_bin, + hex_to_dec, + hex_to_dec_string, + hex_to_mac, + hex_to_oct, + hide_mouse, + hsb_color, + hsb_color_slider, + http_get, + http_post, + http_response_to_string, + hue_of, + identity_matrix, + index_of, + init_custom_logger, + inset_rectangle, + interface_enabled, + interface_style_panel, + intersection, + ipv4_to_dec, + ipv4_to_hex, + is_binary, + is_connection_open, + is_current_window, + is_delete_request_for, + is_double, + is_get_request_for, + is_hex, + is_integer, + is_number, + is_octal, + is_options_request_for, + is_post_request_for, + is_prime_number, + is_put_request_for, + is_request_for, + is_trace_request_for, + is_valid_ipv4, + is_valid_mac, + is_zero_vector, + json_count_keys, + json_from_color, + json_from_file, + json_from_string, + json_has_key, + json_read_array, + json_read_bool, + json_read_number, + json_read_number_as_double, + json_read_number_as_int, + json_read_object, + json_read_string, + json_set_array, + json_set_bool, + json_set_number, + json_set_object, + json_set_string, + json_to_color, + json_to_file, + json_to_string, + key_down, + key_name, + key_released, + key_typed, + key_up, + label_element, + last_connection, + last_element_changed, + last_element_confirmed, + least_common_multiple, + leave_column, + length_of, + line_from, + line_intersection_point, + line_intersects_circle, + line_intersects_lines, + line_intersects_rect, + line_length, + line_length_squared, + line_mid_point, + line_normal, + line_to_string, + lines_from, + lines_intersect, + load_animation_script, + load_bitmap, + load_font, + load_music, + load_resource_bundle, + load_sound_effect, + log, + mac_to_hex, + matrix_inverse, + matrix_multiply, + matrix_to_string, + message_connection, + message_count, + message_data, + message_data_bytes, + message_host, + message_port, + message_protocol, + mouse_clicked, + mouse_down, + mouse_movement, + mouse_position, + mouse_position_vector, + mouse_shown, + mouse_up, + mouse_wheel_scroll, + mouse_x, + mouse_y, + move_camera_by, + move_camera_to, + move_current_window_to, + move_mouse, + move_sprite, + move_sprite_to, + move_window_to, + music_filename, + music_name, + music_named, + music_playing, + music_valid, + music_volume, + my_ip, + name_for_connection, + new_connection_count, + next_web_request, + number_box, + number_of_displays, + oct_to_bin, + oct_to_dec, + oct_to_hex, + open_audio, + open_connection, + open_popup, + open_window, + option_defaults, + option_draw_to, + option_flip_x, + option_flip_xy, + option_flip_y, + option_line_width, + option_part_bmp, + option_rotate_bmp, + option_scale_bmp, + option_to_screen, + option_to_world, + option_with_animation, + option_with_bitmap_cell, + paragraph, + path_to_resource, + path_to_resources, + pause_music, + pause_timer, + pixel_drawn_at_point, + play_music, + play_sound_effect, + point_at, + point_at_origin, + point_in_circle, + point_in_quad, + point_in_rectangle, + point_in_triangle, + point_in_window, + point_line_distance, + point_offset_by, + point_offset_from_origin, + point_on_line, + point_on_screen, + point_point_angle, + point_point_distance, + point_to_string, + pop_clip, + process_events, + push_clip, + quad_from, + quad_ray_intersection, + quads_intersect, + quit_requested, + random_bitmap_point, + random_color, + random_rgb_color, + random_screen_point, + random_window_point, + raspi_cleanup, + raspi_get_mode, + raspi_init, + raspi_read, + raspi_set_mode, + raspi_set_pull_up_down, + raspi_set_pwm_dutycycle, + raspi_set_pwm_frequency, + raspi_set_pwm_range, + raspi_spi_close, + raspi_spi_open, + raspi_spi_transfer, + raspi_write, + ray_circle_intersect_distance, + ray_intersection_point, + read_char, + read_line, + read_message, + read_message_data, + reading_text, + reconnect, + rect_in_window, + rect_on_screen, + rectangle_around, + rectangle_bottom, + rectangle_center, + rectangle_circle_intersect, + rectangle_from, + rectangle_left, + rectangle_offset_by, + rectangle_ray_intersection, + rectangle_right, + rectangle_to_string, + rectangle_top, + rectangles_intersect, + red_of, + refresh_screen, + refresh_window, + register_callback_on_key_down, + register_callback_on_key_typed, + register_callback_on_key_up, + register_free_notifier, + release_all_connections, + remote_raspi_cleanup, + remote_raspi_get_mode, + remote_raspi_init, + remote_raspi_read, + remote_raspi_set_mode, + remote_raspi_set_pull_up_down, + remote_raspi_set_pwm_dutycycle, + remote_raspi_set_pwm_frequency, + remote_raspi_set_pwm_range, + remote_raspi_write, + replace_all, + request_body, + request_has_query_parameter, + request_headers, + request_method, + request_query_parameter, + request_query_string, + request_uri, + request_uri_stubs, + reset_clip, + reset_layout, + reset_new_connection_count, + reset_quit, + reset_timer, + resize_current_window, + resize_window, + resolve_collision, + restart_animation, + resume_music, + resume_timer, + retrieve_connection, + rgb_color, + rgba_color, + rnd, + rotation_matrix, + same_point, + saturation_of, + save_bitmap, + save_response_to_file, + scale_matrix, + scale_rotate_translate_matrix, + screen_center, + screen_height, + screen_rectangle, + screen_width, + select_sprite_pack, + send_css_file_response, + send_file_response, + send_html_file_response, + send_javascript_file_response, + send_message_to, + send_response, + server_has_new_connection, + server_named, + set_camera_position, + set_camera_x, + set_camera_y, + set_clip, + set_current_window, + set_font_style, + set_interface_accent_color, + set_interface_border_color, + set_interface_colors_auto, + set_interface_element_color, + set_interface_element_shadows, + set_interface_font, + set_interface_font_size, + set_interface_label_width, + set_interface_panel_shadows, + set_interface_root_text_color, + set_interface_shadows, + set_interface_spacing, + set_interface_style, + set_interface_text_color, + set_layout_height, + set_music_volume, + set_quad_point, + set_resources_path, + set_udp_packet_size, + setup_collision_mask, + show_mouse, + sine, + single_line_layout, + slider, + sound_effect_filename, + sound_effect_name, + sound_effect_named, + sound_effect_playing, + sound_effect_valid, + split, + split_into_columns, + split_into_columns_relative, + split_uri_stubs, + sprite_add_layer, + sprite_add_to_velocity, + sprite_add_value, + sprite_anchor_point, + sprite_anchor_position, + sprite_animation_has_ended, + sprite_animation_name, + sprite_at, + sprite_bitmap_collision, + sprite_bring_layer_forward, + sprite_bring_layer_to_front, + sprite_call_on_event, + sprite_center_point, + sprite_circle, + sprite_circle_collision, + sprite_collision, + sprite_collision_bitmap, + sprite_collision_circle, + sprite_collision_kind, + sprite_collision_rectangle, + sprite_current_cell, + sprite_current_cell_rectangle, + sprite_dx, + sprite_dy, + sprite_has_value, + sprite_heading, + sprite_height, + sprite_hide_layer, + sprite_layer, + sprite_layer_circle, + sprite_layer_count, + sprite_layer_height, + sprite_layer_index, + sprite_layer_name, + sprite_layer_offset, + sprite_layer_rectangle, + sprite_layer_width, + sprite_location_matrix, + sprite_mass, + sprite_move_from_anchor_point, + sprite_move_to, + sprite_name, + sprite_named, + sprite_offscreen, + sprite_on_screen_at, + sprite_point_collision, + sprite_position, + sprite_quad_collision, + sprite_ray_collision, + sprite_rectangle_collision, + sprite_replay_animation, + sprite_rotation, + sprite_scale, + sprite_screen_rectangle, + sprite_send_layer_backward, + sprite_send_layer_to_back, + sprite_set_anchor_point, + sprite_set_collision_bitmap, + sprite_set_collision_kind, + sprite_set_dx, + sprite_set_dy, + sprite_set_heading, + sprite_set_layer_offset, + sprite_set_mass, + sprite_set_move_from_anchor_point, + sprite_set_position, + sprite_set_rotation, + sprite_set_scale, + sprite_set_speed, + sprite_set_value, + sprite_set_velocity, + sprite_set_x, + sprite_set_y, + sprite_show_layer, + sprite_speed, + sprite_start_animation, + sprite_stop_calling_on_event, + sprite_toggle_layer_visible, + sprite_triangle_collision, + sprite_value, + sprite_value_count, + sprite_velocity, + sprite_visible_index_of_layer, + sprite_visible_layer, + sprite_visible_layer_count, + sprite_visible_layer_id, + sprite_width, + sprite_x, + sprite_y, + square_root, + start_custom_layout, + start_inset, + start_panel, + start_popup, + start_reading_text, + start_timer, + start_treenode, + start_web_server, + stop_calling_on_sprite_event, + stop_music, + stop_sound_effect, + stop_timer, + stop_web_server, + string_to_color, + take_screenshot, + tangent, + tangent_points, + terminal_has_input, + text_box, + text_entry_cancelled, + text_height, + text_input, + text_width, + timer_named, + timer_paused, + timer_started, + timer_ticks, + to_lowercase, + to_screen, + to_screen_x, + to_screen_y, + to_uppercase, + to_world, + to_world_x, + to_world_y, + translation_matrix, + triangle_barycenter, + triangle_from, + triangle_quad_intersect, + triangle_ray_intersection, + triangle_rectangle_intersect, + triangle_to_string, + triangles_from, + triangles_intersect, + trim, + udp_packet_size, + unit_vector, + update_all_sprites, + update_animation, + update_sprite, + update_sprite_animation, + vector_add, + vector_angle, + vector_from_angle, + vector_from_center_sprite_to_point, + vector_from_line, + vector_from_point_to_rect, + vector_from_to, + vector_in_rect, + vector_invert, + vector_limit, + vector_magnitude, + vector_magnitude_squared, + vector_multiply, + vector_normal, + vector_out_of_circle_from_circle, + vector_out_of_circle_from_point, + vector_out_of_rect_from_circle, + vector_out_of_rect_from_point, + vector_out_of_rect_from_rect, + vector_point_to_point, + vector_subtract, + vector_to, + vector_to_string, + vector_world_to_screen, + vectors_equal, + vectors_not_equal, + widest_points, + window_area, + window_caption, + window_close_requested, + window_has_border, + window_has_focus, + window_height, + window_is_fullscreen, + window_named, + window_position, + window_set_icon, + window_toggle_border, + window_toggle_fullscreen, + window_width, + window_with_focus, + window_x, + window_y, + write, + write_line +`; + +export default methods; \ No newline at end of file diff --git a/Browser_IDE/compilers/csharp/csharpCompiler.js b/Browser_IDE/compilers/csharp/csharpCompiler.js new file mode 100644 index 0000000..b6869f9 --- /dev/null +++ b/Browser_IDE/compilers/csharp/csharpCompiler.js @@ -0,0 +1,33 @@ +"use strict"; + +class CSharpCompiler extends Compiler { + constructor() { + super(); + this.signalReady(); + } + + async compileAll(compileList, sourceList, print) { + let compiled = { + output: null, + }; + + let hasErrors = false; + + // If all good, then output the 'compiled' result + if (!hasErrors) { + compiled.output = []; + for (let i = 0; i < sourceList.length; i++) { + compiled.output.push({ + name: sourceList[i].name, + source: sourceList[i].source, + }); + } + } + + return compiled; + } + +} + +// The name has to match the one in languageDefinitions.js +registerCompiler("csharpCompiler", new CSharpCompiler()); diff --git a/Browser_IDE/executionEnvironment.html b/Browser_IDE/executionEnvironment.html index 455ab71..39ced2a 100644 --- a/Browser_IDE/executionEnvironment.html +++ b/Browser_IDE/executionEnvironment.html @@ -48,5 +48,4 @@ - diff --git a/Browser_IDE/executionEnvironment.js b/Browser_IDE/executionEnvironment.js index 50e7b94..c0d2543 100644 --- a/Browser_IDE/executionEnvironment.js +++ b/Browser_IDE/executionEnvironment.js @@ -285,7 +285,7 @@ class ExecutionEnvironment extends EventTarget{ iframe.id="iframetest"; // this code is primordial... if (language.needsSandbox) - iframe.sandbox = 'allow-scripts allow-modals'; + iframe.sandbox = 'allow-scripts allow-modals allow-same-origin'; container.appendChild(iframe); iframe.src="executionEnvironment.html"; diff --git a/Browser_IDE/languageDefinitions.js b/Browser_IDE/languageDefinitions.js index a85eefc..2f1599e 100644 --- a/Browser_IDE/languageDefinitions.js +++ b/Browser_IDE/languageDefinitions.js @@ -11,6 +11,41 @@ // should inherit from Compiler, and need to register themselves to be used let SplashKitOnlineLanguageDefinitions = [ + { + name: "CSharp", + userVisibleName: "C#", + aliases: ['C#', 'CSharp'], + sourceExtensions: ['cs'], + compilableExtensions: ['cs'], + defaultSourceExtension: "cs", + setups: [{ + name: "C#", + runtimeFiles: [ + { src: "moduleEventTarget.js", type: "text/javascript" }, + { src: "loadsplashkit.js", type: "text/javascript" }, + { src: "fsevents.js", type: "text/javascript" }, + { src: "CSharpWasm/main.js", type: "module" }, + { src: "runtimes/ExecutionEnvironmentInternal.js", type: "text/javascript" }, + { src: "runtimes/csharp/csharpRuntime.js", type: "text/javascript" }, + ], + runtimeDependencies: [ + "runtimes/javascript/bin/SplashKitBackendWASM.js", + "runtimes/javascript/bin/SplashKitBackendWASM.wasm", + ], + compilerFiles: [ + "compilers/csharp/csharpCompiler.js", + ], + runtimeSizeAprox: 20, + compilerSizeAprox: 150, + compilerName: "csharpCompiler", + supportHotReloading: false, + getDefaultProject: ()=>{return makeNewProject_CSharp;}, + persistentFilesystem: false, + compiled: true, + needsSandbox: false, + needsServiceWorker: false, + }] + }, { name: "JavaScript", userVisibleName: "JavaScript", @@ -21,12 +56,12 @@ let SplashKitOnlineLanguageDefinitions = [ setups: [{ name: "JavaScript Native", runtimeFiles: [ - "babel/babel.js", //intention is to make this a compilerFile instead - "moduleEventTarget.js", - "loadsplashkit.js", - "fsevents.js", - "executionEnvironment_CodeProcessor.js", //intention is to make this a compilerFile instead - "executionEnvironment_Internal.js", // and this should be based on ExecutionEnvironmentInternal.js + { src: "babel/babel.js", type: "text/javascript" }, //intention is to make this a compilerFile instead + { src: "moduleEventTarget.js", type: "text/javascript" }, + { src: "loadsplashkit.js", type: "text/javascript" }, + { src: "fsevents.js", type: "text/javascript" }, + { src: "executionEnvironment_CodeProcessor.js", type: "text/javascript" }, //intention is to make this a compilerFile instead + { src: "executionEnvironment_Internal.js", type: "text/javascript" }, // and this should be based on ExecutionEnvironmentInternal.js ], runtimeDependencies: [ "runtimes/javascript/bin/SplashKitBackendWASM.js", @@ -56,9 +91,9 @@ let SplashKitOnlineLanguageDefinitions = [ setups: [{ name: "C++ (Clang)", runtimeFiles: [ - "runtimes/ExecutionEnvironmentInternal.js", - "runtimes/cxx/cxxRuntime.js", - "runtimes/cxx/bin/SplashKitBackendWASMCPP.js", + { src: "runtimes/ExecutionEnvironmentInternal.js", type: "text/javascript" }, + { src: "runtimes/cxx/cxxRuntime.js", type: "text/javascript" }, + { src: "runtimes/cxx/bin/SplashKitBackendWASMCPP.js", type: "text/javascript" }, ], runtimeDependencies: [ "runtimes/cxx/bin/SplashKitBackendWASMCPP.js", diff --git a/Browser_IDE/projectInitializer.js b/Browser_IDE/projectInitializer.js index 1c90013..9e157a7 100644 --- a/Browser_IDE/projectInitializer.js +++ b/Browser_IDE/projectInitializer.js @@ -153,6 +153,31 @@ int main(){ } `; +const defaultMainCodeCSharp = ` +using SplashKitSDK; + +namespace WriteLine +{ + public class Program + { + public static void Main() + { + // Example 1: Print explicit string + SplashKit.WriteLine("Hello World"); + + // Example 2: Print value of string variable + string message = "Hello World from 'message' variable"; + SplashKit.WriteLine(message); + + // Example 3: Print combination of explicit string and value of string variable + string hello = "Hello"; + SplashKit.WriteLine(hello + " World! Don't forget spaces between words when printing to the terminal!"); + SplashKit.WriteLine("Otherwise you get this: " + hello + "World!"); + } + } +} +`; + let codePath = "/code"; async function initializeSplashKitResourceFolders(storedProject) { @@ -175,6 +200,13 @@ async function makeNewProject_JavaScript(storedProject){ await storedProject.writeFile("/code/main.js", defaultMainCodeJS); } +async function makeNewProject_CSharp(storedProject){ + await initializeSplashKitResourceFolders(storedProject); + + await storedProject.mkdir("/code"); + await storedProject.writeFile("/code/main.cs", defaultMainCodeCSharp); +} + async function makeNewProject_CXX(storedProject){ await initializeSplashKitResourceFolders(storedProject); @@ -191,4 +223,4 @@ async function initializeFromFileList(storedProject, files){ await storedProject.writeFile(files[i].path, files[i].data); } -} \ No newline at end of file +} diff --git a/Browser_IDE/runtimes/ExecutionEnvironmentInternalLoader.js b/Browser_IDE/runtimes/ExecutionEnvironmentInternalLoader.js index 8a995e7..33d57c0 100644 --- a/Browser_IDE/runtimes/ExecutionEnvironmentInternalLoader.js +++ b/Browser_IDE/runtimes/ExecutionEnvironmentInternalLoader.js @@ -48,8 +48,9 @@ window.addEventListener('message', function(m){ for (let script of m.data.runtimeFiles){ var s = document.createElement("script"); - s.src = script; + s.src = script.src; s.async = false; + s.type = script.type; document.documentElement.appendChild(s); } } diff --git a/Browser_IDE/runtimes/csharp/csharpRuntime.js b/Browser_IDE/runtimes/csharp/csharpRuntime.js new file mode 100644 index 0000000..71c48db --- /dev/null +++ b/Browser_IDE/runtimes/csharp/csharpRuntime.js @@ -0,0 +1,32 @@ +// define and create the ExecutionEnvironmentInternal subclass +class ExecutionEnvironmentInternalCSharp extends ExecutionEnvironmentInternal { + constructor(listenOn) { + return super(listenOn); + } + + async runProgram(program) { + const event = new CustomEvent("compileAndRun", { + detail: { + program: program, + reportError: executionEnvironment.ReportError, + }, + }); + // This event will be handled in the CSharpWasm/main.js file + document.dispatchEvent(event); + } +} + +let executionEnvironment = null; + +// set everything up! +executionEnvironment = new ExecutionEnvironmentInternalCSharp(window); + +// make canvas take focus when clicked +Module.canvas.addEventListener("click", async function () { + Module.canvas.focus(); +}); + +// send terminal input on enter +runtimeLoadingProgress(1); + +executionEnvironment.signalReady(); diff --git a/Browser_IDE/server.js b/Browser_IDE/server.js index 3261a15..c47a202 100644 --- a/Browser_IDE/server.js +++ b/Browser_IDE/server.js @@ -13,6 +13,7 @@ async function run(){ app.use("/split.js", express.static(path.join(__dirname,"node_modules/split.js/dist/"))); app.use("/mime", express.static(path.join(__dirname,"node_modules/mime/dist/"))); app.use("/DemoProjects", express.static(path.join(__dirname,"../DemoProjects"))); + app.use('/CSharpWasm', express.static(path.join(__dirname, 'CSharpWasm'))); app.use(function (req, res, next) { res.header("Access-Control-Allow-Origin", "*"); diff --git a/CSharpWasm/.gitignore b/CSharpWasm/.gitignore new file mode 100644 index 0000000..50b34e5 --- /dev/null +++ b/CSharpWasm/.gitignore @@ -0,0 +1,3 @@ +# Build results +bin/ +obj/ diff --git a/CSharpWasm/CSharpCodeRunner.cs b/CSharpWasm/CSharpCodeRunner.cs new file mode 100644 index 0000000..1454b7f --- /dev/null +++ b/CSharpWasm/CSharpCodeRunner.cs @@ -0,0 +1,111 @@ +using System; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.JavaScript; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using System.Net.Http; +using System.Threading.Tasks; + +public class DiagnosticInfo +{ + public int Line { get; set; } + public string Message { get; set; } +} + +public partial class CSharpCodeRunner +{ + + static async Task LoadAssemblyFromServer(string assemblyName) + { + var baseUrl = GetHRef(); + var url = $"/CSharpWasm/bin/{assemblyName}"; + + try + { + using var httpClient = new HttpClient { BaseAddress = new Uri(baseUrl) }; + var assemblyBytes = await httpClient.GetByteArrayAsync(url); + return MetadataReference.CreateFromImage(assemblyBytes); + } + catch (Exception ex) + { + Console.WriteLine($"Error loading assembly {assemblyName}: {ex.Message}"); + throw; + } + } + + [JSExport] + internal static Task CompileAndRun(string code) + { + return Task.Run(async () => + { + try + { + var syntaxTree = CSharpSyntaxTree.ParseText(code); + + // Use Task.WhenAll to run async LoadAssemblyFromServer in parallel + var references = await Task.WhenAll( + LoadAssemblyFromServer("mscorlib.dll"), + LoadAssemblyFromServer("netstandard.dll"), + LoadAssemblyFromServer("System.Console.dll"), + LoadAssemblyFromServer("System.Private.CoreLib.dll"), + LoadAssemblyFromServer("System.Runtime.dll"), + LoadAssemblyFromServer("CSharpWasm.dll") + ); + + // Create a compilation with the syntax tree and references + var compilation = CSharpCompilation.Create( + assemblyName: "DynamicAssembly", + syntaxTrees: new[] { syntaxTree }, + references: references, + options: new CSharpCompilationOptions(OutputKind.ConsoleApplication) + ); + + // Create a MemoryStream to store the compiled assembly + using var ms = new MemoryStream(); + var emitResult = compilation.Emit(ms); + + // Check for compilation errors + if (!emitResult.Success) + { + var errors = emitResult.Diagnostics + .Where(d => d.Severity == DiagnosticSeverity.Error) + .Select(d => new DiagnosticInfo + { + Line = d.Location.GetLineSpan().StartLinePosition.Line, + Message = d.GetMessage() + }) + .ToList(); + + // If you need to format it as a string, you can do: + var errorString = string.Join("\n", errors.Select(e => $"Line {e.Line}: {e.Message}")); + + return $"Compilation failed:\n{errorString}"; + } + + // Load the compiled assembly into the current AppDomain + ms.Seek(0, SeekOrigin.Begin); + #pragma warning disable IL2026 + var assembly = AppDomain.CurrentDomain.Load(ms.ToArray()); + #pragma warning restore IL2026 + + // Get the entry point and invoke it + var entryPoint = assembly.EntryPoint; + if (entryPoint != null) + { + var result = entryPoint.Invoke(null, null); + return result?.ToString() ?? "Execution complete, no output."; + } + + return "No entry point found."; + } + catch (Exception ex) + { + return $"Error: {ex}"; + } + }); + } + + [JSImport("window.location.href", "main.js")] + public static partial string GetHRef(); +} diff --git a/CSharpWasm/CSharpWasm.csproj b/CSharpWasm/CSharpWasm.csproj new file mode 100644 index 0000000..73b4a83 --- /dev/null +++ b/CSharpWasm/CSharpWasm.csproj @@ -0,0 +1,9 @@ + + + net8.0 + true + + + + + diff --git a/CSharpWasm/Program.cs b/CSharpWasm/Program.cs new file mode 100644 index 0000000..f038460 --- /dev/null +++ b/CSharpWasm/Program.cs @@ -0,0 +1,3 @@ +using System; + +Console.WriteLine("Hello World from C#!"); diff --git a/CSharpWasm/Properties/AssemblyInfo.cs b/CSharpWasm/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9ad9b57 --- /dev/null +++ b/CSharpWasm/Properties/AssemblyInfo.cs @@ -0,0 +1,4 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +[assembly:System.Runtime.Versioning.SupportedOSPlatform("browser")] diff --git a/CSharpWasm/Properties/launchSettings.json b/CSharpWasm/Properties/launchSettings.json new file mode 100644 index 0000000..5168bef --- /dev/null +++ b/CSharpWasm/Properties/launchSettings.json @@ -0,0 +1,13 @@ +{ + "profiles": { + "CSharpWasm": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:7281;http://localhost:5178", + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + } + } +} diff --git a/CSharpWasm/README.md b/CSharpWasm/README.md new file mode 100644 index 0000000..f299f57 --- /dev/null +++ b/CSharpWasm/README.md @@ -0,0 +1,18 @@ +# CSharpWasm + +This project enables building and running C# code in the browser using WebAssembly (Wasm). + +## Project Structure + +- **SplashKitInterop.cs**: This file contains the logic for binding C# code with JavaScript functions, enabling the use of SplashKit functions within the C# environment. + +- **CSharpCodeRunner.cs**: A class responsible for compiling C# code, providing the necessary functionality to run the code dynamically. + +- **buildAndCopy.sh**: A shell script that builds the project and copies the necessary files into the `Browser_IDE/CSharpWasm` directory. This script helps automate the build process for easy integration with the browser. + +### Running the Build and Copy Script + +To build the project and copy the necessary files into the `Browser_IDE/CSharpWasm` directory, run the following shell script: + +```bash +./buildAndCopy.sh diff --git a/CSharpWasm/SplashKitBindings.Generated.cs b/CSharpWasm/SplashKitBindings.Generated.cs new file mode 100644 index 0000000..28c013f --- /dev/null +++ b/CSharpWasm/SplashKitBindings.Generated.cs @@ -0,0 +1,752 @@ +using System.Runtime.InteropServices.JavaScript; + +namespace SplashKitSDK +{ + public partial class SplashKit + { + [JSImport("SplashKitBackendWASM.free_all_animation_scripts", "main.js")] + public static partial void FreeAllAnimationScripts(); + + [JSImport("SplashKitBackendWASM.free_animation_script", "main.js")] + public static partial void FreeAnimationScript(string name); + + [JSImport("SplashKitBackendWASM.has_animation_script", "main.js")] + public static partial bool HasAnimationScript(string name); + + [JSImport("SplashKitBackendWASM.audio_ready", "main.js")] + public static partial bool AudioReady(); + + [JSImport("SplashKitBackendWASM.close_audio", "main.js")] + public static partial void CloseAudio(); + + [JSImport("SplashKitBackendWASM.open_audio", "main.js")] + public static partial void OpenAudio(); + + [JSImport("SplashKitBackendWASM.fade_music_in", "main.js")] + public static partial void FadeMusicIn(string name, int ms); + + [JSImport("SplashKitBackendWASM.fade_music_in", "main.js")] + public static partial void FadeMusicIn(string name, int times, int ms); + + [JSImport("SplashKitBackendWASM.fade_music_out", "main.js")] + public static partial void FadeMusicOut(int ms); + + [JSImport("SplashKitBackendWASM.free_all_music", "main.js")] + public static partial void FreeAllMusic(); + + [JSImport("SplashKitBackendWASM.has_music", "main.js")] + public static partial bool HasMusic(string name); + + [JSImport("SplashKitBackendWASM.music_playing", "main.js")] + public static partial bool MusicPlaying(); + + [JSImport("SplashKitBackendWASM.music_volume", "main.js")] + public static partial double MusicVolume(); + + [JSImport("SplashKitBackendWASM.pause_music", "main.js")] + public static partial void PauseMusic(); + + [JSImport("SplashKitBackendWASM.play_music", "main.js")] + public static partial void PlayMusic(string name); + + [JSImport("SplashKitBackendWASM.play_music", "main.js")] + public static partial void PlayMusic(string name, int times); + + [JSImport("SplashKitBackendWASM.resume_music", "main.js")] + public static partial void ResumeMusic(); + + [JSImport("SplashKitBackendWASM.set_music_volume", "main.js")] + public static partial void SetMusicVolume(double volume); + + [JSImport("SplashKitBackendWASM.stop_music", "main.js")] + public static partial void StopMusic(); + + [JSImport("SplashKitBackendWASM.fade_all_sound_effects_out", "main.js")] + public static partial void FadeAllSoundEffectsOut(int ms); + + [JSImport("SplashKitBackendWASM.free_all_sound_effects", "main.js")] + public static partial void FreeAllSoundEffects(); + + [JSImport("SplashKitBackendWASM.has_sound_effect", "main.js")] + public static partial bool HasSoundEffect(string name); + + [JSImport("SplashKitBackendWASM.play_sound_effect", "main.js")] + public static partial void PlaySoundEffect(string name); + + [JSImport("SplashKitBackendWASM.play_sound_effect", "main.js")] + public static partial void PlaySoundEffect(string name, double volume); + + [JSImport("SplashKitBackendWASM.play_sound_effect", "main.js")] + public static partial void PlaySoundEffect(string name, int times); + + [JSImport("SplashKitBackendWASM.play_sound_effect", "main.js")] + public static partial void PlaySoundEffect(string name, int times, double volume); + + [JSImport("SplashKitBackendWASM.sound_effect_playing", "main.js")] + public static partial bool SoundEffectPlaying(string name); + + [JSImport("SplashKitBackendWASM.stop_sound_effect", "main.js")] + public static partial void StopSoundEffect(string name); + + [JSImport("SplashKitBackendWASM.camera_x", "main.js")] + public static partial double CameraX(); + + [JSImport("SplashKitBackendWASM.camera_y", "main.js")] + public static partial double CameraY(); + + [JSImport("SplashKitBackendWASM.move_camera_by", "main.js")] + public static partial void MoveCameraBy(double dx, double dy); + + [JSImport("SplashKitBackendWASM.move_camera_to", "main.js")] + public static partial void MoveCameraTo(double x, double y); + + [JSImport("SplashKitBackendWASM.set_camera_x", "main.js")] + public static partial void SetCameraX(double x); + + [JSImport("SplashKitBackendWASM.set_camera_y", "main.js")] + public static partial void SetCameraY(double y); + + [JSImport("SplashKitBackendWASM.to_screen_x", "main.js")] + public static partial double ToScreenX(double worldX); + + [JSImport("SplashKitBackendWASM.to_screen_y", "main.js")] + public static partial double ToScreenY(double worldY); + + [JSImport("SplashKitBackendWASM.to_world_x", "main.js")] + public static partial double ToWorldX(double screenX); + + [JSImport("SplashKitBackendWASM.to_world_y", "main.js")] + public static partial double ToWorldY(double screenY); + + [JSImport("SplashKitBackendWASM.circles_intersect", "main.js")] + public static partial bool CirclesIntersect(double c1X, double c1Y, double c1Radius, double c2X, double c2Y, double c2Radius); + + [JSImport("SplashKitBackendWASM.cosine", "main.js")] + public static partial float Cosine(float degrees); + + [JSImport("SplashKitBackendWASM.sine", "main.js")] + public static partial float Sine(float degrees); + + [JSImport("SplashKitBackendWASM.tangent", "main.js")] + public static partial float Tangent(float degrees); + + [JSImport("SplashKitBackendWASM.point_in_circle", "main.js")] + public static partial bool PointInCircle(double ptx, double pty, double cx, double cy, double radius); + + [JSImport("SplashKitBackendWASM.point_in_rectangle", "main.js")] + public static partial bool PointInRectangle(double ptx, double pty, double rectX, double rectY, double rectWidth, double rectHeight); + + [JSImport("SplashKitBackendWASM.pop_clip", "main.js")] + public static partial void PopClip(); + + [JSImport("SplashKitBackendWASM.reset_clip", "main.js")] + public static partial void ResetClip(); + + [JSImport("SplashKitBackendWASM.clear_screen", "main.js")] + public static partial void ClearScreen(); + + [JSImport("SplashKitBackendWASM.number_of_displays", "main.js")] + public static partial int NumberOfDisplays(); + + [JSImport("SplashKitBackendWASM.refresh_screen", "main.js")] + public static partial void RefreshScreen(); + + [JSImport("SplashKitBackendWASM.screen_height", "main.js")] + public static partial int ScreenHeight(); + + [JSImport("SplashKitBackendWASM.screen_width", "main.js")] + public static partial int ScreenWidth(); + + [JSImport("SplashKitBackendWASM.take_screenshot", "main.js")] + public static partial void TakeScreenshot(string basename); + + [JSImport("SplashKitBackendWASM.bitmap_height", "main.js")] + public static partial int BitmapHeight(string name); + + [JSImport("SplashKitBackendWASM.bitmap_width", "main.js")] + public static partial int BitmapWidth(string name); + + [JSImport("SplashKitBackendWASM.draw_bitmap", "main.js")] + public static partial void DrawBitmap(string name, double x, double y); + + [JSImport("SplashKitBackendWASM.free_all_bitmaps", "main.js")] + public static partial void FreeAllBitmaps(); + + [JSImport("SplashKitBackendWASM.has_bitmap", "main.js")] + public static partial bool HasBitmap(string name); + + [JSImport("SplashKitBackendWASM.font_has_size", "main.js")] + public static partial bool FontHasSize(string name, int fontSize); + + [JSImport("SplashKitBackendWASM.font_load_size", "main.js")] + public static partial void FontLoadSize(string name, int fontSize); + + [JSImport("SplashKitBackendWASM.free_all_fonts", "main.js")] + public static partial void FreeAllFonts(); + + [JSImport("SplashKitBackendWASM.has_font", "main.js")] + public static partial bool HasFont(string name); + + [JSImport("SplashKitBackendWASM.text_height", "main.js")] + public static partial int TextHeight(string text, string fnt, int fontSize); + + [JSImport("SplashKitBackendWASM.text_width", "main.js")] + public static partial int TextWidth(string text, string fnt, int fontSize); + + [JSImport("SplashKitBackendWASM.process_events", "main.js")] + public static partial void ProcessEvents(); + + [JSImport("SplashKitBackendWASM.quit_requested", "main.js")] + public static partial bool QuitRequested(); + + [JSImport("SplashKitBackendWASM.reset_quit", "main.js")] + public static partial void ResetQuit(); + + [JSImport("SplashKitBackendWASM.any_key_pressed", "main.js")] + public static partial bool AnyKeyPressed(); + + [JSImport("SplashKitBackendWASM.hide_mouse", "main.js")] + public static partial void HideMouse(); + + [JSImport("SplashKitBackendWASM.mouse_shown", "main.js")] + public static partial bool MouseShown(); + + [JSImport("SplashKitBackendWASM.mouse_x", "main.js")] + public static partial float MouseX(); + + [JSImport("SplashKitBackendWASM.mouse_y", "main.js")] + public static partial float MouseY(); + + [JSImport("SplashKitBackendWASM.move_mouse", "main.js")] + public static partial void MoveMouse(double x, double y); + + [JSImport("SplashKitBackendWASM.show_mouse", "main.js")] + public static partial void ShowMouse(); + + [JSImport("SplashKitBackendWASM.show_mouse", "main.js")] + public static partial void ShowMouse(bool show); + + [JSImport("SplashKitBackendWASM.end_reading_text", "main.js")] + public static partial void EndReadingText(); + + [JSImport("SplashKitBackendWASM.reading_text", "main.js")] + public static partial bool ReadingText(); + + [JSImport("SplashKitBackendWASM.text_entry_cancelled", "main.js")] + public static partial bool TextEntryCancelled(); + + [JSImport("SplashKitBackendWASM.text_input", "main.js")] + public static partial string TextInput(); + + [JSImport("SplashKitBackendWASM.add_column", "main.js")] + public static partial void AddColumn(int width); + + [JSImport("SplashKitBackendWASM.add_column_relative", "main.js")] + public static partial void AddColumnRelative(double width); + + [JSImport("SplashKitBackendWASM.button", "main.js")] + public static partial bool Button(string text); + + [JSImport("SplashKitBackendWASM.button", "main.js")] + public static partial bool Button(string labelText, string text); + + [JSImport("SplashKitBackendWASM.checkbox", "main.js")] + public static partial bool Checkbox(string text, bool value); + + [JSImport("SplashKitBackendWASM.checkbox", "main.js")] + public static partial bool Checkbox(string labelText, string text, bool value); + + [JSImport("SplashKitBackendWASM.disable_interface", "main.js")] + public static partial void DisableInterface(); + + [JSImport("SplashKitBackendWASM.draw_interface", "main.js")] + public static partial void DrawInterface(); + + [JSImport("SplashKitBackendWASM.enable_interface", "main.js")] + public static partial void EnableInterface(); + + [JSImport("SplashKitBackendWASM.end_inset", "main.js")] + public static partial void EndInset(string name); + + [JSImport("SplashKitBackendWASM.end_panel", "main.js")] + public static partial void EndPanel(string name); + + [JSImport("SplashKitBackendWASM.end_popup", "main.js")] + public static partial void EndPopup(string name); + + [JSImport("SplashKitBackendWASM.end_treenode", "main.js")] + public static partial void EndTreenode(string labelText); + + [JSImport("SplashKitBackendWASM.enter_column", "main.js")] + public static partial void EnterColumn(); + + [JSImport("SplashKitBackendWASM.get_interface_label_width", "main.js")] + public static partial int GetInterfaceLabelWidth(); + + [JSImport("SplashKitBackendWASM.header", "main.js")] + public static partial bool Header(string labelText); + + [JSImport("SplashKitBackendWASM.interface_enabled", "main.js")] + public static partial bool InterfaceEnabled(); + + [JSImport("SplashKitBackendWASM.label_element", "main.js")] + public static partial void LabelElement(string text); + + [JSImport("SplashKitBackendWASM.last_element_changed", "main.js")] + public static partial bool LastElementChanged(); + + [JSImport("SplashKitBackendWASM.last_element_confirmed", "main.js")] + public static partial bool LastElementConfirmed(); + + [JSImport("SplashKitBackendWASM.leave_column", "main.js")] + public static partial void LeaveColumn(); + + [JSImport("SplashKitBackendWASM.number_box", "main.js")] + public static partial float NumberBox(float value, float step); + + [JSImport("SplashKitBackendWASM.number_box", "main.js")] + public static partial float NumberBox(string labelText, float value, float step); + + [JSImport("SplashKitBackendWASM.open_popup", "main.js")] + public static partial void OpenPopup(string name); + + [JSImport("SplashKitBackendWASM.paragraph", "main.js")] + public static partial void Paragraph(string text); + + [JSImport("SplashKitBackendWASM.reset_layout", "main.js")] + public static partial void ResetLayout(); + + [JSImport("SplashKitBackendWASM.set_interface_font", "main.js")] + public static partial void SetInterfaceFont(string fnt); + + [JSImport("SplashKitBackendWASM.set_interface_font_size", "main.js")] + public static partial void SetInterfaceFontSize(int size); + + [JSImport("SplashKitBackendWASM.set_interface_label_width", "main.js")] + public static partial void SetInterfaceLabelWidth(int width); + + [JSImport("SplashKitBackendWASM.set_interface_spacing", "main.js")] + public static partial void SetInterfaceSpacing(int spacing, int padding); + + [JSImport("SplashKitBackendWASM.set_layout_height", "main.js")] + public static partial void SetLayoutHeight(int height); + + [JSImport("SplashKitBackendWASM.single_line_layout", "main.js")] + public static partial void SingleLineLayout(); + + [JSImport("SplashKitBackendWASM.slider", "main.js")] + public static partial float Slider(float value, float minValue, float maxValue); + + [JSImport("SplashKitBackendWASM.slider", "main.js")] + public static partial float Slider(string labelText, float value, float minValue, float maxValue); + + [JSImport("SplashKitBackendWASM.split_into_columns", "main.js")] + public static partial void SplitIntoColumns(int count); + + [JSImport("SplashKitBackendWASM.split_into_columns", "main.js")] + public static partial void SplitIntoColumns(int count, int lastWidth); + + [JSImport("SplashKitBackendWASM.split_into_columns_relative", "main.js")] + public static partial void SplitIntoColumnsRelative(int count, double lastWidth); + + [JSImport("SplashKitBackendWASM.start_custom_layout", "main.js")] + public static partial void StartCustomLayout(); + + [JSImport("SplashKitBackendWASM.start_inset", "main.js")] + public static partial void StartInset(string name, int height); + + [JSImport("SplashKitBackendWASM.start_popup", "main.js")] + public static partial bool StartPopup(string name); + + [JSImport("SplashKitBackendWASM.start_treenode", "main.js")] + public static partial bool StartTreenode(string labelText); + + [JSImport("SplashKitBackendWASM.text_box", "main.js")] + public static partial string TextBox(string value); + + [JSImport("SplashKitBackendWASM.text_box", "main.js")] + public static partial string TextBox(string labelText, string value); + + [JSImport("SplashKitBackendWASM.free_all_json", "main.js")] + public static partial void FreeAllJson(); + + [JSImport("SplashKitBackendWASM.close_log_process", "main.js")] + public static partial void CloseLogProcess(); + + [JSImport("SplashKitBackendWASM.accept_all_new_connections", "main.js")] + public static partial bool AcceptAllNewConnections(); + + [JSImport("SplashKitBackendWASM.broadcast_message", "main.js")] + public static partial void BroadcastMessage(string aMsg); + + [JSImport("SplashKitBackendWASM.broadcast_message", "main.js")] + public static partial void BroadcastMessage(string aMsg, string name); + + [JSImport("SplashKitBackendWASM.check_network_activity", "main.js")] + public static partial void CheckNetworkActivity(); + + [JSImport("SplashKitBackendWASM.clear_messages", "main.js")] + public static partial void ClearMessages(string name); + + [JSImport("SplashKitBackendWASM.close_all_connections", "main.js")] + public static partial void CloseAllConnections(); + + [JSImport("SplashKitBackendWASM.close_all_servers", "main.js")] + public static partial void CloseAllServers(); + + [JSImport("SplashKitBackendWASM.close_connection", "main.js")] + public static partial bool CloseConnection(string name); + + [JSImport("SplashKitBackendWASM.close_server", "main.js")] + public static partial bool CloseServer(string name); + + [JSImport("SplashKitBackendWASM.has_connection", "main.js")] + public static partial bool HasConnection(string name); + + [JSImport("SplashKitBackendWASM.has_messages", "main.js")] + public static partial bool HasMessages(); + + [JSImport("SplashKitBackendWASM.has_messages", "main.js")] + public static partial bool HasMessages(string name); + + [JSImport("SplashKitBackendWASM.has_new_connections", "main.js")] + public static partial bool HasNewConnections(); + + [JSImport("SplashKitBackendWASM.has_server", "main.js")] + public static partial bool HasServer(string name); + + [JSImport("SplashKitBackendWASM.hex_str_to_ipv4", "main.js")] + public static partial string HexStrToIpv4(string aHex); + + [JSImport("SplashKitBackendWASM.hex_to_dec_string", "main.js")] + public static partial string HexToDecString(string aHex); + + [JSImport("SplashKitBackendWASM.hex_to_mac", "main.js")] + public static partial string HexToMac(string hexStr); + + [JSImport("SplashKitBackendWASM.ipv4_to_hex", "main.js")] + public static partial string Ipv4ToHex(string aIP); + + [JSImport("SplashKitBackendWASM.is_connection_open", "main.js")] + public static partial bool IsConnectionOpen(string name); + + [JSImport("SplashKitBackendWASM.is_valid_ipv4", "main.js")] + public static partial bool IsValidIpv4(string ip); + + [JSImport("SplashKitBackendWASM.is_valid_mac", "main.js")] + public static partial bool IsValidMac(string macAddress); + + [JSImport("SplashKitBackendWASM.mac_to_hex", "main.js")] + public static partial string MacToHex(string macAddress); + + [JSImport("SplashKitBackendWASM.my_ip", "main.js")] + public static partial string MyIP(); + + [JSImport("SplashKitBackendWASM.read_message_data", "main.js")] + public static partial string ReadMessageData(string name); + + [JSImport("SplashKitBackendWASM.reconnect", "main.js")] + public static partial void Reconnect(string name); + + [JSImport("SplashKitBackendWASM.release_all_connections", "main.js")] + public static partial void ReleaseAllConnections(); + + [JSImport("SplashKitBackendWASM.send_message_to", "main.js")] + public static partial bool SendMessageTo(string aMsg, string name); + + [JSImport("SplashKitBackendWASM.server_has_new_connection", "main.js")] + public static partial bool ServerHasNewConnection(string name); + + [JSImport("SplashKitBackendWASM.has_gpio", "main.js")] + public static partial bool HasGpio(); + + [JSImport("SplashKitBackendWASM.raspi_cleanup", "main.js")] + public static partial void RaspiCleanup(); + + [JSImport("SplashKitBackendWASM.raspi_init", "main.js")] + public static partial void RaspiInit(); + + [JSImport("SplashKitBackendWASM.raspi_spi_close", "main.js")] + public static partial int RaspiSpiClose(int handle); + + [JSImport("SplashKitBackendWASM.raspi_spi_open", "main.js")] + public static partial int RaspiSpiOpen(int channel, int speed, int spiFlags); + + [JSImport("SplashKitBackendWASM.free_resource_bundle", "main.js")] + public static partial void FreeResourceBundle(string name); + + [JSImport("SplashKitBackendWASM.has_resource_bundle", "main.js")] + public static partial bool HasResourceBundle(string name); + + [JSImport("SplashKitBackendWASM.load_resource_bundle", "main.js")] + public static partial void LoadResourceBundle(string name, string filename); + + [JSImport("SplashKitBackendWASM.path_to_resources", "main.js")] + public static partial string PathToResources(); + + [JSImport("SplashKitBackendWASM.set_resources_path", "main.js")] + public static partial void SetResourcesPath(string path); + + [JSImport("SplashKitBackendWASM.create_sprite_pack", "main.js")] + public static partial void CreateSpritePack(string name); + + [JSImport("SplashKitBackendWASM.current_sprite_pack", "main.js")] + public static partial string CurrentSpritePack(); + + [JSImport("SplashKitBackendWASM.draw_all_sprites", "main.js")] + public static partial void DrawAllSprites(); + + [JSImport("SplashKitBackendWASM.free_all_sprites", "main.js")] + public static partial void FreeAllSprites(); + + [JSImport("SplashKitBackendWASM.free_sprite_pack", "main.js")] + public static partial void FreeSpritePack(string name); + + [JSImport("SplashKitBackendWASM.has_sprite", "main.js")] + public static partial bool HasSprite(string name); + + [JSImport("SplashKitBackendWASM.has_sprite_pack", "main.js")] + public static partial bool HasSpritePack(string name); + + [JSImport("SplashKitBackendWASM.select_sprite_pack", "main.js")] + public static partial void SelectSpritePack(string name); + + [JSImport("SplashKitBackendWASM.update_all_sprites", "main.js")] + public static partial void UpdateAllSprites(); + + [JSImport("SplashKitBackendWASM.update_all_sprites", "main.js")] + public static partial void UpdateAllSprites(float pct); + + [JSImport("SplashKitBackendWASM.read_char", "main.js")] + public static partial char ReadChar(); + + [JSImport("SplashKitBackendWASM.read_line", "main.js")] + public static partial string ReadLine(); + + [JSImport("SplashKitBackendWASM.terminal_has_input", "main.js")] + public static partial bool TerminalHasInput(); + + [JSImport("SplashKitBackendWASM.write", "main.js")] + public static partial void Write(char data); + + [JSImport("SplashKitBackendWASM.write", "main.js")] + public static partial void Write(double data); + + [JSImport("SplashKitBackendWASM.write", "main.js")] + public static partial void Write(int data); + + [JSImport("SplashKitBackendWASM.write", "main.js")] + public static partial void Write(string text); + + [JSImport("SplashKitBackendWASM.write_line", "main.js")] + public static partial void WriteLine(char data); + + [JSImport("SplashKitBackendWASM.write_line", "main.js")] + public static partial void WriteLine(); + + [JSImport("SplashKitBackendWASM.write_line", "main.js")] + public static partial void WriteLine(double data); + + [JSImport("SplashKitBackendWASM.write_line", "main.js")] + public static partial void WriteLine(int data); + + [JSImport("SplashKitBackendWASM.write_line", "main.js")] + public static partial void WriteLine(string line); + + [JSImport("SplashKitBackendWASM.free_all_timers", "main.js")] + public static partial void FreeAllTimers(); + + [JSImport("SplashKitBackendWASM.has_timer", "main.js")] + public static partial bool HasTimer(string name); + + [JSImport("SplashKitBackendWASM.pause_timer", "main.js")] + public static partial void PauseTimer(string name); + + [JSImport("SplashKitBackendWASM.reset_timer", "main.js")] + public static partial void ResetTimer(string name); + + [JSImport("SplashKitBackendWASM.resume_timer", "main.js")] + public static partial void ResumeTimer(string name); + + [JSImport("SplashKitBackendWASM.start_timer", "main.js")] + public static partial void StartTimer(string name); + + [JSImport("SplashKitBackendWASM.stop_timer", "main.js")] + public static partial void StopTimer(string name); + + [JSImport("SplashKitBackendWASM.timer_paused", "main.js")] + public static partial bool TimerPaused(string name); + + [JSImport("SplashKitBackendWASM.timer_started", "main.js")] + public static partial bool TimerStarted(string name); + + [JSImport("SplashKitBackendWASM.base64_decode", "main.js")] + public static partial string Base64Decode(string input); + + [JSImport("SplashKitBackendWASM.base64_encode", "main.js")] + public static partial string Base64Encode(string input); + + [JSImport("SplashKitBackendWASM.bin_to_hex", "main.js")] + public static partial string BinToHex(string binStr); + + [JSImport("SplashKitBackendWASM.bin_to_oct", "main.js")] + public static partial string BinToOct(string binStr); + + [JSImport("SplashKitBackendWASM.contains", "main.js")] + public static partial bool Contains(string text, string subtext); + + [JSImport("SplashKitBackendWASM.convert_to_double", "main.js")] + public static partial double ConvertToDouble(string text); + + [JSImport("SplashKitBackendWASM.convert_to_integer", "main.js")] + public static partial int ConvertToInteger(string text); + + [JSImport("SplashKitBackendWASM.greatest_common_divisor", "main.js")] + public static partial int GreatestCommonDivisor(int number1, int number2); + + [JSImport("SplashKitBackendWASM.hex_to_bin", "main.js")] + public static partial string HexToBin(string hexStr); + + [JSImport("SplashKitBackendWASM.hex_to_oct", "main.js")] + public static partial string HexToOct(string hexStr); + + [JSImport("SplashKitBackendWASM.index_of", "main.js")] + public static partial int IndexOf(string text, string subtext); + + [JSImport("SplashKitBackendWASM.is_binary", "main.js")] + public static partial bool IsBinary(string binStr); + + [JSImport("SplashKitBackendWASM.is_double", "main.js")] + public static partial bool IsDouble(string text); + + [JSImport("SplashKitBackendWASM.is_hex", "main.js")] + public static partial bool IsHex(string hexStr); + + [JSImport("SplashKitBackendWASM.is_integer", "main.js")] + public static partial bool IsInteger(string text); + + [JSImport("SplashKitBackendWASM.is_number", "main.js")] + public static partial bool IsNumber(string text); + + [JSImport("SplashKitBackendWASM.is_octal", "main.js")] + public static partial bool IsOctal(string octalStr); + + [JSImport("SplashKitBackendWASM.is_prime_number", "main.js")] + public static partial bool IsPrimeNumber(int number); + + [JSImport("SplashKitBackendWASM.least_common_multiple", "main.js")] + public static partial int LeastCommonMultiple(int number1, int number2); + + [JSImport("SplashKitBackendWASM.length_of", "main.js")] + public static partial int LengthOf(string text); + + [JSImport("SplashKitBackendWASM.oct_to_bin", "main.js")] + public static partial string OctToBin(string octalStr); + + [JSImport("SplashKitBackendWASM.oct_to_hex", "main.js")] + public static partial string OctToHex(string octStr); + + [JSImport("SplashKitBackendWASM.replace_all", "main.js")] + public static partial string ReplaceAll(string text, string substr, string newText); + + [JSImport("SplashKitBackendWASM.square_root", "main.js")] + public static partial double SquareRoot(int number); + + [JSImport("SplashKitBackendWASM.to_lowercase", "main.js")] + public static partial string ToLowercase(string text); + + [JSImport("SplashKitBackendWASM.to_uppercase", "main.js")] + public static partial string ToUppercase(string text); + + [JSImport("SplashKitBackendWASM.trim", "main.js")] + public static partial string Trim(string text); + + [JSImport("SplashKitBackendWASM.rnd", "main.js")] + public static partial int Rnd(int min, int max); + + [JSImport("SplashKitBackendWASM.rnd", "main.js")] + public static partial float Rnd(); + + [JSImport("SplashKitBackendWASM.rnd", "main.js")] + public static partial int Rnd(int ubound); + + [JSImport("SplashKitBackendWASM.delay", "main.js")] + public static partial void Delay(int milliseconds); + + [JSImport("SplashKitBackendWASM.close_all_windows", "main.js")] + public static partial void CloseAllWindows(); + + [JSImport("SplashKitBackendWASM.close_current_window", "main.js")] + public static partial void CloseCurrentWindow(); + + [JSImport("SplashKitBackendWASM.close_window", "main.js")] + public static partial void CloseWindow(string name); + + [JSImport("SplashKitBackendWASM.current_window_has_border", "main.js")] + public static partial bool CurrentWindowHasBorder(); + + [JSImport("SplashKitBackendWASM.current_window_height", "main.js")] + public static partial int CurrentWindowHeight(); + + [JSImport("SplashKitBackendWASM.current_window_is_fullscreen", "main.js")] + public static partial bool CurrentWindowIsFullscreen(); + + [JSImport("SplashKitBackendWASM.current_window_toggle_border", "main.js")] + public static partial void CurrentWindowToggleBorder(); + + [JSImport("SplashKitBackendWASM.current_window_toggle_fullscreen", "main.js")] + public static partial void CurrentWindowToggleFullscreen(); + + [JSImport("SplashKitBackendWASM.current_window_width", "main.js")] + public static partial int CurrentWindowWidth(); + + [JSImport("SplashKitBackendWASM.current_window_x", "main.js")] + public static partial int CurrentWindowX(); + + [JSImport("SplashKitBackendWASM.current_window_y", "main.js")] + public static partial int CurrentWindowY(); + + [JSImport("SplashKitBackendWASM.has_window", "main.js")] + public static partial bool HasWindow(string caption); + + [JSImport("SplashKitBackendWASM.move_current_window_to", "main.js")] + public static partial void MoveCurrentWindowTo(int x, int y); + + [JSImport("SplashKitBackendWASM.move_window_to", "main.js")] + public static partial void MoveWindowTo(string name, int x, int y); + + [JSImport("SplashKitBackendWASM.resize_current_window", "main.js")] + public static partial void ResizeCurrentWindow(int width, int height); + + [JSImport("SplashKitBackendWASM.set_current_window", "main.js")] + public static partial void SetCurrentWindow(string name); + + [JSImport("SplashKitBackendWASM.window_close_requested", "main.js")] + public static partial bool WindowCloseRequested(string name); + + [JSImport("SplashKitBackendWASM.window_has_border", "main.js")] + public static partial bool WindowHasBorder(string name); + + [JSImport("SplashKitBackendWASM.window_height", "main.js")] + public static partial int WindowHeight(string name); + + [JSImport("SplashKitBackendWASM.window_is_fullscreen", "main.js")] + public static partial bool WindowIsFullscreen(string name); + + [JSImport("SplashKitBackendWASM.window_toggle_border", "main.js")] + public static partial void WindowToggleBorder(string name); + + [JSImport("SplashKitBackendWASM.window_toggle_fullscreen", "main.js")] + public static partial void WindowToggleFullscreen(string name); + + [JSImport("SplashKitBackendWASM.window_width", "main.js")] + public static partial int WindowWidth(string name); + + [JSImport("SplashKitBackendWASM.window_x", "main.js")] + public static partial int WindowX(string name); + + [JSImport("SplashKitBackendWASM.window_y", "main.js")] + public static partial int WindowY(string name); + + } +} \ No newline at end of file diff --git a/CSharpWasm/buildAndCopy.sh b/CSharpWasm/buildAndCopy.sh new file mode 100755 index 0000000..d32ef99 --- /dev/null +++ b/CSharpWasm/buildAndCopy.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status +set -e + +# Define source and target directories +BIN_DIR="./bin/Debug/net8.0" +TARGET_DIR="../Browser_IDE/CSharpWasm/bin" +FRAMEWORK_SRC="./bin/Debug/net8.0/wwwroot/_framework" +FRAMEWORK_DEST="../Browser_IDE/CSharpWasm/wwwroot/_framework" + +# List of files to copy +FILES=( + "mscorlib.dll" + "netstandard.dll" + "CSharpWasm.dll" + "System.Console.dll" + "System.Private.CoreLib.dll" + "System.Runtime.dll" +) + +echo "Building the project..." +dotnet build + +# Check if the build succeeded +if [ $? -eq 0 ]; then + echo "Build succeeded!" + + # Copy required files from bin to target directory + echo "Copying files to $TARGET_DIR..." + mkdir -p "$TARGET_DIR" # Create the target directory if it doesn't exist + for FILE in "${FILES[@]}"; do + if [[ -f "$BIN_DIR/$FILE" ]]; then + cp "$BIN_DIR/$FILE" "$TARGET_DIR/" + echo "Copied $FILE to $TARGET_DIR." + else + echo "Warning: $FILE not found in $BIN_DIR." + fi + done + + # Copy _framework directory to the target destination + echo "Copying _framework directory..." + if [[ -d "$FRAMEWORK_SRC" ]]; then + mkdir -p "$FRAMEWORK_DEST" # Create the target directory if it doesn't exist + cp -r "$FRAMEWORK_SRC"/* "$FRAMEWORK_DEST/" + echo "Copied _framework to $FRAMEWORK_DEST." + else + echo "Error: Framework directory not found at $FRAMEWORK_SRC." + exit 1 + fi + + echo "Build and copy process completed successfully!" +else + echo "Build failed. Exiting script." + exit 1 +fi \ No newline at end of file diff --git a/CSharpWasm/runtimeconfig.template.json b/CSharpWasm/runtimeconfig.template.json new file mode 100644 index 0000000..b96a943 --- /dev/null +++ b/CSharpWasm/runtimeconfig.template.json @@ -0,0 +1,10 @@ +{ + "wasmHostProperties": { + "perHostConfig": [ + { + "name": "browser", + "host": "browser" + } + ] + } +} \ No newline at end of file