Restructured the codebase yet again but this time with compiler support for monlithic packages
So no need to stage generate symbolic links in a flat directory for the compiler
This commit is contained in:
23
code/sectr/project/manual_serialization.odin
Normal file
23
code/sectr/project/manual_serialization.odin
Normal file
@ -0,0 +1,23 @@
|
||||
package sectr
|
||||
|
||||
import "core:encoding/json"
|
||||
import "core:reflect"
|
||||
|
||||
// TODO(Ed) : Generic Unmarshling of json objects (There should be a way I believe todo this generically but the reflect library is not well documented)
|
||||
|
||||
vec2_json_unmarshal :: proc( value : ^ json.Value ) -> Vec2 {
|
||||
json_v := value.(json.Array)
|
||||
return {
|
||||
f32(json_v[0].(json.Float)),
|
||||
f32(json_v[1].(json.Float)),
|
||||
}
|
||||
}
|
||||
|
||||
color_json_unmarshal :: proc( value : ^ json.Value ) -> Color {
|
||||
json_color := value.(json.Array)
|
||||
r := u8(json_color[0].(json.Float))
|
||||
g := u8(json_color[1].(json.Float))
|
||||
b := u8(json_color[2].(json.Float))
|
||||
a := u8(json_color[3].(json.Float))
|
||||
return { r, g, b, a }
|
||||
}
|
26
code/sectr/project/project.odin
Normal file
26
code/sectr/project/project.odin
Normal file
@ -0,0 +1,26 @@
|
||||
package sectr
|
||||
|
||||
/*
|
||||
Project: Encapsulation of all things a user can do separate from the core app behavior
|
||||
that is managed independetly of it.
|
||||
*/
|
||||
|
||||
// PMDB
|
||||
CodeBase :: struct {
|
||||
placeholder : int,
|
||||
}
|
||||
|
||||
ProjectConfig :: struct {
|
||||
placeholder : int,
|
||||
}
|
||||
|
||||
Project :: struct {
|
||||
path : StrRunesPair,
|
||||
name : StrRunesPair,
|
||||
|
||||
config : ProjectConfig,
|
||||
codebase : CodeBase,
|
||||
|
||||
// TODO(Ed) : Support multiple workspaces
|
||||
workspace : Workspace,
|
||||
}
|
186
code/sectr/project/serialize.odin
Normal file
186
code/sectr/project/serialize.odin
Normal file
@ -0,0 +1,186 @@
|
||||
package sectr
|
||||
|
||||
import "core:encoding/json"
|
||||
import "core:fmt"
|
||||
import "core:os"
|
||||
import "core:reflect"
|
||||
import "base:runtime"
|
||||
import "core:strings"
|
||||
|
||||
@(private="file")
|
||||
assign_int :: proc(val: any, i: $T) -> bool {
|
||||
v := reflect.any_core(val)
|
||||
switch &dst in v {
|
||||
case i8: dst = i8 (i)
|
||||
case i16: dst = i16 (i)
|
||||
case i16le: dst = i16le (i)
|
||||
case i16be: dst = i16be (i)
|
||||
case i32: dst = i32 (i)
|
||||
case i32le: dst = i32le (i)
|
||||
case i32be: dst = i32be (i)
|
||||
case i64: dst = i64 (i)
|
||||
case i64le: dst = i64le (i)
|
||||
case i64be: dst = i64be (i)
|
||||
case i128: dst = i128 (i)
|
||||
case i128le: dst = i128le (i)
|
||||
case i128be: dst = i128be (i)
|
||||
case u8: dst = u8 (i)
|
||||
case u16: dst = u16 (i)
|
||||
case u16le: dst = u16le (i)
|
||||
case u16be: dst = u16be (i)
|
||||
case u32: dst = u32 (i)
|
||||
case u32le: dst = u32le (i)
|
||||
case u32be: dst = u32be (i)
|
||||
case u64: dst = u64 (i)
|
||||
case u64le: dst = u64le (i)
|
||||
case u64be: dst = u64be (i)
|
||||
case u128: dst = u128 (i)
|
||||
case u128le: dst = u128le (i)
|
||||
case u128be: dst = u128be (i)
|
||||
case int: dst = int (i)
|
||||
case uint: dst = uint (i)
|
||||
case uintptr: dst = uintptr(i)
|
||||
case: return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
when false {
|
||||
unmarshal_from_object :: proc( $Type: typeid, object : json.Object ) -> Type
|
||||
{
|
||||
result : Type
|
||||
type_info := type_info_of(Type)
|
||||
#partial switch type in type_info.variant {
|
||||
case runtime.Type_Info_Union:
|
||||
ensure( false, "This proc doesn't support raw unions" )
|
||||
}
|
||||
|
||||
base_ptr := uintptr( & result )
|
||||
|
||||
field_infos := reflect.struct_fields_zipped(Type)
|
||||
for field_info in field_infos
|
||||
{
|
||||
field_type := field_info.type.id
|
||||
field_ptr := cast(field_type) rawptr( base_ptr + field_info.offset )
|
||||
|
||||
#partial switch type in field_info.type.variant {
|
||||
case runtime.Type_Info_Integer:
|
||||
field_ptr = object[filed_info.name].(json.Integer)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
Serializer_Version :: 1
|
||||
Serializer_Loading :: false
|
||||
|
||||
ArchiveData :: struct {
|
||||
data : [] byte,
|
||||
version : i32,
|
||||
}
|
||||
|
||||
archive_init_temp :: proc() -> ^ ArchiveData {
|
||||
archive := new( ArchiveData, context.temp_allocator )
|
||||
archive.version = Serializer_Version
|
||||
return archive
|
||||
}
|
||||
|
||||
state_serialize :: proc( archive : ^ ArchiveData = nil ) {
|
||||
// TODO(Ed): We'll need this for a better save/load snapshot setup.
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
MarshalArchive :: struct {
|
||||
version : i32,
|
||||
project : Project
|
||||
}
|
||||
|
||||
if is_writting
|
||||
{
|
||||
marshal_archive := new(MarshalArchive, frame_slab_allocator())
|
||||
marshal_archive.version = archive.version
|
||||
marshal_archive.project = project^
|
||||
// TODO(Ed): In the future this will be more complicated, as serialization of workspaces and the code database won't be trivial
|
||||
|
||||
json_data, marshal_code := json.marshal( marshal_archive, 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")
|
||||
|
||||
archive_json := parsed_json.(json.Object)
|
||||
archive_version : i32 = cast(i32) archive_json["version"].(json.Float)
|
||||
verify( Serializer_Version == archive_version, "Version mismatch on archive!" )
|
||||
|
||||
// Note(Ed) : This works fine for now, but eventually it will most likely break with pointers...
|
||||
// We'll most likely set things up so that all refs in the project & workspace are handles.
|
||||
marshal_archive := new(MarshalArchive, frame_slab_allocator())
|
||||
json.unmarshal( archive.data, & marshal_archive, spec = json.Specification.MJSON, allocator = context.temp_allocator )
|
||||
if marshal_archive.version == Serializer_Version {
|
||||
project^ = marshal_archive.project
|
||||
}
|
||||
|
||||
// Manual unmarshal
|
||||
when false
|
||||
{
|
||||
project_json := archive_json["project"].(json.Object)
|
||||
project.name = project_json["name"].(json.String)
|
||||
|
||||
// TODO(Ed) : Make this a separate proc
|
||||
workspace_json := project_json["workspace"].(json.Object)
|
||||
{
|
||||
using project.workspace
|
||||
name = workspace_json["name"].(json.String)
|
||||
|
||||
// cam = unmarshal_from_object(Camera, workspace_json["camera"].(json.Object) )
|
||||
frame_1 = frame_json_unmarshal( & workspace_json["frame_1"] )
|
||||
}
|
||||
}
|
||||
|
||||
// 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.str ) {
|
||||
os.make_directory( project.path.str )
|
||||
verify( cast(b32) os.is_dir( project.path.str ), "Failed to create project path for saving" )
|
||||
}
|
||||
|
||||
os.write_entire_file( str_tmp_from_any( project.path.str, project.name.str, ".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( b32(read_code), "Failed to read from project file" )
|
||||
|
||||
archive.data = data
|
||||
project_serialize( project, archive, Serializer_Loading )
|
||||
}
|
38
code/sectr/project/workspace.odin
Normal file
38
code/sectr/project/workspace.odin
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
Workspace : A canvas for compositoning a view for the codebase along with notes.
|
||||
|
||||
Each workspace viewport supports both a canvas composition of code frames
|
||||
or frame tiling towards the application's screenspace.
|
||||
*/
|
||||
package sectr
|
||||
|
||||
Workspace :: struct {
|
||||
name : StrRunesPair,
|
||||
|
||||
cam : Camera,
|
||||
zoom_target : f32,
|
||||
|
||||
frames : Array(Frame),
|
||||
|
||||
test_frame : Frame,
|
||||
|
||||
// TODO(Ed) : The workspace is mainly a 'UI' conceptually...
|
||||
ui : UI_State,
|
||||
}
|
||||
|
||||
// Top level widgets for the workspace
|
||||
Frame :: struct {
|
||||
pos : Vec2,
|
||||
size : Vec2,
|
||||
|
||||
ui : UI_Widget,
|
||||
}
|
||||
|
||||
CodeFrame :: struct {
|
||||
readonly : b32, // Should this frame allow editing?
|
||||
|
||||
}
|
||||
|
||||
NoteFrame :: struct {
|
||||
|
||||
}
|
Reference in New Issue
Block a user