init dump
This commit is contained in:
165
Sources/JolkEngine/Content/ContentManager.swift
Normal file
165
Sources/JolkEngine/Content/ContentManager.swift
Normal file
@ -0,0 +1,165 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
public protocol ContentLoaderParametersProtocol
|
||||
{
|
||||
associatedtype T: Resource
|
||||
}
|
||||
|
||||
public struct ContentManager
|
||||
{
|
||||
private var loaders = Dictionary<String, any LoaderProtocol>()
|
||||
private var resources = [any RendererResource]()
|
||||
private let renderer: Renderer
|
||||
private let bundle: Bundle
|
||||
}
|
||||
|
||||
extension ContentManager
|
||||
{
|
||||
internal init(_ renderer: inout Renderer, bundle: Bundle)
|
||||
{
|
||||
self.renderer = renderer
|
||||
self.bundle = bundle
|
||||
}
|
||||
|
||||
public mutating func setLoader<T: Resource, Loader: LoaderProtocol>(extensions exts: [String], loader: Loader) where Loader.T == T
|
||||
{
|
||||
for i in exts
|
||||
{
|
||||
setLoader(extension: i, loader: loader)
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func setLoader<T: Resource, Loader: LoaderProtocol>(extension ext: String, loader: Loader) where Loader.T == T
|
||||
{
|
||||
loaders[ext] = loader
|
||||
}
|
||||
|
||||
public mutating func create(mesh: Mesh) throws -> RenderMesh
|
||||
{
|
||||
let rendMesh = try renderer.createMesh(mesh: mesh)
|
||||
resources.append(rendMesh)
|
||||
return rendMesh
|
||||
}
|
||||
|
||||
public mutating func create(texture: Image, params: Texture2DParameters = .init()) throws -> Texture2D
|
||||
{
|
||||
try texture.pixels.withUnsafeBytes
|
||||
{
|
||||
raw in
|
||||
let data = raw.baseAddress!
|
||||
let rendTex = try renderer.createTexture(
|
||||
data: data, width: texture.width, height: texture.height,
|
||||
filter: params.magFilter, mipMode: params.mipMode)
|
||||
resources.append(rendTex)
|
||||
return Texture2D(id: rendTex, width: texture.width, height: texture.height)
|
||||
}
|
||||
}
|
||||
|
||||
public func getResource(_ path: String) throws -> URL
|
||||
{
|
||||
guard let extIndex = path.lastIndex(of: ".")
|
||||
else { throw ContentError.badPath }
|
||||
let name = String(path[..<extIndex]), ext = String(path[extIndex...])
|
||||
guard let resourceUrl: URL = bundle.url(
|
||||
forResource: name,
|
||||
withExtension: ext)
|
||||
else { throw ContentError.resourceNotFound }
|
||||
return resourceUrl
|
||||
}
|
||||
|
||||
public mutating func load<T: Resource>(_ path: String) throws -> T
|
||||
{
|
||||
let resourceUrl = try getResource(path)
|
||||
|
||||
let loader = loaders[resourceUrl.pathExtension]
|
||||
guard let resource = loader?.load(url: resourceUrl)
|
||||
else { throw ContentError.loadFailure }
|
||||
|
||||
if T.self == Mesh.self
|
||||
{
|
||||
guard let mesh = resource as? Mesh else { throw ContentError.loadFailure }
|
||||
return mesh as! T
|
||||
}
|
||||
if T.self == Image.self
|
||||
{
|
||||
guard let image = resource as? Image else { throw ContentError.loadFailure }
|
||||
return image as! T
|
||||
}
|
||||
if T.self == Texture2D.self
|
||||
{
|
||||
guard let image = resource as? Image else { throw ContentError.loadFailure }
|
||||
let texture2D = try self.create(texture: image)
|
||||
return texture2D as! T
|
||||
}
|
||||
throw ContentError.loadFailure
|
||||
}
|
||||
|
||||
public mutating func load<T: Resource, Params: ContentLoaderParametersProtocol>(_ path: String, params: Params) throws
|
||||
-> T where Params.T == T
|
||||
{
|
||||
let resourceUrl = try getResource(path)
|
||||
|
||||
let loader = loaders[resourceUrl.pathExtension]
|
||||
guard let resource = loader?.load(url: resourceUrl)
|
||||
else { throw ContentError.loadFailure }
|
||||
|
||||
if T.self == Mesh.self
|
||||
{
|
||||
guard let mesh = resource as? Mesh else { throw ContentError.loadFailure }
|
||||
return mesh as! T
|
||||
}
|
||||
if T.self == Image.self
|
||||
{
|
||||
guard let image = resource as? Image else { throw ContentError.loadFailure }
|
||||
return image as! T
|
||||
}
|
||||
if T.self == Texture2D.self
|
||||
{
|
||||
guard let image = resource as? Image else { throw ContentError.loadFailure }
|
||||
let texture2D = try self.create(texture: image, params: params as! Texture2DParameters)
|
||||
return texture2D as! T
|
||||
}
|
||||
throw ContentError.loadFailure
|
||||
}
|
||||
|
||||
public mutating func load<T: RendererResource>(_ path: String) throws -> T
|
||||
{
|
||||
let resourceUrl = try getResource(path)
|
||||
|
||||
let loader = loaders[resourceUrl.pathExtension]
|
||||
guard let resource = loader?.load(url: resourceUrl)
|
||||
else { throw ContentError.loadFailure }
|
||||
|
||||
if T.self == RenderMesh.self
|
||||
{
|
||||
guard let mesh = resource as? Mesh else { throw ContentError.loadFailure }
|
||||
let renderResource = try self.create(mesh: mesh)
|
||||
return renderResource as! T
|
||||
}
|
||||
throw ContentError.loadFailure
|
||||
}
|
||||
|
||||
internal mutating func releaseAll()
|
||||
{
|
||||
for resource in resources.reversed()
|
||||
{
|
||||
if resource is RenderMesh
|
||||
{
|
||||
renderer.deleteMesh(resource as! RenderMesh)
|
||||
}
|
||||
else if resource is RenderTexture2D
|
||||
{
|
||||
renderer.deleteTexture(resource as! RenderTexture2D)
|
||||
}
|
||||
}
|
||||
resources.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
public enum ContentError: Error
|
||||
{
|
||||
case badPath //else { fatalError("Malformed resource path \"\(path)\"") }
|
||||
case resourceNotFound //else { fatalError("Resource \"\(path)\" doesn't exist") }
|
||||
case loadFailure //else { fatalError("Failed to load resource \"\(path)\"") }
|
||||
}
|
Reference in New Issue
Block a user