using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UIElements;
using Debug = UnityEngine.Debug;
namespace RMC.Backend.Baas.Aws.Samples
{
// Classes ------------------------------------
// Demo-specific table
public class InventoryTable : Table
{
public InventoryTable()
{
TableName = "InventoryTable";
}
}
// Demo-specific item
public class GoldInventoryItem : InventoryItem
{
public GoldInventoryItem()
{
Name = "Gold";
Quantity = 0;
}
}
// Demo-specific item
public class DemoModel
{
public bool DatabaseHasTable = false;
public int DatabaseItemQuantityPrevious = 1;
}
///
/// Main entry point for the Scene.
///
public class DemoJaws01 : MonoBehaviour
{
// Properties ------------------------------------
private Button AccountsSignInButton { get { return _hudUI.Button01; }}
private Button AccountsSignOutButton { get { return _hudUI.Button02; }}
private Button DatabaseCreateTableButton { get { return _hudUI.Button03; }}
private Button DatabaseUpdateTableButton { get { return _hudUI.Button04; }}
private Button CloudCodeMethodCallButton { get { return _hudUI.Button05; }}
private Button AIInvokeButton { get { return _hudUI.Button06; }}
// Fields ----------------------------------------
[Header("UI")]
[SerializeField]
private HudUI _hudUI;
// AWS
//TODO: Optional, Add Unity UI to allow user to type in this info.
private const string _descriptionPrefix = "Jaws For Unity - ";
private const string _userEmail = "test.email@test.email.com";
private const string _userPassword = "test.password!AND@#%123";
private const string _userNickname = "test.nickname";
// State
private DemoModel _demoModel = new DemoModel();
private const int _flickerDurationMS = 100; //Make reload obvious with a UI flicker
// Unity Methods ---------------------------------
protected async void Start()
{
Debug.Log($"{GetType().Name}.Start()");
// Observe Jaws
Jaws.Instance.OnInitialized.AddListener((jaws) => { Debug.LogWarning("@@ Jaws.OnInitialized()"); });
// Observe Accounts
Jaws.Instance.Accounts.OnUserCreated.AddListener((accounts) => { Debug.LogWarning("@@ Jaws.OnUserCreated()"); });
Jaws.Instance.Accounts.OnUserDeleted.AddListener((accounts) => { Debug.LogWarning("@@ Jaws.OnUserDeleted()"); });
Jaws.Instance.Accounts.OnUserSignedIn.AddListener(async (accounts) => { Debug.LogWarning("@@ Jaws.OnUserSignedIn()"); await RefreshUI();});
Jaws.Instance.Accounts.OnUserSignedOut.AddListener(async (accounts) => { Debug.LogWarning("@@ Jaws.OnUserSignedOut()"); await RefreshUI();});
// Observe CloudCode
Jaws.Instance.CloudCode.OnMethodCalled.AddListener((cloudCode) => { Debug.LogWarning("@@ Jaws.OnMethodCalled()"); });
// Observe Database
Jaws.Instance.Database.OnTableRead.AddListener((database) => { Debug.LogWarning("@@ Jaws.OnTableRead()"); });
Jaws.Instance.Database.OnItemCreated.AddListener((database) => { Debug.LogWarning("@@ Jaws.OnItemCreated()"); });
Jaws.Instance.Database.OnItemRead.AddListener((database) => { Debug.LogWarning("@@ Jaws.OnItemRead()"); });
Jaws.Instance.Database.OnItemUpdated.AddListener((database) => { Debug.LogWarning("@@ Jaws.OnItemUpdated()"); });
// Set Interactivity
_hudUI.IsEnabledUI = true;
// UI
_hudUI.ClearTextField(_hudUI.InputTextField01);
_hudUI.ClearTextField(_hudUI.InputTextField02);
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
AccountsSignInButton.text = "1. Create & Sign In\n(Accounts)";
AccountsSignInButton.clicked += async () =>
{
await DoAccountsSignIn();
};
AccountsSignOutButton.text = "2. Sign Out\n(Accounts)";
AccountsSignOutButton.clicked += async () =>
{
await DoAccountsSignOut();
};
DatabaseCreateTableButton.text = "3. Create Table\n(Database)";
DatabaseCreateTableButton.clicked += async () =>
{
// Create Table
await DoDatabaseCreateTable();
// Update Table (Resetting the Item Quantity)
GoldInventoryItem item = new GoldInventoryItem();
item.Quantity = 1;
await DoDatabaseUpdateTable(item);
};
DatabaseUpdateTableButton.text = "4. Update Table\n(Database)";
DatabaseUpdateTableButton.clicked += async () =>
{
// Update Table (Incrementing Item Quantity)
GoldInventoryItem item = new GoldInventoryItem();
item.Quantity = _demoModel.DatabaseItemQuantityPrevious + 1;
await DoDatabaseUpdateTable(item);
};
CloudCodeMethodCallButton.text = "5. Method Call\n(CloudCode)";
CloudCodeMethodCallButton.clicked += async () =>
{
await DoCloudCodeMethodCall();
};
AIInvokeButton.text = "6. Invoke\n(AI)";
AIInvokeButton.clicked += async () =>
{
await DoAIInvoke();
};
// Init
await Jaws.Instance.InitializeAsync();
// UI
await RefreshUI();
// Load first demo
await DoAccountsSignIn();
}
private async Task RefreshUI()
{
// Set Interactivity
_hudUI.IsEnabledUI = false;
// Don't use ****** during demos.
_hudUI.InputTextField01.isPasswordField = false;
_hudUI.InputTextField02.isPasswordField = false;
_hudUI.OutputTextField01.isPasswordField = false;
_hudUI.OutputTextField02.isPasswordField = false;
//Cosmetic delay
await Task.Delay(_flickerDurationMS/2);
_hudUI.TitleLabel.text = $"{SceneManager.GetActiveScene().name}";
//
bool hasUser = Jaws.Instance.Accounts.HasUser();
AccountsSignInButton.SetEnabled(!hasUser);
AccountsSignOutButton.SetEnabled(hasUser);
DatabaseCreateTableButton.SetEnabled(hasUser); //Allow calling this regardless of hasTable
DatabaseUpdateTableButton.SetEnabled(hasUser && _demoModel.DatabaseHasTable);
CloudCodeMethodCallButton.SetEnabled(hasUser);
AIInvokeButton.SetEnabled(hasUser);
//Cosmetic delay
await Task.Delay(_flickerDurationMS/2);
// Set Interactivity
_hudUI.IsEnabledUI = true;
}
// Methods ---------------------------------------
private async Task DoAccountsSignIn()
{
// UI
await RefreshUI();
_hudUI.IsEnabledUI = false;
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Create / Sign In a User";
_hudUI.InputTextField01.label = $"Email";
_hudUI.InputTextField01.value = $"{_userEmail}";
_hudUI.InputTextField02.label = $"Password";
_hudUI.InputTextField02.value = $"{_userPassword}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
//////////////////////////////////////
// Subsystem: Accounts
//////////////////////////////////////
// Check
if (!Jaws.Instance.Accounts.HasUser())
{
// Create User
Stopwatch stopwatch = new Stopwatch();
_hudUI.MeasureLatencyBegin();
var userCreateResponse = await Jaws.Instance.Accounts.UserCreateAsync(_userEmail, _userPassword, _userNickname);
_hudUI.MeasureLatencyEnd();
LogResponse($"Jaws #1: userCreateResponse", userCreateResponse);
if (!userCreateResponse.IsSuccess)
{
_hudUI.OutputTextField02SetError(userCreateResponse.ErrorMessage);
}
// Sign In User
_hudUI.MeasureLatencyBegin();
var userSignInResponse = await Jaws.Instance.Accounts.UserSignInAsync(_userEmail, _userPassword);
_hudUI.MeasureLatencyEnd();
LogResponse($"Jaws #2: userSignInResponse", userSignInResponse);
if (!userSignInResponse.IsSuccess)
{
_hudUI.OutputTextField02SetError(userCreateResponse.ErrorMessage);
}
}
// Results
var user = Jaws.Instance.Accounts.GetUser();
// UI
_hudUI.OutputTextField01.label = $"User";
_hudUI.OutputTextField01.value = $"Email = {user.Email}, TokenId = {user.TokenId}, AccessToken = {user.AccessToken}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
_hudUI.IsEnabledUI = true;
}
private async Task DoAccountsSignOut()
{
// UI
await RefreshUI();
_hudUI.IsEnabledUI = false;
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Sign Out a User";
_hudUI.InputTextField01.label = $"Email";
_hudUI.InputTextField01.value = $"{_userEmail}";
_hudUI.InputTextField02.label = $"Password";
_hudUI.InputTextField02.value = $"{_userPassword}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
//////////////////////////////////////
// Subsystem: Accounts
//////////////////////////////////////
// Check
if (Jaws.Instance.Accounts.HasUser())
{
// Sign In User
string accessToken = Jaws.Instance.Accounts.GetUser().AccessToken;
_hudUI.MeasureLatencyBegin();
UserSignOutResponse userSignOutResponse = await Jaws.Instance.Accounts.UserSignOutAsync(accessToken);
_hudUI.MeasureLatencyEnd();
LogResponse($"Jaws #1: userSignOutResponse", userSignOutResponse);
if (!userSignOutResponse.IsSuccess)
{
_hudUI.OutputTextField02SetError(userSignOutResponse.ErrorMessage);
}
}
_hudUI.ClearTextField(_hudUI.InputTextField01);
_hudUI.ClearTextField(_hudUI.InputTextField02);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
_hudUI.OutputTextField01.label = "Result";
_hudUI.OutputTextField01.value = "Success";
_hudUI.IsEnabledUI = true;
}
private async Task DoDatabaseCreateTable()
{
if (!Jaws.Instance.Accounts.HasUser())
{
await DoAccountsSignIn();
}
if (!Jaws.Instance.Accounts.HasUser())
{
Debug.Log($"DoDatabaseCreateTable() failed. HasUser() must not be {Jaws.Instance.Accounts.HasUser()}");
}
//UI
await RefreshUI();
_hudUI.IsEnabledUI = false;
//////////////////////////////////////
// Subsystem: Database Table Read
//////////////////////////////////////
TableReadResponse response = null;
Table table = new InventoryTable();
if (Jaws.Instance.Accounts.HasUser())
{
// UI
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Table Read";
_hudUI.InputTextField01.label = $"TableName";
_hudUI.InputTextField01.value = $"{table.TableName}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
// Call
_hudUI.MeasureLatencyBegin();
response = await Jaws.Instance.Database.TableReadAsync(table.TableName);
_hudUI.MeasureLatencyEnd();
// UI
if (response.IsSuccess)
{
_hudUI.OutputTextField01.label = $"TableName";
_hudUI.OutputTextField01.value = $"{response.Table.TableName}";
_hudUI.OutputTextField02.label = $"ItemCount";
_hudUI.OutputTextField02.value = $"{response.Table.ItemCount}";
_demoModel.DatabaseHasTable = true;
}
else
{
_hudUI.OutputTextField02SetError(response.ErrorMessage);
}
}
//////////////////////////////////////
// Subsystem: Database - Item Read
//////////////////////////////////////
User user = Jaws.Instance.Accounts.GetUser();
GoldInventoryItem item = new GoldInventoryItem();
ItemReadResponse itemReadResponse = null;
if (user != null && table != null && item != null)
{
// Setup
// UI
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Item Read";
_hudUI.InputTextField01.label = $"TableName";
_hudUI.InputTextField01.value = $"{table.TableName}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
// Call
_hudUI.MeasureLatencyBegin();
itemReadResponse = await Jaws.Instance.Database.ItemReadAsync(table, user, item);
_hudUI.MeasureLatencyEnd();
// UI
if (response.IsSuccess)
{
_hudUI.OutputTextField01.label = $"TableName";
_hudUI.OutputTextField01.value = $"{itemReadResponse.Table.TableName}";
_hudUI.OutputTextField02.label = $"Item";
_hudUI.OutputTextField02.value = $"{itemReadResponse.Item.Quantity} {itemReadResponse.Item.Name}";
_demoModel.DatabaseItemQuantityPrevious = itemReadResponse.Item.Quantity;
}
else
{
_hudUI.OutputTextField02SetError(response.ErrorMessage);
}
}
//NOTE: Only create if it doesn't already exist
if (!itemReadResponse.IsSuccess)
{
//////////////////////////////////////
// Subsystem: Database - Item Create
//////////////////////////////////////
item.Quantity = 10;
if (user != null && table != null && item != null)
{
// Setup
// UI
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Item Create";
_hudUI.InputTextField01.label = $"TableName";
_hudUI.InputTextField01.value = $"{table.TableName}";
// Call
_hudUI.MeasureLatencyBegin();
ItemCreateResponse itemCreateResponse = await Jaws.Instance.Database.ItemCreateAsync(table, user, item);
_hudUI.MeasureLatencyEnd();
// UI
if (response.IsSuccess)
{
_hudUI.OutputTextField01.label = $"TableName";
_hudUI.OutputTextField01.value = $"{itemCreateResponse.Table.TableName}";
_hudUI.OutputTextField02.label = $"Item";
_hudUI.OutputTextField02.value =
$"{itemCreateResponse.Item.Quantity} {itemCreateResponse.Item.Name}";
}
else
{
_hudUI.OutputTextField02SetError(response.ErrorMessage);
}
}
}
//UI
_hudUI.IsEnabledUI = true;
}
private async Task DoDatabaseUpdateTable(InventoryItem item )
{
if (!Jaws.Instance.Accounts.HasUser())
{
await DoAccountsSignIn();
}
if (!_demoModel.DatabaseHasTable)
{
await DoDatabaseCreateTable();
}
//UI
await RefreshUI();
_hudUI.IsEnabledUI = false;
//////////////////////////////////////
// Subsystem: Database - Item Update
//////////////////////////////////////
User user = Jaws.Instance.Accounts.GetUser();
InventoryTable table = new InventoryTable();
if (user != null)
{
// UI
_hudUI.InputTextField01.label = $"TableName";
_hudUI.InputTextField01.value = $"{table.TableName}";
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Item Update";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
// Call
_hudUI.MeasureLatencyBegin();
ItemUpdateResponse itemUpdateResponse = await Jaws.Instance.Database.ItemUpdateAsync(table, user, item);
_hudUI.MeasureLatencyEnd();
// UI
if (itemUpdateResponse.IsSuccess)
{
_hudUI.OutputTextField01.label = $"TableName";
_hudUI.OutputTextField01.value = $"{itemUpdateResponse.Table.TableName}";
_hudUI.OutputTextField02.label = $"Item";
_hudUI.OutputTextField02.value = $"{itemUpdateResponse.Item.Quantity} {itemUpdateResponse.Item.Name}";
_demoModel.DatabaseItemQuantityPrevious = itemUpdateResponse.Item.Quantity;
}
else
{
_hudUI.OutputTextField02SetError(itemUpdateResponse.ErrorMessage);
}
}
//UI
_hudUI.IsEnabledUI = true;
}
private async Task DoCloudCodeMethodCall()
{
if (!Jaws.Instance.Accounts.HasUser())
{
await DoAccountsSignIn();
}
if (!Jaws.Instance.Accounts.HasUser())
{
Debug.Log($"DoCloudCodeMethodCall() failed. HasUser() must not be {Jaws.Instance.Accounts.HasUser()}");
}
//UI
await RefreshUI();
_hudUI.IsEnabledUI = false;
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Call Cloud Code";
//////////////////////////////////////
// Subsystem: Cloud Code
//////////////////////////////////////
if (Jaws.Instance.Accounts.HasUser())
{
// Prepare
string functionName = "HelloWorld";
Dictionary args = new Dictionary();
args.Add("message", "this is from the client");
// UI
_hudUI.InputTextField01.label = $"functionName";
_hudUI.InputTextField01.value = $"{functionName}";
_hudUI.InputTextField02.label = $"args";
_hudUI.InputTextField02.value = $"{JsonConvert.SerializeObject(args)}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
// Call
_hudUI.MeasureLatencyBegin();
MethodCallResponse response = await Jaws.Instance.CloudCode.MethodCallAsync(functionName, args);
_hudUI.MeasureLatencyEnd();
// UI
if (response.IsSuccess)
{
_hudUI.OutputTextField01.label = $"Result";
_hudUI.OutputTextField01.value = $"{response.Data}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
//We may or may not have a table at this moment,
//but pretend we DO NOT for a clean UX
_demoModel.DatabaseHasTable = false;
}
else
{
_hudUI.OutputTextField02SetError(response.ErrorMessage);
}
}
//UI
_hudUI.IsEnabledUI = true;
}
private async Task DoAIInvoke()
{
if (!Jaws.Instance.Accounts.HasUser())
{
await DoAccountsSignIn();
}
if (!Jaws.Instance.Accounts.HasUser())
{
Debug.Log($"DoAIInvoke() failed. HasUser() must not be {Jaws.Instance.Accounts.HasUser()}");
}
//UI
await RefreshUI();
_hudUI.IsEnabledUI = false;
_hudUI.DescriptionLabel.text = $"{_descriptionPrefix}Invoke AI Prompt";
//////////////////////////////////////
// Subsystem: Cloud Code
//////////////////////////////////////
if (Jaws.Instance.Accounts.HasUser())
{
// Prepare
string functionName = "HelloWorld";
Dictionary args = new Dictionary();
args.Add("message", "this is from the client");
// UI
_hudUI.InputTextField01.label = $"functionName";
_hudUI.InputTextField01.value = $"{functionName}";
_hudUI.InputTextField02.label = $"args";
_hudUI.InputTextField02.value = $"{JsonConvert.SerializeObject(args)}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
// Call
_hudUI.MeasureLatencyBegin();
InvokeAIModelResponse response = await Jaws.Instance.AI.InvokeAIModel(new InvokeAIModelRequest());
_hudUI.MeasureLatencyEnd();
// UI
if (response.IsSuccess)
{
_hudUI.OutputTextField01.label = $"Result";
_hudUI.OutputTextField01.value = $"{response}";
_hudUI.ClearTextField(_hudUI.OutputTextField01);
_hudUI.ClearTextField(_hudUI.OutputTextField02);
//We may or may not have a table at this moment,
//but pretend we DO NOT for a clean UX
_demoModel.DatabaseHasTable = false;
}
else
{
_hudUI.OutputTextField02SetError(response.ErrorMessage);
}
}
//UI
_hudUI.IsEnabledUI = true;
}
private void LogResponse(string message, Response response)
{
Debug.Log($"{message}. IsSuccess = {response.IsSuccess}");
if (!response.IsSuccess)
{
Debug.LogError($"\t{response.ErrorMessage}");
}
}
// Event Handlers --------------------------------
}
}