Got project saving/loading initally working
This commit is contained in:
		| @@ -60,6 +60,8 @@ startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ | ||||
| 	state := new( State, tracked_allocator( memory.persistent ) ) | ||||
| 	using state | ||||
|  | ||||
| 	context.user_ptr = state | ||||
|  | ||||
| 	input      = & input_data[1] | ||||
| 	input_prev = & input_data[0] | ||||
|  | ||||
| @@ -87,6 +89,14 @@ startup :: proc( live_mem : virtual.Arena, snapshot_mem : []u8, host_logger : ^ | ||||
| 		default_font = font_rec_mono_semicasual_reg | ||||
| 		log( "Default font loaded" ) | ||||
| 	} | ||||
|  | ||||
| 	project.path = "./" | ||||
| 	project.name = "First Project" | ||||
| 	project.workspace.name = "First Workspace" | ||||
|  | ||||
| 	project_save( & project ) | ||||
| 	project = {} | ||||
| 	project_load( "./First Project.sectr_proj", & project ) | ||||
| } | ||||
|  | ||||
| // For some reason odin's symbols conflict with native foreign symbols... | ||||
|   | ||||
							
								
								
									
										107
									
								
								code/env.odin
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								code/env.odin
									
									
									
									
									
								
							| @@ -25,11 +25,25 @@ Memory :: struct { | ||||
| 	logger : Logger, | ||||
| } | ||||
|  | ||||
| save_snapshot :: proc( snapshot : [^]u8 ) { | ||||
| 	state := get_state()  | ||||
|  | ||||
| 	// state.font_rec_mono_semicasual_reg | ||||
| 	// state.default_font | ||||
|  | ||||
| 	live_ptr := cast( ^ rawptr ) memory.live.curr_block.base | ||||
| 	mem.copy_non_overlapping( & snapshot[0], live_ptr, memory_chunk_size ) | ||||
| } | ||||
|  | ||||
| load_snapshot :: proc( snapshot : [^]u8 ) { | ||||
| 	live_ptr := cast( ^ rawptr ) memory.live.curr_block.base | ||||
| 	mem.copy_non_overlapping( live_ptr, snapshot, memory_chunk_size ) | ||||
| } | ||||
|  | ||||
| State :: struct { | ||||
| 	input_data : [2] InputState, | ||||
|  | ||||
| 	input_prev : ^ InputState, | ||||
| 	input      : ^ InputState, | ||||
| 	input_prev : ^   InputState, | ||||
| 	input      : ^   InputState, | ||||
|  | ||||
| 	debug  : DebugData, | ||||
|  | ||||
| @@ -48,17 +62,20 @@ State :: struct { | ||||
| 	default_font                 : Font, | ||||
| } | ||||
|  | ||||
| get_state :: proc() -> (^ State) { | ||||
| 	return cast( ^ State ) raw_data( memory.persistent.backing.data ) | ||||
| } | ||||
|  | ||||
| Project :: struct { | ||||
| 	path : string, | ||||
| 	name : string, | ||||
|  | ||||
| 	// TODO(Ed) : Support multiple workspaces | ||||
| 	workspace : Workspace | ||||
| } | ||||
|  | ||||
| Workspace :: struct { | ||||
|  | ||||
| } | ||||
|  | ||||
| get_state :: proc() -> (^ State) { | ||||
| 	return cast( ^ State ) raw_data( memory.persistent.backing.data ) | ||||
| 	name : string | ||||
| } | ||||
|  | ||||
| DebugData :: struct { | ||||
| @@ -92,77 +109,3 @@ poll_debug_actions :: proc( actions : ^ DebugActions, input : ^ InputState ) | ||||
|  | ||||
| 	show_mouse_pos = keyboard.right_alt.ended_down && pressed(keyboard.M) | ||||
| } | ||||
|  | ||||
| save_snapshot :: proc( snapshot : [^]u8 ) { | ||||
| 	state := get_state()  | ||||
|  | ||||
| 	// state.font_rec_mono_semicasual_reg | ||||
| 	// state.default_font | ||||
|  | ||||
| 	live_ptr := cast( ^ rawptr ) memory.live.curr_block.base | ||||
| 	mem.copy_non_overlapping( & snapshot[0], live_ptr, memory_chunk_size ) | ||||
| } | ||||
|  | ||||
| load_snapshot :: proc( snapshot : [^]u8 ) { | ||||
| 	live_ptr := cast( ^ rawptr ) memory.live.curr_block.base | ||||
| 	mem.copy_non_overlapping( live_ptr, snapshot, memory_chunk_size ) | ||||
| } | ||||
|  | ||||
| ReplayMode :: enum { | ||||
| 	Off, | ||||
| 	Record, | ||||
| 	Playback, | ||||
| } | ||||
|  | ||||
| ReplayState :: struct { | ||||
| 	loop_active : b32, | ||||
| 	mode        : ReplayMode, | ||||
| 	active_file : os.Handle | ||||
| } | ||||
|  | ||||
| replay_recording_begin :: proc( path : string ) | ||||
| { | ||||
| 	if file_exists( path ) { | ||||
| 		result := os.remove( path ) | ||||
| 		verify( result != os.ERROR_NONE, "Failed to delete replay file before beginning a new one" ) | ||||
| 	} | ||||
|  | ||||
| 	replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE ) | ||||
| 	verify( open_error != os.ERROR_NONE, "Failed to create or open the replay file" ) | ||||
|  | ||||
| 	os.seek( replay_file, 0, 0 ) | ||||
|  | ||||
| 	replay := & memory.replay | ||||
| 	replay.active_file = replay_file | ||||
| 	replay.mode        = ReplayMode.Record | ||||
| } | ||||
|  | ||||
| replay_recording_end :: proc() { | ||||
| 	replay := & memory.replay | ||||
| 	replay.mode = ReplayMode.Off | ||||
|  | ||||
| 	os.seek( replay.active_file, 0, 0 ) | ||||
| 	os.close( replay.active_file ) | ||||
| } | ||||
|  | ||||
| replay_playback_begin :: proc( path : string ) | ||||
| { | ||||
| 	verify( ! file_exists( path ), "Failed to find replay file" ) | ||||
|  | ||||
| 	replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE ) | ||||
| 	verify( open_error != os.ERROR_NONE, "Failed to create or open the replay file" ) | ||||
|  | ||||
| 	os.seek( replay_file, 0, 0 ) | ||||
|  | ||||
| 	replay := & memory.replay | ||||
| 	replay.active_file = replay_file | ||||
| 	replay.mode        = ReplayMode.Playback | ||||
| } | ||||
|  | ||||
| replay_playback_end :: proc() { | ||||
| 	input  := get_state().input | ||||
| 	replay := & memory.replay | ||||
| 	replay.mode = ReplayMode.Off | ||||
| 	os.seek( replay.active_file, 0, 0 ) | ||||
| 	os.close( replay.active_file ) | ||||
| } | ||||
|   | ||||
							
								
								
									
										0
									
								
								code/gen/genodin.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								code/gen/genodin.odin
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										62
									
								
								code/replay.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								code/replay.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| package sectr | ||||
|  | ||||
| import "core:os" | ||||
|  | ||||
| ReplayMode :: enum { | ||||
| 	Off, | ||||
| 	Record, | ||||
| 	Playback, | ||||
| } | ||||
|  | ||||
| ReplayState :: struct { | ||||
| 	loop_active : b32, | ||||
| 	mode        : ReplayMode, | ||||
| 	active_file : os.Handle | ||||
| } | ||||
|  | ||||
| replay_recording_begin :: proc( path : string ) | ||||
| { | ||||
| 	if file_exists( path ) { | ||||
| 		result := os.remove( path ) | ||||
| 		verify( result != os.ERROR_NONE, "Failed to delete replay file before beginning a new one" ) | ||||
| 	} | ||||
|  | ||||
| 	replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE ) | ||||
| 	verify( open_error != os.ERROR_NONE, "Failed to create or open the replay file" ) | ||||
|  | ||||
| 	os.seek( replay_file, 0, 0 ) | ||||
|  | ||||
| 	replay := & memory.replay | ||||
| 	replay.active_file = replay_file | ||||
| 	replay.mode        = ReplayMode.Record | ||||
| } | ||||
|  | ||||
| replay_recording_end :: proc() { | ||||
| 	replay := & memory.replay | ||||
| 	replay.mode = ReplayMode.Off | ||||
|  | ||||
| 	os.seek( replay.active_file, 0, 0 ) | ||||
| 	os.close( replay.active_file ) | ||||
| } | ||||
|  | ||||
| replay_playback_begin :: proc( path : string ) | ||||
| { | ||||
| 	verify( ! file_exists( path ), "Failed to find replay file" ) | ||||
|  | ||||
| 	replay_file, open_error := os.open( path, os.O_RDWR | os.O_CREATE ) | ||||
| 	verify( open_error != os.ERROR_NONE, "Failed to create or open the replay file" ) | ||||
|  | ||||
| 	os.seek( replay_file, 0, 0 ) | ||||
|  | ||||
| 	replay := & memory.replay | ||||
| 	replay.active_file = replay_file | ||||
| 	replay.mode        = ReplayMode.Playback | ||||
| } | ||||
|  | ||||
| replay_playback_end :: proc() { | ||||
| 	input  := get_state().input | ||||
| 	replay := & memory.replay | ||||
| 	replay.mode = ReplayMode.Off | ||||
| 	os.seek( replay.active_file, 0, 0 ) | ||||
| 	os.close( replay.active_file ) | ||||
| } | ||||
							
								
								
									
										86
									
								
								code/serialize.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								code/serialize.odin
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| package sectr | ||||
|  | ||||
| import "core:encoding/json" | ||||
| import "core:fmt" | ||||
| import "core:os" | ||||
| import "core:strings" | ||||
|  | ||||
| Serializer_Version :: 1 | ||||
| Serializer_Loading :: false | ||||
|  | ||||
| ArchiveData :: struct { | ||||
| 	data        : [] byte, | ||||
| 	version     : i32, | ||||
| 	is_writting : b32 | ||||
| } | ||||
|  | ||||
| archive_init_temp :: proc () -> ^ ArchiveData { | ||||
| 	archive := new( ArchiveData, context.temp_allocator ) | ||||
| 	archive.version = Serializer_Version | ||||
| 	return archive | ||||
| } | ||||
|  | ||||
| state_serialize :: proc ( archive : ^ ArchiveData = nil ) { | ||||
|  | ||||
| } | ||||
|  | ||||
| project_serialize :: proc ( project : ^ Project, archive : ^ ArchiveData, is_writting : b32 = true ) | ||||
| { | ||||
| 	options : json.Marshal_Options | ||||
| 	options.spec        = json.Specification.MJSON | ||||
| 	options.indentation = 2 | ||||
| 	options.pretty      = true | ||||
| 	options.use_spaces  = false | ||||
|  | ||||
| 	if is_writting | ||||
| 	{ | ||||
| 		json_data, marshal_code := json.marshal( project^, options, allocator = context.temp_allocator ) | ||||
| 		verify( marshal_code != json.Marshal_Data_Error.None, "Failed to marshal the project to JSON" ) | ||||
|  | ||||
| 		archive.data = json_data | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		parsed_json, parse_code := json.parse( archive.data, json.Specification.MJSON, allocator = context.temp_allocator ) | ||||
| 		verify( parse_code != json.Error.None, "Failed to parse project JSON") | ||||
|  | ||||
| 		project_json := parsed_json.(json.Object) | ||||
| 		project.name  = project_json["name"].(json.String) | ||||
|  | ||||
| 		// TODO(Ed) : Make this a separate proc | ||||
| 		workspace_json        := project_json["workspace"].(json.Object) | ||||
| 		project.workspace.name = workspace_json["name"].(json.String) | ||||
|  | ||||
| 		// DEBUG DUD | ||||
| 		options.use_spaces = false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| project_save :: proc ( project : ^ Project, archive : ^ ArchiveData = nil ) | ||||
| { | ||||
| 	archive := archive | ||||
| 	if archive == nil { | ||||
| 		archive = archive_init_temp() | ||||
| 	} | ||||
| 	project_serialize( project, archive ) | ||||
|  | ||||
| 	if ! os.is_dir( project.path ) { | ||||
| 		os.make_directory( project.path ) | ||||
| 		verify( ! os.is_dir( project.path ), "Failed to create project path for saving" ) | ||||
| 	} | ||||
|  | ||||
| 	os.write_entire_file( fmt.tprint( project.path, project.name, ".sectr_proj", sep = ""), archive.data ) | ||||
| } | ||||
|  | ||||
| project_load :: proc ( path : string, project : ^ Project, archive : ^ ArchiveData = nil ) { | ||||
| 	archive := archive | ||||
| 	if archive == nil { | ||||
| 		archive = archive_init_temp() | ||||
| 	} | ||||
|  | ||||
| 	data, read_code := os.read_entire_file( path, context.temp_allocator ) | ||||
| 	verify( ! read_code, "Failed to read from project file" ) | ||||
|  | ||||
| 	archive.data = data | ||||
| 	project_serialize( project, archive, Serializer_Loading ) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user