import logging
from pathlib import Path
from typing import Any
import moderngl
import moderngl_window as mglw
from moderngl_window.finders import data, program, scene, texture
logger = logging.getLogger(__name__)
class BaseLoader:
"""Base loader class for all resources"""
kind = None
"""
The kind of resource this loaded supports.
This can be used when file extensions is not enough
to decide what loader should be selected.
"""
file_extensions = []
"""
A list defining the file extensions accepted by this loader.
Example::
# Loader will match .xyz and .xyz.gz files.
file_extensions = [
['.xyz'],
['.xyz', '.gz'],
]
"""
[docs] def __init__(self, meta):
"""Initialize loader.
Loaders take a ResourceDescription instance
containing all the parameters needed to load and initialize
this data.
Args:
meta (ResourceDescription): The resource to load
"""
self.meta = meta
if self.kind is None:
raise ValueError("Loader {} doesn't have a kind".format(self.__class__))
[docs] @classmethod
def supports_file(cls, meta):
"""Check if the loader has a supported file extension.
What extensions are supported can be defined in the
:py:attr:`file_extensions` class attribute.
"""
path = Path(meta.path)
for ext in cls.file_extensions:
if path.suffixes[: len(ext)] == ext:
return True
return False
[docs] def load(self) -> Any:
"""Loads a resource.
When creating a loader this is the only
method that needs to be implemented.
Returns:
The loaded resource
"""
raise NotImplementedError()
[docs] def find_data(self, path):
"""Find resource using data finders.
This is mainly a shortcut method to simplify the task.
Args:
path: Path to resource
"""
return self._find(Path(path), data.get_finders())
[docs] def find_program(self, path):
"""Find resource using program finders.
This is mainly a shortcut method to simplify the task.
Args:
path: Path to resource
"""
return self._find(Path(path), program.get_finders())
[docs] def find_texture(self, path):
"""Find resource using texture finders.
This is mainly a shortcut method to simplify the task.
Args:
path: Path to resource
"""
return self._find(Path(path), texture.get_finders())
[docs] def find_scene(self, path):
"""Find resource using scene finders.
This is mainly a shortcut method to simplify the task.
Args:
path: Path to resource
"""
return self._find(Path(path), scene.get_finders())
def _find(self, path: Path, finders: list):
"""Find the first occurrance of this path in all finders.
If the incoming path is an absolute path we assume this
path exist and return it.
Args:
path (Path): The path to find
"""
if not path:
return None
if path.is_absolute():
return path
for finder in finders:
result = finder.find(path)
if result:
return result
logger.debug("No finder was able to locate: %s", path)
return None
@property
def ctx(self) -> moderngl.Context:
"""moderngl.Context: ModernGL context"""
return mglw.ctx()