Skip to content

Commit

Permalink
Improve Isolates
Browse files Browse the repository at this point in the history
  • Loading branch information
PeculiarProgrammer committed Dec 18, 2024
1 parent e1bdb27 commit 4e68c0f
Showing 1 changed file with 77 additions and 19 deletions.
96 changes: 77 additions & 19 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:isolate';
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import "./algorithm.dart";
Expand Down Expand Up @@ -48,11 +49,16 @@ class _MyHomePageState extends State<MyHomePage> {
String path = "";
DictionaryType dictionaryType = DictionaryType.semiReasonableScrabble;
bool isGenerating = false;
Trie fullScrabbleTrie = Trie();

@override
void initState() {
super.initState();
generateGameFile();

for (var word in scrabbleComplete) {
fullScrabbleTrie.insert(word);
}
}

@override
Expand Down Expand Up @@ -182,6 +188,7 @@ class _MyHomePageState extends State<MyHomePage> {
playerCount: playerCount,
path: path,
dictionaryType: dictionaryType,
fullScrabbleTrie: fullScrabbleTrie,
),
],
),
Expand Down Expand Up @@ -257,6 +264,7 @@ class AlgorithmShower extends StatefulWidget {
final int playerCount;
final String path;
final DictionaryType dictionaryType;
final Trie fullScrabbleTrie;

const AlgorithmShower({
Key? key,
Expand All @@ -266,27 +274,25 @@ class AlgorithmShower extends StatefulWidget {
required this.playerCount,
required this.path,
required this.dictionaryType,
required this.fullScrabbleTrie,
}) : super(key: key);

@override
State<AlgorithmShower> createState() => _AlgorithmShowerState();
}

class _AlgorithmShowerState extends State<AlgorithmShower> {
Future<List<dynamic>>? future;

bool isTurn = false;
Map<String, double> optimalGame = {};
List<MapEntry<String, double>> sortedLetters = [];
String? showWords;
Trie fullScrabbleTrie = Trie();

@override
void initState() {
super.initState();
_initializeAlgorithm();

for (var word in scrabbleComplete) {
fullScrabbleTrie.insert(word);
}
}

@override
Expand All @@ -300,8 +306,6 @@ class _AlgorithmShowerState extends State<AlgorithmShower> {
}

void _initializeAlgorithm() {
// I extrapolated this out of build just to be unnecessarily safe (turns out it was a good idea)

if (!widget.dictionaryTrie.hasChildren(widget.path) ||
widget.dictionaryTrie.has(widget.path)) {
return;
Expand All @@ -314,24 +318,78 @@ class _AlgorithmShowerState extends State<AlgorithmShower> {
optimalGame.clear();
sortedLetters.clear();

if (isTurn) {
var temporaryDictionary = widget.dictionaryTrie.root.walk(widget.path)!;
future = compute(determinePercentageIsolate, [
widget.dictionaryTrie,
widget.gameData,
widget.playerCount,
widget.path,
isTurn,
]);
}

for (var letter in letters) {
if (!temporaryDictionary.hasChild(letter)) {
continue;
}
optimalGame[letter] = determinePercentage(
widget.path + letter, widget.gameData, widget.playerCount);
}
static List<dynamic> determinePercentageIsolate(List<dynamic> arguments) {
var isTurn = arguments[4] as bool;

if (!isTurn) {
return [null, null];
}

var dictionaryTrie = arguments[0] as Trie;
var gameData = arguments[1] as Map<String, int>;
var playerCount = arguments[2] as int;
var path = arguments[3] as String;

var temporaryDictionary = dictionaryTrie.root.walk(path)!;

sortedLetters.addAll(optimalGame.entries.toList()
..sort((a, b) => b.value.compareTo(a.value)));
var optimalGame = <String, double>{};
var sortedLetters = <MapEntry<String, double>>[];

for (var letter in letters) {
if (!temporaryDictionary.hasChild(letter)) {
continue;
}
optimalGame[letter] =
determinePercentage(path + letter, gameData, playerCount);
}

sortedLetters.addAll(optimalGame.entries.toList()
..sort((a, b) => b.value.compareTo(a.value)));

return [optimalGame, sortedLetters];
}

@override
Widget build(BuildContext context) {
return FutureBuilder<List<dynamic>>(
future: future,
builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return const SizedBox();
case ConnectionState.waiting:
return const Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: CircularProgressIndicator(),
);
case ConnectionState.active:
return const SizedBox();
case ConnectionState.done:
if (snapshot.hasError) {
return Text("Error: ${snapshot.error}");
}

if (snapshot.data![0] != null) {
optimalGame = snapshot.data![0] as Map<String, double>;
sortedLetters =
snapshot.data![1] as List<MapEntry<String, double>>;
}

return loadedInterface(context);
}
});
}

RenderObjectWidget loadedInterface(BuildContext context) {
if (widget.dictionaryTrie.has(widget.path)) {
return const Padding(
padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
Expand All @@ -354,7 +412,7 @@ class _AlgorithmShowerState extends State<AlgorithmShower> {
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
if (fullScrabbleTrie.hasChildren(widget.path))
if (widget.fullScrabbleTrie.hasChildren(widget.path))
const Text(
"Note: Words exist in the full Scrabble dictionary. Change the dictionary type to view them.",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w300),
Expand Down

0 comments on commit 4e68c0f

Please sign in to comment.