Skip to main content

Workspace

The workspace.h header provides a centralized asset management system for Atlas Engine. The Workspace singleton manages all resources like images, audio files, models, and other assets.

ResourceType Enum

Enumeration of supported resource types.
enum class ResourceType {
    File,         // Generic file
    Image,        // Texture/image file
    SpecularMap,  // Specular map texture
    Audio,        // Audio file
    Font,         // Font file
    Model         // 3D model file
};

Resource Struct

Represents a single resource in the workspace.
struct Resource {
    fs::path path;              // Filesystem path to the asset
    std::string name;           // Human-readable name for queries
    ResourceType type;          // Resource type tag
};

Usage Example

// Create a texture resource
Resource texture = Workspace::get().createResource(
    "textures/brick.png",
    "BrickTexture",
    ResourceType::Image
);

// Create an audio resource
Resource music = Workspace::get().createResource(
    "audio/theme.mp3",
    "ThemeMusic",
    ResourceType::Audio
);

// Create a font resource
Resource font = Workspace::get().createResource(
    "fonts/arial.ttf",
    "Arial",
    ResourceType::Font
);

ResourceGroup Struct

Represents a collection of related resources.
struct ResourceGroup {
    std::string groupName;              // Group identifier
    std::vector<Resource> resources;    // Resources in this group
    
    // Find a resource by name within this group
    Resource findResource(const std::string &name);
};

Usage Example

// Create resources for a skybox
Resource right = Workspace::get().createResource(
    "skybox/px.png", "RightSkybox", ResourceType::Image);
Resource left = Workspace::get().createResource(
    "skybox/nx.png", "LeftSkybox", ResourceType::Image);
Resource top = Workspace::get().createResource(
    "skybox/py.png", "TopSkybox", ResourceType::Image);
Resource bottom = Workspace::get().createResource(
    "skybox/ny.png", "BottomSkybox", ResourceType::Image);
Resource front = Workspace::get().createResource(
    "skybox/pz.png", "FrontSkybox", ResourceType::Image);
Resource back = Workspace::get().createResource(
    "skybox/nz.png", "BackSkybox", ResourceType::Image);

// Group them together
ResourceGroup skyboxGroup = Workspace::get().createResourceGroup(
    "Skybox",
    {right, left, top, bottom, front, back}
);

// Use the group to create a cubemap
Cubemap skybox = Cubemap::fromResourceGroup(skyboxGroup);

Workspace Class

Singleton class that manages all resources and resource groups.
class Workspace {
public:
    // Get singleton instance
    static Workspace &get();
    
    // Resource management
    Resource createResource(const fs::path &path,
                          const std::string &name,
                          ResourceType type = ResourceType::File);
    
    Resource getResource(const std::string &name);
    std::vector<Resource> getAllResources();
    std::vector<Resource> getResourcesByType(ResourceType type);
    
    // Resource group management
    ResourceGroup createResourceGroup(const std::string &groupName,
                                     const std::vector<Resource> &initResources);
    
    ResourceGroup getResourceGroup(const std::string &groupName);
    std::vector<ResourceGroup> getAllResourceGroups();
    
    // Root path configuration
    void setRootPath(const fs::path &path);
};

Basic Usage

Initialize Workspace

void initialize(Window &window) override {
    // Set the root path for all resources
    Workspace::get().setRootPath(std::string(TEST_PATH) + "/resources/");
    
    // Now all resource paths are relative to this root
}

Create and Use Textures

// Create texture resources
Resource waterDUDV = Workspace::get().createResource(
    "water_dudv.png",
    "WaterDUDV",
    ResourceType::Image
);

Resource waterNormal = Workspace::get().createResource(
    "water_normal.png",
    "WaterNormal",
    ResourceType::Image
);

// Use resources to load textures
Texture dudvTexture = Texture::fromResource(waterDUDV);
Texture normalTexture = Texture::fromResource(waterNormal);

// Apply textures to objects
Fluid water;
water.movementTexture = dudvTexture;
water.normalTexture = normalTexture;

Create and Use Audio

class BackpackAttach : public Component {
public:
    void init() override {
        // Create audio resource
        Resource audioResource = Workspace::get().createResource(
            "exampleMP3.mp3",
            "ExampleAudio",
            ResourceType::Audio
        );
        
        // Get audio player component
        auto player = this->object->getComponent<AudioPlayer>();
        
        // Set the audio source
        player->setSource(audioResource);
        player->useSpatialization();
        player->source->setLooping(true);
        player->play();
    }
};

Create and Use Fonts

// Create font resource
Resource fontResource = Workspace::get().createResource(
    "arial.ttf",
    "Arial",
    ResourceType::Font
);

// Use font to create text
Text fpsText(
    "FPS: 0",
    Font::fromResource("Arial", fontResource, 24),
    {25.0f, 25.0f},
    Color::white()
);

window.addUIObject(&fpsText);

Complete Example: Scene Setup

class MainScene : public Scene {
    CoreObject ground;
    Fluid water;
    Text fpsText;
    Cubemap skybox;
    
public:
    void initialize(Window &window) override {
        // Set workspace root path
        Workspace::get().setRootPath("assets/");
        
        // Create texture resources
        Resource groundTex = Workspace::get().createResource(
            "textures/ground.png",
            "GroundTexture",
            ResourceType::Image
        );
        
        Resource groundSpec = Workspace::get().createResource(
            "textures/ground_spec.png",
            "GroundSpecular",
            ResourceType::SpecularMap
        );
        
        // Load textures from resources
        Texture albedo = Texture::fromResource(groundTex);
        Texture specular = Texture::fromResource(groundSpec);
        
        // Create ground object with textures
        ground = createBox({10.0f, 0.1f, 10.0f});
        ground.material.albedo = albedo;
        ground.material.specular = specular;
        window.addObject(&ground);
        
        // Create skybox from resource group
        skybox = createSkybox();
        this->setSkybox(skybox);
        
        // Create UI with font resource
        Resource fontRes = Workspace::get().createResource(
            "fonts/roboto.ttf",
            "Roboto",
            ResourceType::Font
        );
        
        fpsText = Text(
            "FPS: 0",
            Font::fromResource("Roboto", fontRes, 18),
            {10.0f, 10.0f},
            Color::white()
        );
        window.addUIObject(&fpsText);
    }
    
private:
    Cubemap createSkybox() {
        // Create individual skybox face resources
        Resource right = Workspace::get().createResource(
            "skybox/right.jpg", "SkyboxRight", ResourceType::Image);
        Resource left = Workspace::get().createResource(
            "skybox/left.jpg", "SkyboxLeft", ResourceType::Image);
        Resource top = Workspace::get().createResource(
            "skybox/top.jpg", "SkyboxTop", ResourceType::Image);
        Resource bottom = Workspace::get().createResource(
            "skybox/bottom.jpg", "SkyboxBottom", ResourceType::Image);
        Resource front = Workspace::get().createResource(
            "skybox/front.jpg", "SkyboxFront", ResourceType::Image);
        Resource back = Workspace::get().createResource(
            "skybox/back.jpg", "SkyboxBack", ResourceType::Image);
        
        // Create resource group
        ResourceGroup group = Workspace::get().createResourceGroup(
            "MainSkybox",
            {right, left, top, bottom, front, back}
        );
        
        // Create cubemap from group
        return Cubemap::fromResourceGroup(group);
    }
};

Query Resources

// Get a specific resource by name
Resource texture = Workspace::get().getResource("BrickTexture");

// Get all resources
std::vector<Resource> allResources = Workspace::get().getAllResources();

// Get resources by type
std::vector<Resource> allTextures = 
    Workspace::get().getResourcesByType(ResourceType::Image);

std::vector<Resource> allAudio = 
    Workspace::get().getResourcesByType(ResourceType::Audio);

// Get a resource group
ResourceGroup skybox = Workspace::get().getResourceGroup("Skybox");

// Find resource within a group
Resource topFace = skybox.findResource("TopSkybox");

// Get all resource groups
std::vector<ResourceGroup> allGroups = 
    Workspace::get().getAllResourceGroups();

Advanced Example: Dynamic Resource Loading

class AssetManager {
public:
    void loadLevel(const std::string &levelName) {
        std::string levelPath = "levels/" + levelName + "/";
        
        // Load all textures for this level
        loadLevelTextures(levelPath);
        
        // Load all audio for this level
        loadLevelAudio(levelPath);
        
        // Load all models for this level
        loadLevelModels(levelPath);
    }
    
private:
    void loadLevelTextures(const std::string &path) {
        std::vector<std::string> textures = {
            "ground.png", "wall.png", "ceiling.png"
        };
        
        for (const auto &tex : textures) {
            std::string name = extractName(tex);
            Workspace::get().createResource(
                path + "textures/" + tex,
                name,
                ResourceType::Image
            );
        }
    }
    
    void loadLevelAudio(const std::string &path) {
        std::vector<std::string> sounds = {
            "ambient.mp3", "music.mp3"
        };
        
        for (const auto &sound : sounds) {
            std::string name = extractName(sound);
            Workspace::get().createResource(
                path + "audio/" + sound,
                name,
                ResourceType::Audio
            );
        }
    }
    
    void loadLevelModels(const std::string &path) {
        // Load level models...
    }
    
    std::string extractName(const std::string &filename) {
        // Extract name without extension
        size_t lastDot = filename.find_last_of(".");
        return filename.substr(0, lastDot);
    }
};

Best Practices

  1. Set root path early: Call setRootPath() in scene initialization
  2. Use descriptive names: Make resource names clear and searchable
  3. Group related resources: Use ResourceGroup for skyboxes, material sets, etc.
  4. Use appropriate types: Tag resources with the correct ResourceType
  5. Cache resource references: Store frequently used resources instead of querying repeatedly
  6. Organize by feature: Group resources logically (e.g., “PlayerTextures”, “UIFonts”)
  7. Use relative paths: Paths are relative to the workspace root
  8. Check resource existence: Verify resources are loaded before using them

Build docs developers (and LLMs) love