Skip to content

Commit

Permalink
Improve error handling in AssetLoader
Browse files Browse the repository at this point in the history
  • Loading branch information
mogemimi committed Oct 6, 2019
1 parent 985692d commit 8f5200b
Show file tree
Hide file tree
Showing 18 changed files with 717 additions and 875 deletions.
117 changes: 72 additions & 45 deletions build/pomdog.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

22 changes: 13 additions & 9 deletions build/pomdog/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ source_group(Audio REGULAR_EXPRESSION "(include/Pomdog|sr
source_group(Basic REGULAR_EXPRESSION "(include/Pomdog|src)/Basic/*")
source_group(Content REGULAR_EXPRESSION "(include/Pomdog|src)/Content/*")
source_group(Content\\AssetBuilders REGULAR_EXPRESSION "(include/Pomdog|src)/Content/AssetBuilders/*")
source_group(Content\\AssetLoaders REGULAR_EXPRESSION "(include/Pomdog|src)/Content/AssetLoaders/*")
source_group(Content\\Audio REGULAR_EXPRESSION "(include/Pomdog|src)/Content/Audio/*")
source_group(Content\\Image REGULAR_EXPRESSION "(include/Pomdog|src)/Content/Image/*")
source_group(Content\\Utility REGULAR_EXPRESSION "(include/Pomdog|src)/Content/Utility/*")
source_group(Graphics REGULAR_EXPRESSION "(include/Pomdog|src)/Graphics/*")
source_group(Graphics\\ShaderCompilers REGULAR_EXPRESSION "(include/Pomdog|src)/Graphics/ShaderCompilers/*")
Expand Down Expand Up @@ -85,13 +88,17 @@ set(POMDOG_SOURCES_CORE
${POMDOG_DIR}/include/Pomdog/Content/AssetBuilders/PipelineStateBuilder.hpp
${POMDOG_DIR}/include/Pomdog/Content/AssetBuilders/ShaderBuilder.hpp
${POMDOG_DIR}/include/Pomdog/Content/Utility/BinaryFileStream.hpp
${POMDOG_DIR}/include/Pomdog/Content/Audio/WAV.hpp
${POMDOG_DIR}/include/Pomdog/Content/Image/ImageBuffer.hpp
${POMDOG_DIR}/include/Pomdog/Content/Image/DDS.hpp
${POMDOG_DIR}/include/Pomdog/Content/Image/PNG.hpp
${POMDOG_DIR}/include/Pomdog/Content/Utility/BinaryReader.hpp
${POMDOG_DIR}/include/Pomdog/Content/Utility/MakeFourCC.hpp
${POMDOG_DIR}/include/Pomdog/Content/detail/AssetDictionary.hpp
${POMDOG_DIR}/include/Pomdog/Content/detail/AssetLoaderContext.hpp
${POMDOG_DIR}/include/Pomdog/Content/detail/AssetLoader.hpp
${POMDOG_DIR}/include/Pomdog/Content/detail/AssetLoaders/AudioClipLoader.hpp
${POMDOG_DIR}/include/Pomdog/Content/detail/AssetLoaders/Texture2DLoader.hpp
${POMDOG_DIR}/include/Pomdog/Content/AssetLoaders/AssetLoader.hpp
${POMDOG_DIR}/include/Pomdog/Content/AssetLoaders/AudioClipLoader.hpp
${POMDOG_DIR}/include/Pomdog/Content/AssetLoaders/Texture2DLoader.hpp
${POMDOG_DIR}/include/Pomdog/Graphics/Blend.hpp
${POMDOG_DIR}/include/Pomdog/Graphics/BlendDescription.hpp
${POMDOG_DIR}/include/Pomdog/Graphics/BlendOperation.hpp
Expand Down Expand Up @@ -255,12 +262,9 @@ set(POMDOG_SOURCES_CORE
${POMDOG_DIR}/src/Content/AssetBuilders/ShaderBuilder.cpp
${POMDOG_DIR}/src/Content/AssetLoaders/AudioClipLoader.cpp
${POMDOG_DIR}/src/Content/AssetLoaders/Texture2DLoader.cpp
${POMDOG_DIR}/src/Content/Utility/DDSTextureReader.cpp
${POMDOG_DIR}/src/Content/Utility/DDSTextureReader.hpp
${POMDOG_DIR}/src/Content/Utility/MSWaveAudioLoader.cpp
${POMDOG_DIR}/src/Content/Utility/MSWaveAudioLoader.hpp
${POMDOG_DIR}/src/Content/Utility/PNGTextureReader.cpp
${POMDOG_DIR}/src/Content/Utility/PNGTextureReader.hpp
${POMDOG_DIR}/src/Content/Audio/WAV.cpp
${POMDOG_DIR}/src/Content/Image/DDS.cpp
${POMDOG_DIR}/src/Content/Image/PNG.cpp
${POMDOG_DIR}/src/Graphics/ConstantBuffer.cpp
${POMDOG_DIR}/src/Graphics/EffectBinaryParameter.cpp
${POMDOG_DIR}/src/Graphics/EffectReflection.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
#pragma once

#include "Pomdog/Basic/Export.hpp"
#include "Pomdog/Content/detail/AssetLoader.hpp"
#include "Pomdog/Content/AssetLoaders/AssetLoader.hpp"
#include "Pomdog/Utility/Errors.hpp"
#include <memory>
#include <string>
#include <tuple>

namespace Pomdog {
class AssetManager;
class AudioClip;
} // namespace Pomdog

namespace Pomdog::Detail {

class AssetLoaderContext;

template <>
struct POMDOG_EXPORT AssetLoader<AudioClip> final {
std::shared_ptr<AudioClip> operator()(
const AssetLoaderContext& loaderContext,
const std::string& assetName);
[[nodiscard]] std::tuple<std::shared_ptr<AudioClip>, std::shared_ptr<Error>>
operator()(AssetManager& assets, const std::string& filePath);
};

} // namespace Pomdog::Detail
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
#pragma once

#include "Pomdog/Basic/Export.hpp"
#include "Pomdog/Content/detail/AssetLoader.hpp"
#include "Pomdog/Content/AssetLoaders/AssetLoader.hpp"
#include "Pomdog/Utility/Errors.hpp"
#include <memory>
#include <string>
#include <tuple>

namespace Pomdog {
class AssetManager;
class Texture2D;
} // namespace Pomdog

namespace Pomdog::Detail {

class AssetLoaderContext;

template <>
struct POMDOG_EXPORT AssetLoader<Texture2D> final {
std::shared_ptr<Texture2D> operator()(
const AssetLoaderContext& loaderContext,
const std::string& assetName);
[[nodiscard]] std::tuple<std::shared_ptr<Texture2D>, std::shared_ptr<Error>>
operator()(AssetManager& assets, const std::string& filePath);
};

} // namespace Pomdog::Detail
21 changes: 21 additions & 0 deletions include/Pomdog/Content/Audio/WAV.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2013-2019 mogemimi. Distributed under the MIT license.

#pragma once

#include "Pomdog/Audio/detail/ForwardDeclarations.hpp"
#include "Pomdog/Basic/Export.hpp"
#include "Pomdog/Utility/Errors.hpp"
#include <cstddef>
#include <fstream>
#include <memory>
#include <tuple>
#include <vector>

namespace Pomdog::WAV {

/// Reads an audio data from Waveform Audio File (.wav) format data.
[[nodiscard]] POMDOG_EXPORT
std::tuple<std::shared_ptr<AudioClip>, std::shared_ptr<Error>>
Load(std::ifstream&& stream, std::size_t byteLength);

} // namespace Pomdog::WAV
20 changes: 20 additions & 0 deletions include/Pomdog/Content/Image/DDS.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2013-2019 mogemimi. Distributed under the MIT license.

#pragma once

#include "Pomdog/Basic/Export.hpp"
#include "Pomdog/Content/Image/ImageBuffer.hpp"
#include "Pomdog/Utility/Errors.hpp"
#include <cstddef>
#include <cstdint>
#include <memory>
#include <tuple>

namespace Pomdog::DDS {

/// Reads a DDS image from data (.dds).
[[nodiscard]] POMDOG_EXPORT
std::tuple<ImageBuffer, std::shared_ptr<Error>>
Decode(const std::uint8_t* data, std::size_t size);

} // namespace Pomdog::DDS
36 changes: 36 additions & 0 deletions include/Pomdog/Content/Image/ImageBuffer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2013-2019 mogemimi. Distributed under the MIT license.

#pragma once

#include "Pomdog/Basic/Export.hpp"
#include "Pomdog/Graphics/SurfaceFormat.hpp"
#include <cstdint>
#include <memory>
#include <vector>

namespace Pomdog {

struct POMDOG_EXPORT ImageBuffer final {
/// Raw pixel data.
std::vector<std::uint8_t> RawData;

/// Pointer to pixel data array.
const std::uint8_t* PixelData = nullptr;

/// Size of byte array of pixel data.
std::size_t ByteLength = 0;

/// Width of the image in pixels.
std::int32_t Width = 1;

/// Height of the image in pixels.
std::int32_t Height = 1;

/// The number of mipmap levels in a multilevel texture.
std::int32_t MipmapCount = 0;

/// Surface format of the image.
SurfaceFormat Format = SurfaceFormat::R8_UNorm;
};

} // namespace Pomdog
20 changes: 20 additions & 0 deletions include/Pomdog/Content/Image/PNG.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2013-2019 mogemimi. Distributed under the MIT license.

#pragma once

#include "Pomdog/Basic/Export.hpp"
#include "Pomdog/Content/Image/ImageBuffer.hpp"
#include "Pomdog/Utility/Errors.hpp"
#include <cstddef>
#include <cstdint>
#include <memory>
#include <tuple>

namespace Pomdog::PNG {

/// Reads a PNG image from data (.png).
[[nodiscard]] POMDOG_EXPORT
std::tuple<ImageBuffer, std::shared_ptr<Error>>
Decode(const std::uint8_t* data, std::size_t size);

} // namespace Pomdog::PNG
54 changes: 35 additions & 19 deletions src/Content/AssetLoaders/AudioClipLoader.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Copyright (c) 2013-2019 mogemimi. Distributed under the MIT license.

#include "Pomdog/Content/detail/AssetLoaders/AudioClipLoader.hpp"
#include "../Utility/MSWaveAudioLoader.hpp"
#include "Pomdog/Content/AssetLoaders/AudioClipLoader.hpp"
#include "Pomdog/Audio/AudioClip.hpp"
#include "Pomdog/Content/Audio/WAV.hpp"
#include "Pomdog/Content/Utility/BinaryReader.hpp"
#include "Pomdog/Content/Utility/MakeFourCC.hpp"
#include "Pomdog/Content/detail/AssetLoaderContext.hpp"
#include "Pomdog/Content/AssetManager.hpp"
#include "Pomdog/Utility/Assert.hpp"
#include "Pomdog/Utility/Exception.hpp"
#include "Pomdog/Utility/FileSystem.hpp"
#include <fstream>
#include <memory>
#include <string>
Expand All @@ -16,37 +17,51 @@

namespace Pomdog::Detail {

std::shared_ptr<AudioClip> AssetLoader<AudioClip>::operator()(
const AssetLoaderContext& loaderContext, const std::string& assetName)
std::tuple<std::shared_ptr<AudioClip>, std::shared_ptr<Error>>
AssetLoader<AudioClip>::operator()([[maybe_unused]] AssetManager& assets, const std::string& filePath)
{
auto binaryStream = loaderContext.OpenStream(assetName);
std::ifstream stream{filePath, std::ifstream::binary};

if (!binaryStream.Stream) {
POMDOG_THROW_EXCEPTION(std::runtime_error,
"Cannot open the wave file: " + assetName);
if (!stream) {
auto err = Errors::New("cannot open the file, " + filePath);
return std::make_tuple(nullptr, std::move(err));
}

if (binaryStream.SizeInBytes < (sizeof(std::uint8_t) * 12)) {
POMDOG_THROW_EXCEPTION(std::runtime_error,
"The audio file is too small: " + assetName);
auto[byteLength, sizeErr] = FileSystem::GetFileSize(filePath);
if (sizeErr != nullptr) {
auto err = Errors::Wrap(std::move(sizeErr), "failed to get file size, " + filePath);
return std::make_tuple(nullptr, std::move(err));
}

auto & stream = binaryStream.Stream;
POMDOG_ASSERT(stream);

if (byteLength < (sizeof(std::uint8_t) * 12)) {
auto err = Errors::New("The audio file is too small " + filePath);
return std::make_tuple(nullptr, std::move(err));
}

auto signature = BinaryReader::ReadArray<std::uint8_t, 12>(stream);
if (stream.fail()) {
POMDOG_THROW_EXCEPTION(std::runtime_error,
"Failed to read the audio file.");
auto err = Errors::New("failed to read signature in the file " + filePath);
return std::make_tuple(nullptr, std::move(err));
}

stream.clear();
stream.seekg(0, std::ios_base::beg);

const auto fourCC = MakeFourCC(signature[0], signature[1], signature[2], signature[3]);

if (fourCC == MakeFourCC('R', 'I', 'F', 'F')) {
const auto fccType = MakeFourCC(signature[8], signature[9], signature[10], signature[11]);
if (fccType == MakeFourCC('W', 'A', 'V', 'E')) {
// This file format is RIFF waveform audio.
auto audioClip = MSWaveAudioLoader::Load(std::move(binaryStream));
return std::move(audioClip);
// NOTE: This file format is RIFF waveform audio.
auto[audioClip, loadErr] = WAV::Load(std::move(stream), byteLength);

if (loadErr != nullptr) {
auto err = Errors::Wrap(std::move(loadErr), "Cannot load the wave file " + filePath);
return std::make_tuple(nullptr, std::move(err));
}
return std::make_tuple(std::move(audioClip), nullptr);
}
}
else if (fourCC == MakeFourCC('O', 'g', 'g', 'S')) {
Expand All @@ -55,7 +70,8 @@ std::shared_ptr<AudioClip> AssetLoader<AudioClip>::operator()(
"Pomdog does not yet supported Ogg Vorbis format.");
}

POMDOG_THROW_EXCEPTION(std::runtime_error, "Not implemented.");
auto err = Errors::New("This audio file format is not supported " + filePath);
return std::make_tuple(nullptr, std::move(err));
}

} // namespace Pomdog::Detail
Loading

0 comments on commit 8f5200b

Please sign in to comment.