Skip to content

Commit

Permalink
Merge pull request #49 from YarnSpinnerTool/sqlite_example
Browse files Browse the repository at this point in the history
Add Sqlite example
  • Loading branch information
dogboydog authored Apr 27, 2024
2 parents e2e654e + 195ad26 commit 2851ca3
Show file tree
Hide file tree
Showing 14 changed files with 415 additions and 9 deletions.
2 changes: 1 addition & 1 deletion Samples/PausingTypewriter/PauseSample.tscn
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[gd_scene load_steps=7 format=3 uid="uid://ckp616grs7xrs"]

[ext_resource type="PackedScene" uid="uid://bv42g323prh5f" path="res://addons/YarnSpinner-Godot/Scenes/DefaultDialogueSystem.tscn" id="1_m0dlq"]
[ext_resource type="Resource" uid="uid://btil08na83k0p" path="res://Samples/PausingTypewriter/PauseProj.yarnproject" id="2_j3415"]
[ext_resource type="Resource" uid="uid://21gon4fidoq8" path="res://Samples/PausingTypewriter/PauseProj.yarnproject" id="2_j3415"]
[ext_resource type="Texture2D" uid="uid://crtrls05kcbu5" path="res://Samples/PausingTypewriter/sprites/talking.png" id="2_njmvd"]
[ext_resource type="Script" path="res://Samples/PausingTypewriter/PauseResponder.cs" id="3_uqanb"]
[ext_resource type="Texture2D" uid="uid://dk84dy4vqquds" path="res://Samples/PausingTypewriter/sprites/thinking.png" id="4_1i87u"]
Expand Down
36 changes: 36 additions & 0 deletions Samples/SQLiteVariableStorage/SQLSample.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[gd_scene load_steps=5 format=3 uid="uid://dt33g06nhtxn2"]

[ext_resource type="PackedScene" uid="uid://dqe5yshlcmnpg" path="res://addons/YarnSpinner-Godot/Scenes/RoundedDialogueSystem.tscn" id="1_8wwci"]
[ext_resource type="Resource" uid="uid://tsj53mnkwps3" path="res://Samples/SQLiteVariableStorage/SQLSample.yarnproject" id="2_73843"]
[ext_resource type="Script" path="res://Samples/SQLiteVariableStorage/SQLVariableStorage.cs" id="3_71oeg"]
[ext_resource type="Script" path="res://Samples/ReturnOnComplete.cs" id="4_lgfx4"]

[node name="SqlSample" type="Node2D"]

[node name="RoundedYarnSpinnerCanvasLayer" parent="." instance=ExtResource("1_8wwci")]

[node name="DialogueRunner" parent="RoundedYarnSpinnerCanvasLayer" index="0" node_paths=PackedStringArray("variableStorage")]
yarnProject = ExtResource("2_73843")
variableStorage = NodePath("../SQLVariableStorage")
startNode = "SqlSample"
startAutomatically = true

[node name="ColorRect" type="ColorRect" parent="RoundedYarnSpinnerCanvasLayer"]
z_index = -6
z_as_relative = false
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2
color = Color(0.187867, 0.096, 0.2, 1)

[node name="SQLVariableStorage" type="Node2D" parent="RoundedYarnSpinnerCanvasLayer"]
script = ExtResource("3_71oeg")

[node name="ReturnOnComplete" type="Node2D" parent="." node_paths=PackedStringArray("dialogueRunner")]
script = ExtResource("4_lgfx4")
dialogueRunner = NodePath("../RoundedYarnSpinnerCanvasLayer/DialogueRunner")

[editable path="RoundedYarnSpinnerCanvasLayer"]
10 changes: 10 additions & 0 deletions Samples/SQLiteVariableStorage/SQLSample.yarnproject
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"projectFileVersion": 2,
"sourceFiles": [
"**/*.yarn"
],
"excludeFiles": [],
"localisation": {},
"baseLanguage": "en",
"compilerOptions": {}
}
14 changes: 14 additions & 0 deletions Samples/SQLiteVariableStorage/SQLSample.yarnproject.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[remap]

importer="yarnproject"
type="Resource"
uid="uid://tsj53mnkwps3"
path="res://.godot/imported/SQLSample.yarnproject-492bf8c35d4a0f0a8978692c27ea366f.tres"

[deps]

source_file="res://Samples/SQLiteVariableStorage/SQLSample.yarnproject"
dest_files=["res://.godot/imported/SQLSample.yarnproject-492bf8c35d4a0f0a8978692c27ea366f.tres"]

[params]

256 changes: 256 additions & 0 deletions Samples/SQLiteVariableStorage/SQLVariableStorage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
#nullable disable

using System;
using System.Collections.Generic;
using System.Linq;
using Godot;
using SQLite;
using YarnSpinnerGodot;

/// <summary>
/// SQLite based custom variable storage example.
/// </summary>
public partial class SQLVariableStorage : VariableStorageBehaviour
{
private SQLiteConnection db; // the database connector

public override void _EnterTree()
{
// pick a place on disk for the database to save to
string path = ProjectSettings.GlobalizePath("user://db.sqlite");
// create a new database connection to speak to it
db = new SQLiteConnection(path);
// create the tables we need
db.CreateTable<YarnString>();
db.CreateTable<YarnFloat>();
db.CreateTable<YarnBool>();
GD.Print($"Initialized database at {path}");
}

public override bool TryGetValue<T>(string variableName, out T result)
{
string query = "";
List<object> results = new();
if (typeof(T) == typeof(IConvertible))
{
// we don't know the expected type
if (TryGetValue<string>(variableName, out string stringResult))
{
result = (T) (object) stringResult;
return true;
}

if (TryGetValue<float>(variableName, out float floatResult))
{
result = (T) (object) floatResult;
return true;
}

if (TryGetValue<bool>(variableName, out bool boolResult))
{
result = (T) (object) boolResult;
return true;
}

result = default(T);
return false;
}

if (typeof(T) == typeof(string))
{
query = "SELECT * FROM YarnString WHERE key = ?";
results.AddRange(db.Query<YarnString>(query, variableName));
}
else if (typeof(T) == typeof(bool))
{
query = "SELECT * FROM YarnBool WHERE key = ?";
results.AddRange(db.Query<YarnBool>(query, variableName));
}
else if (typeof(T) == typeof(float))
{
query = "SELECT * FROM YarnFloat WHERE key = ?";
results.AddRange(db.Query<YarnFloat>(query, variableName));
}

// if a result was found, convert it to type T and assign it
if (results?.Count > 0)
{
if (results[0] is YarnFloat f)
{
result = (T) (object) f.value;
}
else if (results[0] is YarnBool b)
{
result = (T) (object) b.value;
}
else if (results[0] is YarnString s)
{
result = (T) (object) s.value;
}
else
{
throw new ArgumentException($"Unknown variable type {typeof(T)}");
}

return true;
}

// otherwise TryGetValue has failed
result = default(T);
return false;
}

public override void SetValue(string variableName, string stringValue)
{
// check it doesn't exist already in other table
if (Exists(variableName, typeof(bool)))
{
throw new ArgumentException($"{variableName} is a bool.");
}

if (Exists(variableName, typeof(float)))
{
throw new ArgumentException($"{variableName} is a float.");
}

// if not, insert or update row in this table to the given value
string query = "INSERT OR REPLACE INTO YarnString (key, value)";
query += "VALUES (?, ?)";
db.Execute(query, variableName, stringValue);
}

public override void SetValue(string variableName, float floatValue)
{
// check it doesn't exist already in other table
if (Exists(variableName, typeof(string)))
{
throw new ArgumentException($"{variableName} is a string.");
}

if (Exists(variableName, typeof(bool)))
{
throw new ArgumentException($"{variableName} is a bool.");
}

// if not, insert or update row in this table to the given value
string query = "INSERT OR REPLACE INTO YarnFloat (key, value)";
query += "VALUES (?, ?)";
db.Execute(query, variableName, floatValue);
}

public override void SetValue(string variableName, bool boolValue)
{
// check it doesn't exist already in other table
if (Exists(variableName, typeof(string)))
{
throw new ArgumentException($"{variableName} is a string.");
}

if (Exists(variableName, typeof(float)))
{
throw new ArgumentException($"{variableName} is a float.");
}

// if not, insert or update row in this table to the given value
string query = "INSERT OR REPLACE INTO YarnBool (key, value)";
query += "VALUES (?, ?)";
db.Execute(query, variableName, boolValue);
}

public override void Clear()
{
db.Execute("DELETE * FROM YarnString;");
db.Execute("DELETE * FROM YarnBool;");
db.Execute("DELETE * FROM YarnFloat;");
}

public override bool Contains(string variableName)
{
return Exists(variableName, typeof(string)) ||
Exists(variableName, typeof(bool)) ||
Exists(variableName, typeof(float));
}

public override void SetAllVariables(Dictionary<string, float> floats, Dictionary<string, string> strings,
Dictionary<string, bool> bools, bool clear = true)
{
foreach (var entry in floats)
{
SetValue(entry.Key, entry.Value);
}

foreach (var entry in bools)
{
SetValue(entry.Key, entry.Value);
}

foreach (var entry in strings)
{
SetValue(entry.Key, entry.Value);
}
}

public override (Dictionary<string, float>, Dictionary<string, string>, Dictionary<string, bool>) GetAllVariables()
{
var floatQuery = "SELECT value FROM YarnFloat";
var floats = db.Query<YarnFloat>(floatQuery)
.AsEnumerable()
.ToDictionary(f => f.key, f => f.value);
var stringQuery = "SELECT value FROM YarnString";
var strings = db.Query<YarnString>(stringQuery)
.AsEnumerable()
.ToDictionary(f => f.key, f => f.value);
var boolQuery = "SELECT value FROM YarnBool";
var booleans = db.Query<YarnBool>(boolQuery)
.AsEnumerable()
.ToDictionary(f => f.key, f => f.value);

return (floats, strings, booleans);
}

private bool Exists(string variableName, Type type)
{
if (type == typeof(string))
{
string stringResult;
if (TryGetValue(variableName, out stringResult))
{
return (stringResult != null);
}
}
else if (type == typeof(bool))
{
if (TryGetValue(variableName, out bool _))
{
return true;
}
}
else if (type == typeof(float))
{
if (TryGetValue(variableName, out float _))
{
return true;
}
}

return false;
}
}

public class YarnString
{
[PrimaryKey] public string key { get; set; }
public string value { get; set; }
}

public class YarnFloat
{
[PrimaryKey] public string key { get; set; }
public float value { get; set; }
}

public class YarnBool
{
[PrimaryKey] public string key { get; set; }
public bool value { get; set; }
}
41 changes: 41 additions & 0 deletions Samples/SQLiteVariableStorage/SqlSample.yarn
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
title: SqlSample
tags:
---
<<declare $characterName = "" as string>>
<<declare $numVariables = 0>>
<<declare $impressed = false as bool>>
Guide: Alright, I've been waiting for my last applicant of the day.
Guide: Hmm, how do you say your name!? It says "S-Q-L".
-> Eskew-well
<<set $characterName to "Eskew-well">>
-> Seekwill
<<set $characterName to "Seekwill">>
{$characterName}: My name is {$characterName}.
{$characterName}: I have trained for one thousand years to store the most variables of all time.
Guide: Wow. Impressive! Just how many variables do you think you could store??
-> There's no limit.
<<set $numVariables to -1>>
Guide: Wh- what? Unlimited??
Guide: Gahhh!!!
The guide ran away.
<<stop>>
-> Sixty two thousand.
<<set $numVariables to 62000>>
Guide: Formidable... imagine the heights you could reach under our guidance.
<<set $impressed to true>>
-> One thousand.
<<set $numVariables to 1000>>
Guide: Hmm. That's not bad.
<<set $impressed to true>>
-> Three.
<<set $numVariables to 3>>
Guide: I ...see.
<<set $impressed to false>>

Guide: Alright then, {$characterName}. You can store {$numVariables} variables...
<<if $impressed>>
Guide: Welcome to Variable Academy.
<<else>>
Guide: I'm afraid you're not cut out for Variable Academy.
<<endif>>
===
14 changes: 14 additions & 0 deletions Samples/SQLiteVariableStorage/SqlSample.yarn.import
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[remap]

importer="yarnscript"
type="Resource"
uid="uid://mno2y7y3atrn"
path="res://.godot/imported/SqlSample.yarn-1a034971b5ef626e0730aa486cf1cdf1.tres"

[deps]

source_file="res://Samples/SQLiteVariableStorage/SqlSample.yarn"
dest_files=["res://.godot/imported/SqlSample.yarn-1a034971b5ef626e0730aa486cf1cdf1.tres"]

[params]

Loading

0 comments on commit 2851ca3

Please sign in to comment.