|
|
@@ -28,20 +28,37 @@
|
|
|
|
|
|
#include "HighScores.h"
|
|
|
#include <RmlUi/Core/TypeConverter.h>
|
|
|
+#include <RmlUi/Core/Context.h>
|
|
|
+#include <RmlUi/Core/DataModelHandle.h>
|
|
|
#include <stdio.h>
|
|
|
+#include <algorithm>
|
|
|
|
|
|
HighScores* HighScores::instance = nullptr;
|
|
|
|
|
|
-HighScores::HighScores() : Rml::DataSource("high_scores")
|
|
|
+HighScores::HighScores(Rml::Context* context)
|
|
|
{
|
|
|
RMLUI_ASSERT(instance == nullptr);
|
|
|
instance = this;
|
|
|
|
|
|
- for (int i = 0; i < NUM_SCORES; i++)
|
|
|
+ Rml::DataModelConstructor constructor = context->CreateDataModel("high_scores");
|
|
|
+ if (!constructor)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (auto score_handle = constructor.RegisterStruct<Score>())
|
|
|
{
|
|
|
- scores[i].score = -1;
|
|
|
+ score_handle.RegisterMember("name_required", &Score::name_required);
|
|
|
+ score_handle.RegisterMember("name", &Score::name);
|
|
|
+ score_handle.RegisterMemberFunc("colour", &Score::GetColour);
|
|
|
+ score_handle.RegisterMember("wave", &Score::wave);
|
|
|
+ score_handle.RegisterMember("score", &Score::score);
|
|
|
}
|
|
|
|
|
|
+ constructor.RegisterArray<ScoreList>();
|
|
|
+
|
|
|
+ constructor.Bind("scores", &scores);
|
|
|
+
|
|
|
+ model_handle = constructor.GetModelHandle();
|
|
|
+
|
|
|
LoadScores();
|
|
|
}
|
|
|
|
|
|
@@ -54,9 +71,9 @@ HighScores::~HighScores()
|
|
|
instance = nullptr;
|
|
|
}
|
|
|
|
|
|
-void HighScores::Initialise()
|
|
|
+void HighScores::Initialise(Rml::Context* context)
|
|
|
{
|
|
|
- new HighScores();
|
|
|
+ new HighScores(context);
|
|
|
}
|
|
|
|
|
|
void HighScores::Shutdown()
|
|
|
@@ -64,62 +81,10 @@ void HighScores::Shutdown()
|
|
|
delete instance;
|
|
|
}
|
|
|
|
|
|
-void HighScores::GetRow(Rml::StringList& row, const Rml::String& table, int row_index, const Rml::StringList& columns)
|
|
|
-{
|
|
|
- if (table == "scores")
|
|
|
- {
|
|
|
- for (size_t i = 0; i < columns.size(); i++)
|
|
|
- {
|
|
|
- if (columns[i] == "name")
|
|
|
- {
|
|
|
- row.push_back(scores[row_index].name);
|
|
|
- }
|
|
|
- else if (columns[i] == "name_required")
|
|
|
- {
|
|
|
- row.push_back(Rml::CreateString(4, "%d", scores[row_index].name_required));
|
|
|
- }
|
|
|
- else if (columns[i] == "score")
|
|
|
- {
|
|
|
- row.push_back(Rml::CreateString(32, "%d", scores[row_index].score));
|
|
|
- }
|
|
|
- else if (columns[i] == "colour")
|
|
|
- {
|
|
|
- Rml::String colour_string;
|
|
|
- Rml::TypeConverter< Rml::Colourb, Rml::String >::Convert(scores[row_index].colour, colour_string);
|
|
|
- row.push_back(colour_string);
|
|
|
- }
|
|
|
- else if (columns[i] == "wave")
|
|
|
- {
|
|
|
- row.push_back(Rml::CreateString(8, "%d", scores[row_index].wave));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int HighScores::GetNumRows(const Rml::String& table)
|
|
|
-{
|
|
|
- if (table == "scores")
|
|
|
- {
|
|
|
- for (int i = 0; i < NUM_SCORES; i++)
|
|
|
- {
|
|
|
- if (scores[i].score == -1)
|
|
|
- {
|
|
|
- return i;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return NUM_SCORES;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
int HighScores::GetHighScore()
|
|
|
{
|
|
|
- if (instance->GetNumRows("scores") == 0)
|
|
|
- {
|
|
|
+ if (instance->scores.empty())
|
|
|
return 0;
|
|
|
- }
|
|
|
|
|
|
return instance->scores[0].score;
|
|
|
}
|
|
|
@@ -137,53 +102,37 @@ void HighScores::SubmitScore(const Rml::Colourb& colour, int wave, int score)
|
|
|
// Sets the name of the last player to submit their score.
|
|
|
void HighScores::SubmitName(const Rml::String& name)
|
|
|
{
|
|
|
- for (int i = 0; i < instance->GetNumRows("scores"); i++)
|
|
|
+ for (Score& score : instance->scores)
|
|
|
{
|
|
|
- if (instance->scores[i].name_required)
|
|
|
+ if (score.name_required)
|
|
|
{
|
|
|
- instance->scores[i].name = name;
|
|
|
- instance->scores[i].name_required = false;
|
|
|
- instance->NotifyRowChange("scores", i, 1);
|
|
|
+ score.name = name;
|
|
|
+ score.name_required = false;
|
|
|
+
|
|
|
+ instance->model_handle.DirtyVariable("scores");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void HighScores::SubmitScore(const Rml::String& name, const Rml::Colourb& colour, int wave, int score, bool name_required)
|
|
|
{
|
|
|
- for (int i = 0; i < NUM_SCORES; i++)
|
|
|
- {
|
|
|
- if (score > scores[i].score)
|
|
|
- {
|
|
|
- // If we've already got the maximum number of scores, then we have
|
|
|
- // to send a RowsRemoved message as we're going to delete the last
|
|
|
- // row from the data source.
|
|
|
- bool max_rows = scores[NUM_SCORES - 1].score != -1;
|
|
|
+ Score entry;
|
|
|
+ entry.name = name;
|
|
|
+ entry.colour = colour;
|
|
|
+ entry.wave = wave;
|
|
|
+ entry.score = score;
|
|
|
+ entry.name_required = name_required;
|
|
|
|
|
|
- // Push down all the other scores.
|
|
|
- for (int j = NUM_SCORES - 1; j > i; j--)
|
|
|
- {
|
|
|
- scores[j] = scores[j - 1];
|
|
|
- }
|
|
|
+ auto it = std::find_if(scores.begin(), scores.end(), [score](const Score& other) { return score > other.score; });
|
|
|
|
|
|
- // Insert our new score.
|
|
|
- scores[i].name = name;
|
|
|
- scores[i].colour = colour;
|
|
|
- scores[i].wave = wave;
|
|
|
- scores[i].score = score;
|
|
|
- scores[i].name_required = name_required;
|
|
|
+ scores.insert(it, std::move(entry));
|
|
|
|
|
|
- // Send the row removal message (if necessary).
|
|
|
- if (max_rows)
|
|
|
- {
|
|
|
- NotifyRowRemove("scores", NUM_SCORES - 1, 1);
|
|
|
- }
|
|
|
+ constexpr size_t MaxNumberScores = 10;
|
|
|
|
|
|
- // Then send the rows added message.
|
|
|
- NotifyRowAdd("scores", i, 1);
|
|
|
+ if (scores.size() > MaxNumberScores)
|
|
|
+ scores.pop_back();
|
|
|
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
+ model_handle.DirtyVariable("scores");
|
|
|
}
|
|
|
|
|
|
void HighScores::LoadScores()
|
|
|
@@ -204,7 +153,7 @@ void HighScores::LoadScores()
|
|
|
int wave;
|
|
|
int score;
|
|
|
|
|
|
- if (Rml::TypeConverter< Rml::String , Rml::Colourb >::Convert(score_parts[1], colour) &&
|
|
|
+ if (Rml::TypeConverter< Rml::String, Rml::Colourb >::Convert(score_parts[1], colour) &&
|
|
|
Rml::TypeConverter< Rml::String, int >::Convert(score_parts[2], wave) &&
|
|
|
Rml::TypeConverter< Rml::String, int >::Convert(score_parts[3], score))
|
|
|
{
|
|
|
@@ -223,13 +172,13 @@ void HighScores::SaveScores()
|
|
|
|
|
|
if (scores_file)
|
|
|
{
|
|
|
- for (int i = 0; i < GetNumRows("scores"); i++)
|
|
|
+ for (const Score& score : scores)
|
|
|
{
|
|
|
Rml::String colour_string;
|
|
|
- Rml::TypeConverter< Rml::Colourb, Rml::String >::Convert(scores[i].colour, colour_string);
|
|
|
-
|
|
|
- Rml::String score = Rml::CreateString(1024, "%s\t%s\t%d\t%d\n", scores[i].name.c_str(), colour_string.c_str(), scores[i].wave, scores[i].score);
|
|
|
- fputs(score.c_str(), scores_file);
|
|
|
+ Rml::TypeConverter< Rml::Colourb, Rml::String >::Convert(score.colour, colour_string);
|
|
|
+
|
|
|
+ Rml::String score_str = Rml::CreateString(1024, "%s\t%s\t%d\t%d\n", score.name.c_str(), colour_string.c_str(), score.wave, score.score);
|
|
|
+ fputs(score_str.c_str(), scores_file);
|
|
|
}
|
|
|
|
|
|
fclose(scores_file);
|