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

New patch decompiler #103

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

New patch decompiler #103

wants to merge 2 commits into from

Conversation

jhw
Copy link
Collaborator

@jhw jhw commented Nov 15, 2024

The existing patch decompiler no longer seemed to work (not sure why) so I improved and extended it somewhat

(env) jhw@Justins-Air radiant-voices % python src/python/rv/tools/patch_decompiler.py path/to/sunvox/examples
INFO: --- azzzx-bipoliaro4ka ---
INFO: pia-05-fil-22-amb-03-com-25-fil-26-azz-01
INFO: hh2-06-drg-02-lp-0D-com-1F-sou-0E-fil-0B-mix-1D-grm-1C-bsg-04-sc-0C-azz-01
{...}
(env) jhw@Justins-Air radiant-voices % ls -l tmp/decompiler 
total 0
drwxr-xr-x  4 jhw  staff  128 15 Nov 09:39 azzzx-bipoliaro4ka
drwxr-xr-x  4 jhw  staff  128 15 Nov 09:39 boomlinde-caravan
drwxr-xr-x  4 jhw  staff  128 15 Nov 09:39 csardascontinuum

Summary by Sourcery

Implement a new patch decompiler for SunVox projects, improving module chain parsing and pattern handling.

New Features:

  • Introduce a new patch decompiler that processes SunVox project files and extracts module chains and patterns.

Enhancements:

  • Refactor the module chain parsing to improve handling of module connections and indexing.
  • Enhance the pattern and track handling to better manage note data and module associations.

Copy link

sourcery-ai bot commented Nov 15, 2024

Reviewer's Guide by Sourcery

This PR implements a complete rewrite of the patch decompiler tool to improve its functionality and reliability. The new implementation focuses on better module chain parsing, more robust pattern handling, and cleaner data organization through new class structures.

Sequence diagram for decompiling a project

sequenceDiagram
    participant User
    participant Main
    participant Project
    participant ModuleChain
    participant PatternGroups
    participant Patch
    participant FileSystem

    User->>Main: Run decompile_project
    Main->>Project: Read SunVox file
    Project-->>Main: Return project data
    Main->>ModuleChain: Parse modules
    ModuleChain-->>Main: Return module chains
    Main->>PatternGroups: Parse timeline
    PatternGroups-->>Main: Return pattern groups
    Main->>Patch: Create patch for each chain
    Patch-->>Main: Return patch
    Main->>FileSystem: Dump SunVox and modules
    FileSystem-->>Main: Files created
    Main-->>User: Decompilation complete
Loading

Class diagram for the new patch decompiler

classDiagram
    class ModuleChain {
        +parse_modules(project)
        +clone_modules(project)
        +names()
        +indexes()
        +is_output(item)
    }
    class Track {
        +has_content()
    }
    class Tracks {
        +from_pattern_data(pattern_data)
        +filter_by_chain(chain, modules)
        +lengths()
        +to_pattern_data()
    }
    class PatternGroup {
        +mod_indexes()
        +master_tracks(chain, modules)
    }
    class PatternGroups {
        +parse_timeline(project)
        +filter_by_chain(chain, filter_fn)
    }
    ModuleChain --> Track
    ModuleChain --> Tracks
    Tracks --> Track
    PatternGroups --> PatternGroup
    PatternGroup --> Tracks
    Tracks --> PatternGroup
Loading

File-Level Changes

Change Details Files
Implemented new module chain parsing logic
  • Added ModuleChain.parse_modules() to replace expand()
  • Improved module relationship tracking using depth-first search
  • Added handling for invalid or missing modules
  • Implemented better chain representation with module names and indexes
src/python/rv/tools/patch_decompiler.py
Redesigned pattern and track handling system
  • Created new Track and Tracks classes for better pattern data organization
  • Added matrix rotation utilities for easier pattern data manipulation
  • Implemented content filtering in tracks based on module chains
  • Added pattern grouping functionality for better organization
src/python/rv/tools/patch_decompiler.py
Added new project processing and output functionality
  • Implemented create_patch() function to generate individual patches
  • Added JSON export capability for module configurations
  • Created separate dump functions for SunVox files and module data
  • Improved error handling and logging throughout the codebase
src/python/rv/tools/patch_decompiler.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @jhw - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Please provide a more detailed commit message explaining why the rewrite was necessary and what architectural changes were made. The current message "no longer seemed to work (not sure why)" doesn't give enough context for future maintenance.
Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

src/python/rv/tools/patch_decompiler.py Show resolved Hide resolved

class ModuleChain(list):

@staticmethod
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider simplifying the parse_modules method by combining module lookup with traversal logic.

The parse_modules method can be simplified while maintaining its functionality. Here's a cleaner approach that reduces nesting and combines the module lookup with traversal:

@staticmethod
def parse_modules(project):
    modules = project.modules

    def dfs(index):
        if not (0 <= index < len(modules)) or not modules[index]:
            return []

        mod = modules[index]
        current = (mod.name, mod.index)
        modules[index] = None  # Mark as visited

        # Base case - no input links
        if not mod.in_links:
            return [ModuleChain([current])]

        # Recursive case - build chains from inputs
        chains = []
        for prev_index in mod.in_links:
            for chain in dfs(prev_index):
                chains.append(ModuleChain(chain + [current]))

        return sorted(chains, key=lambda x: x[0][1])

    return dfs(0)

Key improvements:

  • Eliminates separate module dictionary creation
  • Uses in-place visited marking instead of a separate set
  • Reduces nesting levels in the traversal logic
  • Maintains the same module relationship tracking

@matthewryanscott
Copy link
Contributor

@jhw I will do what I can to take a look at this today.

@matthewryanscott
Copy link
Contributor

@jhw I finally got a chance to take a quick look at this.

One thing that comes to mind superficially is that the master branch is quite outdated and there was a lot of work done on the sunvox-2.0-file-format branch, which along with a TON of other stuff includes some fixes to the original version of your script.

I haven't tested it, but I did prepare a branch, sunvox-2.0-file-format--jhw-01-decompiler-v2 that rolls back the changes made to the script and then applies your branch.

But, bigger-picture, I'd like to have a broader discussion about the future of the project and how you might be able to port your script over to the native SunVox lib. I'll open that up separately and ping you there!

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