/* date = April 30th 2023 11:35 am */

#ifndef VN_THREAD_CONTEXT_H
#define VN_THREAD_CONTEXT_H

#define per_thread __declspec(thread)

struct thread_context
{
    memory_arena Arenas[2];
};

per_thread thread_context *ThreadLocal_ThreadContext = 0;

inline void SetThreadContext(thread_context *Context)
{
    ThreadLocal_ThreadContext = Context;
}

inline thread_context *GetThreadContext(void)
{
    return(ThreadLocal_ThreadContext);
}

static temporary_memory GetScratch(memory_arena **Conflicts = 0, u64 ConflictCount = 0)
{
    temporary_memory Scratch = {};
    thread_context *Context = GetThreadContext();
    
    for(u64 ArenaIndex = 0;
        ArenaIndex < ArrayCount(Context->Arenas);
        ++ArenaIndex)
    {
        b32 FoundConflict = false;
        for(u64 ConflictIndex = 0;
            ConflictIndex < ConflictCount;
            ++ConflictIndex)
        {
            memory_arena *Conflict = Conflicts[ConflictIndex];
            if(Conflict == Context->Arenas + ArenaIndex)
            {
                FoundConflict = true;
                break;
            }
        }
        
        if(!FoundConflict)
        {
            Scratch = BeginTemporaryMemory(Context->Arenas + ArenaIndex);
            break;
        }
    }
    
    Assert(Scratch.Arena);
    
    return(Scratch);
}

#define ReleaseScratch(Scratch) EndTemporaryMemory(Scratch)

#endif //VN_THREAD_CONTEXT_H
