Skip to content

Commit

Permalink
feat(scoreboard): implement all methods in EndstoneObjective
Browse files Browse the repository at this point in the history
  • Loading branch information
wu-vincent committed Jul 20, 2024
1 parent c4b9392 commit 3623534
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 61 deletions.
10 changes: 6 additions & 4 deletions include/endstone/detail/scoreboard/objective.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#pragma once

#include <functional>
#include <memory>
#include <optional>

Expand All @@ -38,19 +39,20 @@ class EndstoneObjective : public Objective {
[[nodiscard]] bool isModifiable() const override;
[[nodiscard]] Scoreboard &getScoreboard() const override;
[[nodiscard]] std::optional<DisplaySlot> getDisplaySlot() const override;
void setDisplaySlot(DisplaySlot slot) override;
[[nodiscard]] std::optional<ObjectiveSortOrder> getSortOrder() const override;
void setDisplay(DisplaySlot slot) override;
void setDisplay(DisplaySlot slot, ObjectiveSortOrder order) override;
[[nodiscard]] std::optional<RenderType> getRenderType() const override;
void setRenderType(RenderType render_type) override;
[[nodiscard]] std::optional<ObjectiveSortOrder> getSortOrder() const override;
void setSortOrder(ObjectiveSortOrder order) override;
[[nodiscard]] std::unique_ptr<Score> getScore(ScoreEntry entry) const override;

[[nodiscard]] bool checkState() const;

private:
friend class EndstoneScore;

static std::string toBedrock(DisplaySlot slot);
void foreachDisplayObjective(const std::function<bool(DisplaySlot, const DisplayObjective &)> &callback) const;
static std::string getDisplaySlotName(DisplaySlot slot);

std::string name_;
EndstoneScoreboard &scoreboard_;
Expand Down
4 changes: 4 additions & 0 deletions include/endstone/scoreboard/display_slot.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ namespace endstone {
* @brief Locations for displaying objectives to the player
*/
enum class DisplaySlot {
/**
* @brief Indicates that the score will not be displayed.
*/
None,
/**
* @brief Displays the score below the player's name.
*/
Expand Down
34 changes: 18 additions & 16 deletions include/endstone/scoreboard/objective.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,40 +80,42 @@ class Objective {
[[nodiscard]] virtual std::optional<DisplaySlot> getDisplaySlot() const = 0;

/**
* @brief Sets this objective to display on the specified slot for the scoreboard, removing it from any other
* display slot.
* @brief Gets the sort order for this objective.
*
* @param slot display slot to change
* @return The sort order for this objective.
*/
virtual void setDisplaySlot(DisplaySlot slot) = 0;
[[nodiscard]] virtual std::optional<ObjectiveSortOrder> getSortOrder() const = 0;

/**
* Gets manner in which this objective will be rendered.
* @brief Sets the display slot for this objective.
* This will remove it from any other display slot.
*
* @return the render type
* @param slot The display slot where this objective should be displayed.
*/
[[nodiscard]] virtual std::optional<RenderType> getRenderType() const = 0;
virtual void setDisplay(DisplaySlot slot) = 0;

/**
* @brief Sets manner in which this objective will be rendered.
* @brief Sets the display slot and sort order for this objective.
* This will remove it from any other display slot.
*
* @param render_type new render type
* @param slot The display slot where this objective should be displayed.
* @param order The sort order for this objective in the display slot.
*/
virtual void setRenderType(RenderType render_type) = 0;
virtual void setDisplay(DisplaySlot slot, ObjectiveSortOrder order) = 0;

/**
* @brief Gets the sort order for this objective.
* Gets manner in which this objective will be rendered.
*
* @return The sort order for this objective.
* @return the render type
*/
[[nodiscard]] virtual std::optional<ObjectiveSortOrder> getSortOrder() const = 0;
[[nodiscard]] virtual std::optional<RenderType> getRenderType() const = 0;

/**
* @brief Sets the sort order for this objective.
* @brief Sets manner in which this objective will be rendered.
*
* @param order The sort order to set.
* @param render_type new render type
*/
virtual void setSortOrder(ObjectiveSortOrder order) = 0;
virtual void setRenderType(RenderType render_type) = 0;

/**
* @brief Gets an entry's Score for this objective.
Expand Down
12 changes: 5 additions & 7 deletions python/src/endstone/_internal/endstone_python.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ class Objective:
"""
Gets an entry's Score for this objective
"""
def set_display(self, slot: DisplaySlot, order: ObjectiveSortOrder | None = None) -> None:
"""
Sets the display slot and sort order for this objective. This will remove it from any other display slot.
"""
@property
def criteria(self) -> Criteria:
"""
Expand All @@ -679,11 +683,8 @@ class Objective:
@property
def display_slot(self) -> DisplaySlot | None:
"""
Gets and sets the display slot this objective is displayed at
Gets the display slot this objective is displayed at
"""
@display_slot.setter
def display_slot(self, arg1: DisplaySlot) -> None:
...
@property
def is_modifiable(self) -> bool:
"""
Expand Down Expand Up @@ -712,9 +713,6 @@ class Objective:
"""
Gets and sets the sort order for this objective
"""
@sort_order.setter
def sort_order(self, arg1: ObjectiveSortOrder) -> None:
...
class ObjectiveSortOrder:
"""
Represents the sort order of objectives on a DisplaySlot.
Expand Down
94 changes: 64 additions & 30 deletions src/endstone_core/scoreboard/objective.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,57 +77,74 @@ Scoreboard &EndstoneObjective::getScoreboard() const

std::optional<DisplaySlot> EndstoneObjective::getDisplaySlot() const
{
std::optional<DisplaySlot> result;
if (!checkState()) {
return std::nullopt;
return result;
}

for (auto const &slot : magic_enum::enum_values<DisplaySlot>()) {
if (const auto *display = scoreboard_.board_.getDisplayObjective(toBedrock(slot)); display) {
if (display->getObjective() == &objective_) {
return slot;
}
foreachDisplayObjective([&](auto slot, const auto &display) -> bool {
if (display.getObjective() == &objective_) {
result = slot;
return false;
}
}
return std::nullopt;
}

void EndstoneObjective::setDisplaySlot(DisplaySlot slot)
{
throw std::runtime_error("Not implemented.");
return true;
});
return result;
}

std::optional<RenderType> EndstoneObjective::getRenderType() const
std::optional<ObjectiveSortOrder> EndstoneObjective::getSortOrder() const
{
if (checkState()) {
return static_cast<RenderType>(objective_.getRenderType());
std::optional<ObjectiveSortOrder> result;
if (!checkState()) {
return result;
}
return std::nullopt;

foreachDisplayObjective([&](auto /*slot*/, const auto &display) -> bool {
if (display.getObjective() == &objective_) {
result = static_cast<ObjectiveSortOrder>(display.getSortOrder());
return false;
}
return true;
});
return result;
}

void EndstoneObjective::setRenderType(RenderType render_type)
void EndstoneObjective::setDisplay(DisplaySlot slot)
{
throw std::runtime_error("Not implemented.");
setDisplay(slot, ObjectiveSortOrder::Ascending);
}

std::optional<ObjectiveSortOrder> EndstoneObjective::getSortOrder() const
void EndstoneObjective::setDisplay(DisplaySlot slot, ObjectiveSortOrder order)
{
if (!checkState()) {
return std::nullopt;
return;
}

for (auto const &slot : magic_enum::enum_values<DisplaySlot>()) {
if (const auto *display = scoreboard_.board_.getDisplayObjective(toBedrock(slot)); display) {
if (display->getObjective() == &objective_) {
return static_cast<ObjectiveSortOrder>(display->getSortOrder());
}
foreachDisplayObjective([this](auto i, const auto &display) -> bool {
if (display.getObjective() == &objective_) {
scoreboard_.board_.clearDisplayObjective(getDisplaySlotName(i));
}
return true;
});

if (slot != DisplaySlot::None) {
scoreboard_.board_.setDisplayObjective(getDisplaySlotName(slot), objective_,
static_cast<::ObjectiveSortOrder>(order));
}
}

std::optional<RenderType> EndstoneObjective::getRenderType() const
{
if (checkState()) {
return static_cast<RenderType>(objective_.getRenderType());
}
return std::nullopt;
}

void EndstoneObjective::setSortOrder(ObjectiveSortOrder order)
void EndstoneObjective::setRenderType(RenderType render_type)
{
throw std::runtime_error("Not implemented.");
auto &server = entt::locator<EndstoneServer>::value();
server.getLogger().error("Objective::setRenderType is not supported.");
}

std::unique_ptr<Score> EndstoneObjective::getScore(ScoreEntry entry) const
Expand All @@ -148,7 +165,23 @@ bool EndstoneObjective::checkState() const
return true;
}

std::string EndstoneObjective::toBedrock(DisplaySlot slot)
void EndstoneObjective::foreachDisplayObjective(
const std::function<bool(DisplaySlot, const DisplayObjective &)> &callback) const
{
for (auto const &slot : magic_enum::enum_values<DisplaySlot>()) {
if (slot == DisplaySlot::None) {
continue;
}

if (const auto *display = scoreboard_.board_.getDisplayObjective(getDisplaySlotName(slot)); display) {
if (!callback(slot, *display)) {
return;
}
}
}
}

std::string EndstoneObjective::getDisplaySlotName(DisplaySlot slot)
{
switch (slot) {
case DisplaySlot::BelowName:
Expand All @@ -157,8 +190,9 @@ std::string EndstoneObjective::toBedrock(DisplaySlot slot)
return "list";
case DisplaySlot::SideBar:
return "sidebar";
default:
throw std::runtime_error("Unknown DisplaySlot!");
}
throw std::runtime_error("You should never be here");
}

} // namespace endstone::detail
15 changes: 11 additions & 4 deletions src/endstone_python/scoreboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,19 @@ void init_scoreboard(py::module_ &m)
.def_property_readonly("scoreboard", &Objective::getScoreboard,
"Gets the scoreboard to which this objective is attached",
py::return_value_policy::reference)
.def_property("display_slot", &Objective::getDisplaySlot, &Objective::setDisplaySlot,
"Gets and sets the display slot this objective is displayed at")
.def_property_readonly("display_slot", &Objective::getDisplaySlot,
"Gets the display slot this objective is displayed at")
.def_property_readonly("sort_order", &Objective::getSortOrder,
"Gets and sets the sort order for this objective")
.def(
"set_display",
[](Objective &self, DisplaySlot slot, std::optional<ObjectiveSortOrder> order) {
self.setDisplay(slot, order.value_or(ObjectiveSortOrder::Ascending));
},
"Sets the display slot and sort order for this objective. This will remove it from any other display slot.",
py::arg("slot"), py::arg("order") = std::nullopt)
.def_property("render_type", &Objective::getRenderType, &Objective::setRenderType,
"Gets and sets the manner in which this objective will be rendered.")
.def_property("sort_order", &Objective::getSortOrder, &Objective::setSortOrder,
"Gets and sets the sort order for this objective")
.def("get_score", &Objective::getScore, "Gets an entry's Score for this objective", py::arg("entry"),
py::return_value_policy::reference);

Expand Down

0 comments on commit 3623534

Please sign in to comment.