Skip to content

Instantly share code, notes, and snippets.

@Xliff
Last active July 31, 2023 07:36
Show Gist options
  • Save Xliff/20ef0dce6be4fa4a6a72854aa6ad99c5 to your computer and use it in GitHub Desktop.
Save Xliff/20ef0dce6be4fa4a6a72854aa6ad99c5 to your computer and use it in GitHub Desktop.
On Parsing ElectricSheep Flame Files....

Over the weekend, I wrote a module to do just that. It's early days still, as I'm sure there are tags that are not covered. I'll need to find the spec and have a nice long sit down before it's complete.

Here's what I have, though.

Have fun!

use XML::Class;
use DateTime::Parse;

class Color does XML::Class[xml-element => 'color'] {
  has Int $.index is xml-attribute is rw;
  has Str $.rgb   is xml-attribute is rw;

  has Num $.r;
  has Num $.g;
  has Num $.b;

  submethod TWEAK {
    ($!r, $!g, $!b) = $!rgb.split(' ').map( *.Num );
  }
}

class XForm does XML::Class[xml-element => 'xform'] {
  has Num $.weight       is xml-attribute                 is rw;
  has Int $.color        is xml-attribute                 is rw;
  has Num $.color-speed  is xml-attribute('color-speed')  is rw;
  has Int $.animate      is xml-attribute                 is rw;
  has Num $.julia        is xml-attribute                 is rw;
  has Num $.julian       is xml-attribute                 is rw;
  has Int $.julian-power is xml-attribute('julian_power') is rw;
  has Int $.julian-dist  is xml-attribute('julian_dist')  is rw;
  has Str $.coefs        is xml-attribute                 is rw;
  has Int $.opacity      is xml-attribute                 is rw;

  has @.coefficients;

  method TWEAK {
    @!coefficients = $!coefs.split(' ').map( *.Num ) if $!coefs;
  }
}

class Edit does XML::Class[xml-element => 'edit' ] { ... }

class Edit {
  has Str $.date     is xml-attribute is rw;
  has Str $.action   is xml-attribute is rw;
  has Int $.id       is xml-attribute is rw;
  has Int $.gen      is xml-attribute is rw;
  has Str $.filename is xml-attribute is rw;
  has Int $.index    is xml-attribute is rw;

  has Edit @.edits;

  has @.actions;
  has $.parsed-date;

  submethod BUILD (
    :$date,
    :$action,
    :$id,
    :$gen,
    :$filename,
    :$index,
    :@edits
  ) {
    $!date     = $date     if $date.defined;
    $!id       = $id       if $id.defined;
    $!gen      = $gen      if $gen.defined;
    $!filename = $filename if $filename.defined;
    $!index    = $index    if $index.defined;
    $!action   = $action   if $action.defined;
    @!edits    = @edits    if +@edits;
  }

  #submethod TWEAK {
  #  $!parsed-date = DateTime::Parse.new($!date) if $!date.defined;
  #}
}

class Flame does XML::Class[xml-element => 'flame'] {
  has Str $.version               is xml-attribute                          is rw;
  has Int $.time                  is xml-attribute                          is rw;
  has Str $.name                  is xml-attribute                          is rw;
  has Str $.size                  is xml-attribute                          is rw;
  has Str $.center                is xml-attribute                          is rw;
  has Num $.scale                 is xml-attribute                          is rw;
  has Num $.rotate                is xml-attribute                          is rw;
  has Int $.supersample           is xml-attribute                          is rw;
  has Int $.filer                 is xml-attribute                          is rw;
  has Str $.filter-shape          is xml-attribute('filter_shape')          is rw;
  has Str $.temporal-filter-type  is xml-attribute('temporal_filter_type')  is rw;
  has Num $.temporal-filter-width is xml-attribute('temporal_filter_width') is rw;
  has Int $.quality               is xml-attribute                          is rw;
  has Int $.passes                is xml-attribute                          is rw;
  has Int $.temporal-samples      is xml-attribute('temporal_samples')      is rw;
  has Str $.background            is xml-attribute                          is rw;
  has Num $.brightness            is xml-attribute                          is rw;
  has Num $.gamma                 is xml-attribute                          is rw;
  has Int $.highlight-power       is xml-attribute('highlight_power')       is rw;
  has Num $.vibrancy              is xml-attribute                          is rw;
  has Int $.estimator-radiance    is xml-attribute('estimator_radiance')    is rw;
  has Int $.estimator-medium      is xml-attribute('estimator_medium')      is rw;
  has Num $.estimator-curve       is xml-attribute('estimator_curve')       is rw;
  has Num $.gamma-threshold       is xml-attribute('gamma_threshold')       is rw;
  has Str $.palette-mode          is xml-attribute('palette_mode')          is rw;
  has Str $.interpolation-type    is xml-attribute('interpolation_type')    is rw;
  has Str $.palette-interpolation is xml-attribute('palette_interpolation') is rw;

  has XForm @.xforms;
  has Color @.colors;
  has Edit  @.edits;
}
@Xliff
Copy link
Author

Xliff commented Jul 31, 2023

To use this, save the above to a module name of your choice and run the following:

raku -e 'use <ModuleName>; my $flame-data = Flame.from-xml(<xml-data-string>); $flame-data.gist.say'

You might need to tweak some things. I have future PRs going in against XML::Class and DateTime::Parse that handle some of the bugs I exposed when writing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment