DanielGavin / ols

Language server for Odin
MIT License
440 stars 68 forks source link

OLS showing errors that don't appear on build and sometimes crashes #290

Closed androbytes closed 9 months ago

androbytes commented 9 months ago
package ECS

import "core:mem"
import "core:fmt"
import "core:hash"
import "core:math/rand"

Limits :: enum {
    MaxComponents = 256,
    MaxEntities   = 4096,
}

PtrToArray :: proc(Pointer: rawptr, Size: int, $Type: typeid) -> [^]Type {
    return (cast([^]Type)Pointer)[:Size]
}

Vector :: struct($VectorType: typeid) {
    First:      rawptr,
    End:        rawptr,
    VecType:    VectorType,
    Size:       int,
}

VecToArray :: proc(Vector: Vector($Type)) -> [^]Type {
    return PtrToArray(Vector.First, Vector.Size, typeof(Vector.VecType))
}

CreateVector :: proc($Type: typeid) -> ^Vector(Type) {
    Vec := new(Vector(Type))
    Vec.Size    = 0
    Vec.First   = make([^]type_of(Vec.VecType), Vec.Size)
    Vec.End     = mem.ptr_offset(cast([^]type_of(Vec.VecType))Vec.First, Vec.Size * size_of(Vec.VecType))
    return Vec
}

DestroyVector :: proc(Vector: Vector($Type)) {
    delete((cast([^]type_of(Vector.VecType))Vector.First)[:Vector.Size])
    fmt.println("Destroyed vector")
}

Reserve :: proc(Vector: ^Vector($Type), Count: int) {
    OldVec          := Vector^

    Vector.Size     = Count
    Vector.First    = make([^]type_of(Vector.VecType), Vector.Size)
    Vector.End      = mem.ptr_offset(cast([^]type_of(Vector.VecType))Vector.First, Vector.Size * size_of(Vector.VecType))

    FirstToVec := PtrToArray(Vec.First, Vec.Size, type_of(Vec.VecType))

    for elem, idx in FirstToVec {
        FirstToVec[idx] = Vector.VecType
    }

    for elem, idx in PtrToArray(OldVec.First, OldVec.Size, type_of(OldVec.VecType)) {
        FirstToVec[idx] = elem
    }

    DestroyVector(OldVec)
}

PushBack :: proc(Vec: ^Vector($Type), Element: $EType) {
    if type_of(Element) != type_of(Vec.VecType) {
        fmt.println("Vector type mismatch")
    }
    ActualElement   := Element
    OldVec          := Vec^

    Vec.Size    += 1
    Vec.First    = make([^]type_of(Vec.VecType), Vec.Size)
    Vec.End      = mem.ptr_offset(cast([^]type_of(Vec.VecType))Vec.First, Vec.Size * size_of(Vec.VecType))

    FirstToVec := PtrToArray(Vec.First, Vec.Size, type_of(Vec.VecType))

    for elem, idx in PtrToArray(OldVec.First, OldVec.Size, type_of(OldVec.VecType)) {
        FirstToVec[idx] = elem
    }
    FirstToVec[Vec.Size - 1] = Element

    DestroyVector(OldVec)
}

AtIndex :: proc(Vector: ^Vector($Type), Index: int) -> ^Type {
    return &((cast([^]type_of(Vector.VecType))Vector.First)[Index])
}

FindVectorValue :: proc(Vector: ^Vector($Type), Value: Type) -> int {
    for elem, idx in (cast([^]type_of(Vector.VecType))Vector.First)[:Vector.Size] {
        if elem == Value {
            return idx
        }
    }
    return -1
}

Set :: struct($Type: typeid) {
    Buckets: ^Vector(Type),
    Seed: u64
}

CreateSet :: proc($Type: typeid, Size: int) -> ^Set(Type) {
    Set := new(Set(Type))
    Set.Buckets = CreateVector(Type)
    Reserve(Set.Buckets, Size)
    Set.Seed = rand._system_random()
    return Set
}

DestroySet :: proc(Set: Set($Type)) {
    DestroyVector(Set.Buckets^)
}

Insert :: proc(Set: ^Set($Type), Element: Type) -> int {
    HashIdx := hash.crc64_ecma_182(mem.any_to_bytes(Element), Set.Seed) % cast(u64)Set.Buckets.Size
    if AtIndex(Set.Buckets, cast(int)HashIdx)^ == Set.Buckets.VecType {
        Idx := AtIndex(Set.Buckets, cast(int)HashIdx)
        Idx^ = Element
    }
    return cast(int)HashIdx
}

AtSetIndex :: proc(Set: ^Set($Type), Idx: int) -> ^Type {
    return AtIndex(Set.Buckets, Idx)
}

SetValueExists :: proc(Set: ^Set($Type), Value: Type) -> bool {
    HashIdx := hash.crc64_ecma_182(mem.any_to_bytes(Value), Set.Seed) % cast(u64)Set.Buckets.Size
    if AtIndex(Set.Buckets, cast(int)HashIdx)^ == Set.Buckets.VecType {
        return false
    }
    return true
}

ArchetypeID :: u32
EntityID    :: u64
Type        :: Vector(typeid)

Column :: struct {
    Elements: rawptr,
    ElementSize: u64,
    Count: u64
}

ArchetypeEdge :: struct {
    Add:    ^Archetype,
    Remove: ^Archetype,
}

Archetype :: struct {
    ID: ArchetypeID,
    Type: Type,
    Components: Vector(Column),
    Edges: map[typeid]ArchetypeEdge,
}

ArchetypeRecord :: struct {
    Column: int,
}

Record :: struct {
    Archetype: ^Archetype,
    Row: int,
}

ArchetypeMap :: map[ArchetypeID]ArchetypeRecord

World :: struct {
    ArchetypeIndex: map[Type]Archetype,
    EntityIndex:    map[EntityID]Record,
    ComponentIndex: map[typeid]ArchetypeMap,
}

CreateWorld :: proc() -> ^World {
    world := new(World)

    world.ArchetypeIndex    = make(map[Type]Archetype)
    world.EntityIndex       = make(map[EntityID]Record)
    world.ComponentIndex    = make(map[typeid]ArchetypeMap)

    return world
}

this is the code that causes errors, i tried to get a minimal example but couldn't get the same issue

DanielGavin commented 9 months ago

Fixed.