diff --git a/mobile-app/lib/Warband.dart b/mobile-app/lib/Warband.dart deleted file mode 100644 index 616835d..0000000 --- a/mobile-app/lib/Warband.dart +++ /dev/null @@ -1,101 +0,0 @@ -import 'dart:collection'; - -import 'package:json_annotation/json_annotation.dart'; -import 'package:yaml/yaml.dart'; - -part 'Warband.g.dart'; - -// flutter packages pub run build_runner build --delete-conflicting-outputs - -@JsonSerializable(nullable: true, anyMap: true, createToJson: false) -class Hero { - @JsonKey(name: 'hero') - final String name; - - @JsonKey(fromJson: _statsFromJson) - final HeroStats stats; - - final String skilllists; - final String weapons; - final String amour; - final String rules; - final int warbandaddition; - - Hero(this.stats, this.skilllists, this.weapons, this.amour, this.rules, this.warbandaddition, this.name); - - factory Hero.fromJson(yaml) => - _$HeroFromJson(yaml); - - static HeroStats _statsFromJson(String stats) { - RegExp re = new RegExp(r"\s*M([0-9]+[dD]*[6]*)\s*,\s*WS([0-9]+)\s*,\s*BS([0-9]+)\s*,\s*S([0-9]+)\s*,\s*T([0-9]+)\s*,\s*W([0-9]+)\s*,\s*I([0-9]+)\s*,\s*A([0-9]+)\s*,\s*Ld([0-9]+)\s*,\s*Sv([0-9\-]+)\s*"); - var matches = re.allMatches(stats).toList().first; - return HeroStats( - int.tryParse(matches.group(1)) ?? 0, - int.tryParse(matches.group(2)) ?? 0, - int.tryParse(matches.group(3)) ?? 0, - int.tryParse(matches.group(4)) ?? 0, - int.tryParse(matches.group(5)) ?? 0, - int.tryParse(matches.group(6)) ?? 0, - int.tryParse(matches.group(7)) ?? 0, - int.tryParse(matches.group(8)) ?? 0, - int.tryParse(matches.group(9)) ?? 0, - int.tryParse(matches.group(10)) ?? 0 - ); - } -} - -class HeroStats { - final int movement; - final int weaponSkill; - final int ballisticSkill; - final int strength; - final int toughtness; - final int wounds; - final int initiative; - final int attacks; - final int leadership; - final int save; - - HeroStats(this.movement, this.weaponSkill, this.ballisticSkill, this.strength, this.toughtness, this.wounds, this.initiative, this.attacks, this.leadership, this.save); -} - -@JsonSerializable(nullable: true, anyMap: true, createToJson: false) -class Warband { - @JsonKey(name: 'warband', fromJson: _warbandNameAndRace) - final HashMap nameAndRace; - @JsonKey(ignore: true) - String name; - @JsonKey(ignore: true) - String race; - - @JsonKey(name: 'campaign') - final int campaignPoints; - - final String objective; - final String alignment; - final String achievments; - final int gc; - final int shards; - final String equipment; - - final List heros; - - Warband(this.nameAndRace, this.campaignPoints, this.objective, this.alignment, this.gc, this.shards, this.equipment, this.achievments, this.heros) { - this.race = this.nameAndRace['name']; - this.name = this.nameAndRace['race']; - } - - static HashMap _warbandNameAndRace(String nameAndRace) { - HashMap nr = new HashMap(); - RegExp re = new RegExp(r"(.*) \((.*)\)"); - - var matches = re.allMatches(nameAndRace); - nr['name'] = matches.toList().first.group(1).toString(); - nr['race'] = matches.toList().first.group(2).toString(); - - return nr; - } - - factory Warband.fromJson(yaml) => - _$WarbandFromJson(yaml); -} \ No newline at end of file diff --git a/mobile-app/lib/Warband.g.dart b/mobile-app/lib/Warband.g.dart deleted file mode 100644 index dce69b7..0000000 --- a/mobile-app/lib/Warband.g.dart +++ /dev/null @@ -1,33 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'Warband.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Hero _$HeroFromJson(Map json) { - return Hero( - Hero._statsFromJson(json['stats'] as String), - json['skilllists'] as String, - json['weapons'] as String, - json['amour'] as String, - json['rules'] as String, - json['warbandaddition'] as int, - json['hero'] as String); -} - -Warband _$WarbandFromJson(Map json) { - return Warband( - Warband._warbandNameAndRace(json['warband'] as String), - json['campaign'] as int, - json['objective'] as String, - json['alignment'] as String, - json['gc'] as int, - json['shards'] as int, - json['equipment'] as String, - json['achievments'] as String, - (json['heros'] as List) - ?.map((e) => e == null ? null : Hero.fromJson(e)) - ?.toList()); -} diff --git a/mobile-app/lib/WarbandRoaster.dart b/mobile-app/lib/WarbandRoaster.dart new file mode 100644 index 0000000..6f4abc2 --- /dev/null +++ b/mobile-app/lib/WarbandRoaster.dart @@ -0,0 +1,188 @@ +import 'dart:collection'; + +import 'package:json_annotation/json_annotation.dart'; + +part 'WarbandRoaster.g.dart'; + +// flutter packages pub run build_runner build --delete-conflicting-outputs + +abstract class Unit { + static List _splitListFromJson(String list) { + if (list == null) { + return new List(); + } + return list.split(new RegExp(r" *, *")); + } + + static Stats _statsFromJson(String stats) { + RegExp re = new RegExp(r"\s*M([0-9]+[dD]*[6]*)\s*,\s*WS([0-9]+)\s*,\s*BS([0-9]+)\s*,\s*S([0-9]+)\s*,\s*T([0-9]+)\s*,\s*W([0-9]+)\s*,\s*I([0-9]+)\s*,\s*A([0-9]+)\s*,\s*Ld([0-9]+)\s*,\s*Sv([0-9\-]+)\s*"); + var matches = re.allMatches(stats).toList().first; + return Stats( + int.tryParse(matches.group(1)) ?? 0, + int.tryParse(matches.group(2)) ?? 0, + int.tryParse(matches.group(3)) ?? 0, + int.tryParse(matches.group(4)) ?? 0, + int.tryParse(matches.group(5)) ?? 0, + int.tryParse(matches.group(6)) ?? 0, + int.tryParse(matches.group(7)) ?? 0, + int.tryParse(matches.group(8)) ?? 0, + int.tryParse(matches.group(9)) ?? 0, + int.tryParse(matches.group(10)) ?? 0 + ); + } +} + +@JsonSerializable(nullable: true, anyMap: true, createToJson: false) +class HenchmenGroup extends Unit { + @JsonKey(name: 'group', fromJson: _henchmenHeaderFromJson) + final HashMap header; + @JsonKey(ignore: true) + String name; + @JsonKey(ignore: true) + String type; + @JsonKey(ignore: true) + int number; + @JsonKey(ignore: true) + int experience; + + @JsonKey(fromJson: Unit._statsFromJson) + final Stats stats; + + @JsonKey(fromJson: Unit._splitListFromJson) + final List weapons; + + @JsonKey(fromJson: Unit._splitListFromJson) + final List amour; + + HenchmenGroup(this.header, this.stats, this.weapons, this.amour) { + this.name = this.header['name']; + this.type = this.header['type']; + this.number = int.tryParse(this.header['number']) ?? 1; + this.experience = int.tryParse(this.header['experience']) ?? 0; + } + + static HashMap _henchmenHeaderFromJson(String header) { + HashMap h = new HashMap(); + RegExp re = new RegExp(r"([^\(]+)\(([0-9]+)x?\s+([^\)]+)\)\s*\[([0-9]+)XP\]\s*"); + var matches = re.allMatches(header).toList().first; + + h['name'] = matches.group(1); + h['type'] = matches.group(2); + h['number'] = matches.group(3); + h['experience'] = matches.group(4); + + return h; + } + + factory HenchmenGroup.fromJson(yaml) => + _$HenchmenGroupFromJson(yaml); + +} + +@JsonSerializable(nullable: true, anyMap: true, createToJson: false) +class Hero extends Unit { + @JsonKey(name: 'hero', fromJson: _heroHeaderFromJson) + final HashMap header; + @JsonKey(ignore: true) + String name; + @JsonKey(ignore: true) + String type; + @JsonKey(ignore: true) + int experience; + + @JsonKey(fromJson: Unit._statsFromJson) + final Stats stats; + + @JsonKey(fromJson: Unit._splitListFromJson) + final List skilllists; + + @JsonKey(fromJson: Unit._splitListFromJson) + final List weapons; + + @JsonKey(fromJson: Unit._splitListFromJson) + final List amour; + + @JsonKey(fromJson: Unit._splitListFromJson) + final List rules; + + final int warbandaddition; + + Hero(this.stats, this.skilllists, this.weapons, this.amour, this.rules, this.warbandaddition, this.header) { + this.name = this.header['name']; + this.type = this.header['type']; + this.experience = int.tryParse(this.header['experience']) ?? 0; + } + + factory Hero.fromJson(yaml) => + _$HeroFromJson(yaml); + + static HashMap _heroHeaderFromJson(String header) { + HashMap h = new HashMap(); + RegExp re = new RegExp(r"([^\(]+)\(([^\)]+)\)\s*\[([0-9]+)XP\]\s*"); + var matches = re.allMatches(header).toList().first; + + h['name'] = matches.group(1); + h['type'] = matches.group(2); + h['experience'] = matches.group(3); + + return h; + } +} + +class Stats { + final int movement; + final int weaponSkill; + final int ballisticSkill; + final int strength; + final int toughtness; + final int wounds; + final int initiative; + final int attacks; + final int leadership; + final int save; + + Stats(this.movement, this.weaponSkill, this.ballisticSkill, this.strength, this.toughtness, this.wounds, this.initiative, this.attacks, this.leadership, this.save); +} + +@JsonSerializable(nullable: true, anyMap: true, createToJson: false) +class WarbandRoaster { + @JsonKey(name: 'warband', fromJson: _warbandNameAndRace) + final HashMap nameAndRace; + @JsonKey(ignore: true) + String name; + @JsonKey(ignore: true) + String race; + + @JsonKey(name: 'campaign') + final int campaignPoints; + + final String objective; + final String alignment; + final String achievments; + final int gc; + final int shards; + final String equipment; + final List heros; + + @JsonKey(name: 'henchmen') + final List henchmenGroups; + + WarbandRoaster(this.nameAndRace, this.campaignPoints, this.objective, this.alignment, this.gc, this.shards, this.equipment, this.achievments, this.heros, this.henchmenGroups) { + this.name = this.nameAndRace['name']; + this.race = this.nameAndRace['race']; + } + + static HashMap _warbandNameAndRace(String nameAndRace) { + HashMap nr = new HashMap(); + RegExp re = new RegExp(r"(.*) \((.*)\)"); + + var matches = re.allMatches(nameAndRace); + nr['name'] = matches.toList().first.group(1).toString(); + nr['race'] = matches.toList().first.group(2).toString(); + + return nr; + } + + factory WarbandRoaster.fromJson(yaml) => + _$WarbandRoasterFromJson(yaml); +} \ No newline at end of file diff --git a/mobile-app/lib/WarbandRoaster.g.dart b/mobile-app/lib/WarbandRoaster.g.dart new file mode 100644 index 0000000..69d262d --- /dev/null +++ b/mobile-app/lib/WarbandRoaster.g.dart @@ -0,0 +1,44 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'WarbandRoaster.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +HenchmenGroup _$HenchmenGroupFromJson(Map json) { + return HenchmenGroup( + HenchmenGroup._henchmenHeaderFromJson(json['group'] as String), + Unit._statsFromJson(json['stats'] as String), + Unit._splitListFromJson(json['weapons'] as String), + Unit._splitListFromJson(json['amour'] as String)); +} + +Hero _$HeroFromJson(Map json) { + return Hero( + Unit._statsFromJson(json['stats'] as String), + Unit._splitListFromJson(json['skilllists'] as String), + Unit._splitListFromJson(json['weapons'] as String), + Unit._splitListFromJson(json['amour'] as String), + Unit._splitListFromJson(json['rules'] as String), + json['warbandaddition'] as int, + Hero._heroHeaderFromJson(json['hero'] as String)); +} + +WarbandRoaster _$WarbandRoasterFromJson(Map json) { + return WarbandRoaster( + WarbandRoaster._warbandNameAndRace(json['warband'] as String), + json['campaign'] as int, + json['objective'] as String, + json['alignment'] as String, + json['gc'] as int, + json['shards'] as int, + json['equipment'] as String, + json['achievments'] as String, + (json['heros'] as List) + ?.map((e) => e == null ? null : Hero.fromJson(e)) + ?.toList(), + (json['henchmen'] as List) + ?.map((e) => e == null ? null : HenchmenGroup.fromJson(e)) + ?.toList()); +} diff --git a/mobile-app/lib/main.dart b/mobile-app/lib/main.dart index d59040d..a86fc16 100644 --- a/mobile-app/lib/main.dart +++ b/mobile-app/lib/main.dart @@ -1,8 +1,7 @@ -import 'dart:convert'; - import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' as prefix0; import 'package:http/http.dart' as http; -import 'package:toolheim/Warband.dart'; +import 'package:toolheim/WarbandRoaster.dart'; import 'package:yaml/yaml.dart'; void main() => runApp(Toolheim()); @@ -27,31 +26,55 @@ class RoasterWidget extends StatefulWidget { } class _RoasterWidgetState extends State { - final String urlPath = 'https://raw.githubusercontent.com/Labernator/Mordheim/master/Mordheim-BorderTownBurning/Warband%20Rosters/Aaron/aaron.mordheim.yml'; - Warband warband; + Future roaster; - Future fetchWarband() async { + static Future fetchWarband() async { + final String urlPath = 'https://raw.githubusercontent.com/Labernator/Mordheim/master/Mordheim-BorderTownBurning/Warband%20Rosters/Aaron/aaron.mordheim.yml'; http.Response response = await http.get(urlPath); YamlMap yamlObject = loadYaml(response.body); - Warband _warband = Warband.fromJson(yamlObject); - - setState(() { - warband = _warband; - }); + return WarbandRoaster.fromJson(yamlObject); } void initState() { - fetchWarband(); super.initState(); + roaster = fetchWarband(); } @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(warband.name) - ), - body: Text(warband.heros.first.stats.weaponSkill.toString(), textScaleFactor: 1.3) + return FutureBuilder( + future: roaster, + builder: (BuildContext context, AsyncSnapshot snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return Center(child: CircularProgressIndicator()); + case ConnectionState.done: + WarbandRoaster roaster = snapshot.data; + return Scaffold( + appBar: AppBar( + title: Text(roaster.name), + ), + body: ListView.builder( + itemCount: roaster.heros.length, + itemBuilder: (BuildContext context, int index) { + var hero = roaster.heros[index]; + + return ListTile( + title: Text(hero.name), + leading: CircleAvatar( + child: Text(hero.experience.toString()), + backgroundColor: Colors.green, + foregroundColor: Colors.greenAccent, + ), + subtitle: Text(hero.type), + ); + } + ) + ); + } + } ); } }