Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asset packer generates function for getting asset by name #98

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

felipemanga
Copy link

By adding an "index" to an entry in asset.yml, we can remove the need to manually register files with add_buffer_file.
The intent is that File::open would call the generated get_asset_by_name function.

Alternatively, it could generate a function that contains multiple add_buffer_file calls, but I'd like to avoid having a large hash map in RAM.

If no asset has an index property, no function is generated, therefore having no impact on existing code.

Example assets.yml:

assets.cpp:
  data/mission_1.i16:
    index: data/mission_1.i16
    name: mission_1
    type: raw/binary

Example assets.cpp:

// Auto Generated File - DO NOT EDIT!
#include <string>
#include <assets.hpp>

const uint8_t mission_1[] = {
...
};

std::pair<const uint8_t*, uint32_t> get_asset_by_name(const std::string& name) {
    struct Entry {
        const char *name;
        const uint8_t *data;
        uint32_t size;
    };
    static const Entry entries[] = {
        {"data/mission_1.i16", mission_1, sizeof(mission_1)}
    };
    for (uint32_t i = 0; i < sizeof(entries)/sizeof(entries[0]); ++i) {
        if (name == entries[i].name)
            return {entries[i].data, entries[i].size};
    }
    return {nullptr, 0};
}

@Daft-Freak
Copy link
Collaborator

This currently breaks a few things:

tests/test_asset.py F                                                     [  1%]
tests/test_cmake.py .....                                                 [ 10%]
tests/test_dfu_cli.py ...                                                 [ 16%]
tests/test_font.py ..                                                     [ 19%]
tests/test_image_cli.py .FF.FF..F..                                       [ 39%]
tests/test_image_struct.py .                                              [ 41%]
tests/test_map.py .....                                                   [ 50%]
tests/test_map_cli.py .F                                                  [ 53%]
tests/test_metadata.py ..........                                         [ 71%]
tests/test_packer_cli.py .......                                          [ 83%]
tests/test_palette.py ..                                                  [ 87%]
tests/test_raw.py .                                                       [ 89%]
tests/test_relocs.py ..                                                   [ 92%]
tests/test_setup.py ..                                                    [ 96%]
tests/test_setup_cli.py .                                                 [ 98%]
tests/test_version.py .                                                   [100%]

=================================== FAILURES ====================================
___________________________ test_formatter_components ___________________________

    def test_formatter_components():
        """Verify formatter results contain the declared components."""
        data = 'hello', b'hello'
        path = pathlib.Path('/no/such/path')
    
        for name, formatter in AssetFormatter._by_name.items():
>           fragments = formatter.fragments(*data)
E           TypeError: c_source() missing 1 required positional argument: 'path'

tests/test_asset.py:12: TypeError
______________________________ test_image_png_cli _______________________________

test_input_file = <tempfile._TemporaryFileWrapper object at 0x7f661298e6e0>

    def test_image_png_cli(test_input_file):
        from ttblit import main
    
        with pytest.raises(SystemExit):
>           main(['image', '--input_file', test_input_file.name, '--output_format', 'c_header'])

tests/test_image_cli.py:26: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/click/core.py:1128: in __call__
    return self.main(*args, **kwargs)
/usr/lib/python3/dist-packages/click/core.py:1053: in main
    rv = self.invoke(ctx)
/usr/lib/python3/dist-packages/click/core.py:1659: in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
/usr/lib/python3/dist-packages/click/core.py:1395: in invoke
    return ctx.invoke(self.callback, **ctx.params)
/usr/lib/python3/dist-packages/click/core.py:754: in invoke
    return __callback(*args, **kwargs)
ttblit/asset/builder.py:110: in cmd
    aw.write(output_format, output_file, force, report=False)
ttblit/asset/writer.py:41: in write
    fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

.0 = <dict_itemiterator object at 0x7f661299d3f0>

>   fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
E   TypeError: c_header() takes 2 positional arguments but 3 were given

ttblit/asset/writer.py:41: TypeError
__________________________ test_image_png_cli_unpacked __________________________

test_input_file = <tempfile._TemporaryFileWrapper object at 0x7f6614397e80>

    def test_image_png_cli_unpacked(test_input_file):
        from ttblit import main
    
        with pytest.raises(SystemExit):
>           main(['image', '--input_file', test_input_file.name, '--packed', 'no', '--output_format', 'c_header'])

tests/test_image_cli.py:33: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/click/core.py:1128: in __call__
    return self.main(*args, **kwargs)
/usr/lib/python3/dist-packages/click/core.py:1053: in main
    rv = self.invoke(ctx)
/usr/lib/python3/dist-packages/click/core.py:1659: in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
/usr/lib/python3/dist-packages/click/core.py:1395: in invoke
    return ctx.invoke(self.callback, **ctx.params)
/usr/lib/python3/dist-packages/click/core.py:754: in invoke
    return __callback(*args, **kwargs)
ttblit/asset/builder.py:110: in cmd
    aw.write(output_format, output_file, force, report=False)
ttblit/asset/writer.py:41: in write
    fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

.0 = <dict_itemiterator object at 0x7f6613a0a6b0>

>   fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
E   TypeError: c_header() takes 2 positional arguments but 3 were given

ttblit/asset/writer.py:41: TypeError
_____________________ test_image_png_cli_strict_palette_act _____________________

test_input_file = <tempfile._TemporaryFileWrapper object at 0x7f66143d8880>

    def test_image_png_cli_strict_palette_act(test_input_file):
        from ttblit import main
    
        with tempfile.NamedTemporaryFile('wb', suffix='.act') as test_palette_file:
            test_palette_file.write(b'\x00\x00\x00')  # Write black colour
            test_palette_file.write(b'\x00\xff\x00')  # Write green colour
            test_palette_file.write(b'\xff\xff\xff')  # Write white colour
            test_palette_file.write(b'\x00' * 759)  # Pad to 772 bytes
            test_palette_file.write(b'\x00\x03')  # Write size
            test_palette_file.write(b'\x00\x00')  # Ignored bytes
            test_palette_file.flush()
            with pytest.raises(SystemExit):
>               main(['image', '--input_file', test_input_file.name, '--output_format', 'c_header', '--strict', '--palette', test_palette_file.name])

tests/test_image_cli.py:55: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/click/core.py:1128: in __call__
    return self.main(*args, **kwargs)
/usr/lib/python3/dist-packages/click/core.py:1053: in main
    rv = self.invoke(ctx)
/usr/lib/python3/dist-packages/click/core.py:1659: in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
/usr/lib/python3/dist-packages/click/core.py:1395: in invoke
    return ctx.invoke(self.callback, **ctx.params)
/usr/lib/python3/dist-packages/click/core.py:754: in invoke
    return __callback(*args, **kwargs)
ttblit/asset/builder.py:110: in cmd
    aw.write(output_format, output_file, force, report=False)
ttblit/asset/writer.py:41: in write
    fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

.0 = <dict_itemiterator object at 0x7f66143bb740>

>   fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
E   TypeError: c_header() takes 2 positional arguments but 3 were given

ttblit/asset/writer.py:41: TypeError
_____________________ test_image_png_cli_strict_palette_pal _____________________

test_input_file = <tempfile._TemporaryFileWrapper object at 0x7f6613a27a90>

    def test_image_png_cli_strict_palette_pal(test_input_file):
        from ttblit import main
    
        with tempfile.NamedTemporaryFile('wb', suffix='.pal') as test_palette_file:
            test_palette_file.write(b'\x00\x00\x00')  # Write black colour
            test_palette_file.write(b'\x00\xff\x00')  # Write green colour
            test_palette_file.write(b'\xff\xff\xff')  # Write white colour
            test_palette_file.write(b'\x00' * (768 - 9))  # Pad to 768 bytes
            test_palette_file.flush()
            with pytest.raises(SystemExit):
>               main(['image', '--input_file', test_input_file.name, '--output_format', 'c_header', '--strict', '--palette', test_palette_file.name])

tests/test_image_cli.py:68: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/click/core.py:1128: in __call__
    return self.main(*args, **kwargs)
/usr/lib/python3/dist-packages/click/core.py:1053: in main
    rv = self.invoke(ctx)
/usr/lib/python3/dist-packages/click/core.py:1659: in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
/usr/lib/python3/dist-packages/click/core.py:1395: in invoke
    return ctx.invoke(self.callback, **ctx.params)
/usr/lib/python3/dist-packages/click/core.py:754: in invoke
    return __callback(*args, **kwargs)
ttblit/asset/builder.py:110: in cmd
    aw.write(output_format, output_file, force, report=False)
ttblit/asset/writer.py:41: in write
    fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

.0 = <dict_itemiterator object at 0x7f661299fc90>

>   fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
E   TypeError: c_header() takes 2 positional arguments but 3 were given

ttblit/asset/writer.py:41: TypeError
_______________ test_image_png_cli_strict_palette_pal_transparent _______________

test_input_file = <tempfile._TemporaryFileWrapper object at 0x7f66128aee00>

    def test_image_png_cli_strict_palette_pal_transparent(test_input_file):
        from ttblit import main
    
        with tempfile.NamedTemporaryFile('wb', suffix='.pal') as test_palette_file:
            test_palette_file.write(b'\x00\x00\x00')  # Write black colour
            test_palette_file.write(b'\x00\xff\x00')  # Write green colour
            test_palette_file.write(b'\xff\xff\xff')  # Write white colour
            test_palette_file.write(b'\x00' * (768 - 9))  # Pad to 768 bytes
            test_palette_file.flush()
    
            with pytest.raises(SystemExit):
>               main([
                    'image',
                    '--input_file', test_input_file.name,
                    '--output_format', 'c_header',
                    '--strict',
                    '--palette', test_palette_file.name,
                    '--transparent', '0,255,0'
                ])  # Make green transparent

tests/test_image_cli.py:101: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/click/core.py:1128: in __call__
    return self.main(*args, **kwargs)
/usr/lib/python3/dist-packages/click/core.py:1053: in main
    rv = self.invoke(ctx)
/usr/lib/python3/dist-packages/click/core.py:1659: in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
/usr/lib/python3/dist-packages/click/core.py:1395: in invoke
    return ctx.invoke(self.callback, **ctx.params)
/usr/lib/python3/dist-packages/click/core.py:754: in invoke
    return __callback(*args, **kwargs)
ttblit/asset/builder.py:110: in cmd
    aw.write(output_format, output_file, force, report=False)
ttblit/asset/writer.py:41: in write
    fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

.0 = <dict_itemiterator object at 0x7f6612a4c900>

>   fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
E   TypeError: c_header() takes 2 positional arguments but 3 were given

ttblit/asset/writer.py:41: TypeError
______________________________ test_map_tiled_cli _______________________________

test_input_file = <tempfile._TemporaryFileWrapper object at 0x7f6614397af0>

    def test_map_tiled_cli(test_input_file):
        from ttblit import main
    
        with pytest.raises(SystemExit):
>           main(['map', '--input_file', test_input_file.name, '--output_format', 'c_header'])

tests/test_map_cli.py:32: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/click/core.py:1128: in __call__
    return self.main(*args, **kwargs)
/usr/lib/python3/dist-packages/click/core.py:1053: in main
    rv = self.invoke(ctx)
/usr/lib/python3/dist-packages/click/core.py:1659: in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
/usr/lib/python3/dist-packages/click/core.py:1395: in invoke
    return ctx.invoke(self.callback, **ctx.params)
/usr/lib/python3/dist-packages/click/core.py:754: in invoke
    return __callback(*args, **kwargs)
ttblit/asset/builder.py:110: in cmd
    aw.write(output_format, output_file, force, report=False)
ttblit/asset/writer.py:41: in write
    fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

.0 = <dict_itemiterator object at 0x7f6612aa79c0>

>   fragments = [fmt.fragments(symbol, asset["data"], asset["path"]) for symbol, asset in assets]
E   TypeError: c_header() takes 2 positional arguments but 3 were given

ttblit/asset/writer.py:41: TypeError
============================ short test summary info ============================
FAILED tests/test_asset.py::test_formatter_components - TypeError: c_source() ...
FAILED tests/test_image_cli.py::test_image_png_cli - TypeError: c_header() tak...
FAILED tests/test_image_cli.py::test_image_png_cli_unpacked - TypeError: c_hea...
FAILED tests/test_image_cli.py::test_image_png_cli_strict_palette_act - TypeEr...
FAILED tests/test_image_cli.py::test_image_png_cli_strict_palette_pal - TypeEr...
FAILED tests/test_image_cli.py::test_image_png_cli_strict_palette_pal_transparent
FAILED tests/test_map_cli.py::test_map_tiled_cli - TypeError: c_header() takes...
========================= 7 failed, 49 passed in 20.68s =========================

Seems to be any output other than a .cpp file.

assets.hpp:
  image.png: asset_test

assets.bin:
  image.png: asset_test

Also, using individual tools always generates output with a get_asset_by_name function for the one asset.
(32blit image --input_file image.png --symbol_name image --output_file image.cpp)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants