Skip to content

Commit 260dfe4

Browse files
committed
Add a way to register image formats
1 parent b105751 commit 260dfe4

File tree

6 files changed

+93
-0
lines changed

6 files changed

+93
-0
lines changed

include/scratchcpp/scratchconfiguration.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace libscratchcpp
1111
{
1212

1313
class IExtension;
14+
class IImageFormat;
15+
class IImageFormatFactory;
1416
class ScratchConfigurationPrivate;
1517

1618
/*! \brief The ScratchConfiguration class provides methods for adding custom extensions. */
@@ -35,6 +37,10 @@ class LIBSCRATCHCPP_EXPORT ScratchConfiguration
3537
return nullptr;
3638
};
3739

40+
static void registerImageFormat(const std::string &name, std::shared_ptr<IImageFormatFactory> formatFactory);
41+
static void removeImageFormat(const std::string &name);
42+
static std::shared_ptr<IImageFormat> createImageFormat(const std::string &name);
43+
3844
private:
3945
static const std::vector<std::shared_ptr<IExtension>> getExtensions();
4046

src/scratchconfiguration.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// SPDX-License-Identifier: Apache-2.0
22

33
#include <scratchcpp/scratchconfiguration.h>
4+
#include <scratchcpp/iimageformatfactory.h>
45

56
#include "scratchconfiguration_p.h"
67
#include "blocks/standardblocks.h"
8+
#include "imageformats/stub/imageformatstub.h"
79

810
using namespace libscratchcpp;
911

@@ -21,6 +23,29 @@ IExtension *ScratchConfiguration::getExtension(const std::string &name)
2123
return impl->getExtension(name);
2224
}
2325

26+
/*! Registers the given image format. */
27+
void ScratchConfiguration::registerImageFormat(const std::string &name, std::shared_ptr<IImageFormatFactory> formatFactory)
28+
{
29+
impl->imageFormats[name] = formatFactory;
30+
}
31+
32+
/*! Removes the given image format. */
33+
void ScratchConfiguration::removeImageFormat(const std::string &name)
34+
{
35+
impl->imageFormats.erase(name);
36+
}
37+
38+
/*! Creates an instance of the given image format. If the format doesn't exist, a "stub" format will be created. */
39+
std::shared_ptr<IImageFormat> ScratchConfiguration::createImageFormat(const std::string &name)
40+
{
41+
auto it = impl->imageFormats.find(name);
42+
43+
if (it == impl->imageFormats.cend())
44+
return std::make_shared<ImageFormatStub>(); // use stub if the format doesn't exist
45+
else
46+
return it->second->createInstance();
47+
}
48+
2449
const std::vector<std::shared_ptr<IExtension>> ScratchConfiguration::getExtensions()
2550
{
2651
return impl->extensions;

src/scratchconfiguration_p.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,21 @@
77
#include <memory>
88
#include <string>
99
#include <vector>
10+
#include <unordered_map>
1011

1112
namespace libscratchcpp
1213
{
1314

1415
class IExtension;
16+
class IImageFormatFactory;
1517

1618
struct ScratchConfigurationPrivate
1719
{
1820
void registerExtension(std::shared_ptr<IExtension> extension);
1921
IExtension *getExtension(std::string name);
2022

2123
std::vector<std::shared_ptr<IExtension>> extensions = { std::make_shared<StandardBlocks>() };
24+
std::unordered_map<std::string, std::shared_ptr<IImageFormatFactory>> imageFormats;
2225
};
2326

2427
} // namespace libscratchcpp
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#pragma once
2+
3+
#include <scratchcpp/iimageformatfactory.h>
4+
#include <gmock/gmock.h>
5+
6+
using namespace libscratchcpp;
7+
8+
class ImageFormatFactoryMock : public IImageFormatFactory
9+
{
10+
public:
11+
MOCK_METHOD(std::shared_ptr<IImageFormat>, createInstance, (), (const, override));
12+
};

test/scratchconfiguration/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ add_executable(
1414
target_link_libraries(
1515
scratchconfiguration_test
1616
GTest::gtest_main
17+
GTest::gmock_main
1718
scratchcpp
19+
scratchcpp_mocks
1820
)
1921

2022
gtest_discover_tests(scratchconfiguration_test)

test/scratchconfiguration/scratchconfiguration_test.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
#include <scratchcpp/scratchconfiguration.h>
2+
#include <imageformatfactorymock.h>
23

34
#include "../common.h"
5+
#include "imageformats/stub/imageformatstub.h"
46
#include "extension1.h"
57
#include "extension2.h"
68
#include "extension3.h"
79

810
using namespace libscratchcpp;
911

12+
using ::testing::Return;
13+
1014
class ScratchConfigurationTest : public testing::Test
1115
{
1216
public:
@@ -15,11 +19,15 @@ class ScratchConfigurationTest : public testing::Test
1519
m_extension1 = std::make_shared<Extension1>();
1620
m_extension2 = std::make_shared<Extension2>();
1721
m_extension3 = std::make_shared<Extension3>();
22+
m_imageFormatMock1 = std::make_shared<ImageFormatFactoryMock>();
23+
m_imageFormatMock2 = std::make_shared<ImageFormatFactoryMock>();
1824
}
1925

2026
std::shared_ptr<IExtension> m_extension1;
2127
std::shared_ptr<IExtension> m_extension2;
2228
std::shared_ptr<IExtension> m_extension3;
29+
std::shared_ptr<ImageFormatFactoryMock> m_imageFormatMock1;
30+
std::shared_ptr<ImageFormatFactoryMock> m_imageFormatMock2;
2331
};
2432

2533
TEST_F(ScratchConfigurationTest, Extensions)
@@ -35,3 +43,40 @@ TEST_F(ScratchConfigurationTest, Extensions)
3543
ASSERT_EQ(ScratchConfiguration::getExtension<Extension2>(), m_extension2.get());
3644
ASSERT_EQ(ScratchConfiguration::getExtension<Extension3>(), nullptr);
3745
}
46+
47+
TEST_F(ScratchConfigurationTest, ImageFormats)
48+
{
49+
ScratchConfiguration::registerImageFormat("format1", m_imageFormatMock1);
50+
ScratchConfiguration::registerImageFormat("format2", m_imageFormatMock2);
51+
auto format1 = std::make_shared<ImageFormatStub>();
52+
auto format2 = std::make_shared<ImageFormatStub>();
53+
54+
EXPECT_CALL(*m_imageFormatMock1, createInstance()).WillOnce(Return(format1));
55+
ASSERT_EQ(ScratchConfiguration::createImageFormat("format1"), format1);
56+
57+
EXPECT_CALL(*m_imageFormatMock2, createInstance()).WillOnce(Return(format2));
58+
ASSERT_EQ(ScratchConfiguration::createImageFormat("format2"), format2);
59+
60+
auto format = ScratchConfiguration::createImageFormat("format3");
61+
IImageFormat *unsupportedFormat = format.get();
62+
ASSERT_TRUE(unsupportedFormat);
63+
ASSERT_TRUE(dynamic_cast<ImageFormatStub *>(unsupportedFormat));
64+
65+
ScratchConfiguration::removeImageFormat("format1");
66+
format = ScratchConfiguration::createImageFormat("format1");
67+
unsupportedFormat = format.get();
68+
ASSERT_TRUE(unsupportedFormat);
69+
ASSERT_TRUE(dynamic_cast<ImageFormatStub *>(unsupportedFormat));
70+
71+
EXPECT_CALL(*m_imageFormatMock2, createInstance()).WillOnce(Return(format2));
72+
ASSERT_EQ(ScratchConfiguration::createImageFormat("format2"), format2);
73+
74+
ScratchConfiguration::removeImageFormat("format2");
75+
format = ScratchConfiguration::createImageFormat("format2");
76+
unsupportedFormat = format.get();
77+
ASSERT_TRUE(unsupportedFormat);
78+
ASSERT_TRUE(dynamic_cast<ImageFormatStub *>(unsupportedFormat));
79+
80+
testing::Mock::AllowLeak(m_imageFormatMock1.get());
81+
testing::Mock::AllowLeak(m_imageFormatMock2.get());
82+
}

0 commit comments

Comments
 (0)