localStorage にアクセスする関数
https://scrapbox.io/files/64db1c4c99e9f8001bf8a104.png
ソースコードに JavaScript を埋め込んでいます。
コピペする際は、貼り付け時のオートフォーマットで JavaScript が崩れることがある( a === b が a == = b と整形されるなど)ことに注意してください。
code:LocalStorage.hpp
# pragma once
# include <Siv3D/String.hpp>
# include <Siv3D/Optional.hpp>
# include <cstddef>
namespace LocalStorage
{
/// @brief ローカルストレージにキーが存在するかを返します。
/// @param key 確認するキー
/// @return キーが存在する場合 true, それ以外の場合は false
nodiscard
bool Exists(const s3d::String& key);
/// @brief ローカルストレージに保存されたキーに対応する値を返します。
/// @param key 取得する値のキー
/// @return キーに対応する値、キーが存在しない場合は none
nodiscard
s3d::Optional<s3d::String> GetItem(const s3d::String& key);
/// @brief ローカルストレージにキーを追加し、キーに対して値を保存します。
/// @remark キーが既に存在する場合は、そのキーを更新します。
/// @param key 追加、更新するキー
/// @param item 保存、更新する値
void SetItem(const s3d::String& key, const s3d::String& item);
/// @brief ローカルストレージに保存されたキーを削除します。
/// @remark 指定したキーが存在しない場合、何もしません。
/// @param key 削除するキー
void RemoveItem(const s3d::String& key);
/// @brief ローカルストレージに保存されているデータの数を返します。
/// @return 保存されているデータ数
nodiscard
std::size_t Length();
/// @brief ローカルストレージの指定したインデックス番目のキーを返します。
/// @remark キーの順序はユーザエージェント依存です。
/// @param index 0 から始まるインデックス
/// @return インデックス番目のキー、キーが存在しない場合は none
nodiscard
s3d::Optional<s3d::String> Key(std::size_t index);
/// @brief ローカルストレージに保存されているデータをすべて削除します。
void Clear();
}
code:LocalStorage.cpp
# include "LocalStorage.hpp"
# include <emscripten.h>
using namespace s3d;
namespace LocalStorage
{
namespace detail
{
EM_JS
(
bool, Exists, (const char32* key),
{
return localStorage.getItem(UTF32ToString(key)) !== null;
}
);
EM_JS
(
std::size_t, GetLength, (const char32* key),
{
return localStorage.getItem(UTF32ToString(key))?.length ?? -1;
}
);
EM_JS
(
void, GetItem, (const char32* key, char32* s, std::size_t size),
{
const item = localStorage.getItem(UTF32ToString(key)) ?? "";
stringToUTF32(item, s, size * 4);
}
);
EM_JS
(
void, SetItem, (const char32* key, const char32* item),
{
localStorage.setItem(UTF32ToString(key), UTF32ToString(item));
}
);
EM_JS
(
void, RemoveItem, (const char32* key),
{
localStorage.removeItem(UTF32ToString(key));
}
);
EM_JS
(
std::size_t, Length, (),
{
return localStorage.length;
}
);
EM_JS
(
std::size_t, KeyLength, (std::size_t index),
{
return localStorage.key(index)?.length ?? -1;
}
);
EM_JS
(
void, Key, (std::size_t index, char32* s, std::size_t size),
{
const key = localStorage.key(index);
stringToUTF32(item, s, size * 4);
}
);
EM_JS
(
void, Clear, (),
{
localStorage.clear();
}
);
}
bool Exists(const String& key)
{
return detail::Exists(key.c_str());
}
Optional<String> GetItem(const String& key)
{
const auto size = detail::GetLength(key.c_str());
if (size == std::size_t(-1))
{
return none;
}
String item;
if (size)
{
item.resize(size + 1);
detail::GetItem(key.c_str(), item.data(), item.size());
item.resize(size);
}
return item;
}
void SetItem(const String& key, const String& item)
{
detail::SetItem(key.c_str(), item.c_str());
}
void RemoveItem(const String& key)
{
detail::RemoveItem(key.c_str());
}
std::size_t Length()
{
return detail::Length();
}
Optional<String> Key(std::size_t index)
{
const auto size = detail::KeyLength(index);
if (size == std::size_t(-1))
{
return none;
}
String key;
if (size)
{
key.resize(size + 1);
detail::Key(index, key.data(), key.size());
key.resize(size);
}
return key;
}
void Clear()
{
detail::Clear();
}
}
code:Main.cpp
# include <Siv3D.hpp> // OpenSiv3D for Web v0.6.6r1
# include "LocalStorage.hpp"
void Main()
{
const Font font{ 64 };
uint64 count = 0;
if (auto savedCount = LocalStorage::GetItem(U"count"))
{
if (auto value = ParseIntOpt<uint64>(*savedCount))
{
count = *value;
}
}
String countString = ToString(count);
while (System::Update())
{
font(countString).drawAt(Scene::Center());
if (SimpleGUI::ButtonAt(U"+1", Scene::CenterF().movedBy(0, 100)))
{
++count;
countString = ToString(count);
LocalStorage::SetItem(U"count", countString);
}
}
}