Files
NS_unknown_game/Frostbite2D/include/frostbite2D/script/quickjs_bridge_base.h
T
2026-06-08 19:58:35 +08:00

152 lines
4.0 KiB
C++

#pragma once
#include <frostbite2D/2d/actor.h>
#include <memory>
#include <string>
#include <utility>
namespace qjs {
class Value;
}
namespace frostbite2D {
/**
* @brief Basic bridge object between QuickJS and engine Vec2.
*/
class JsVec2 {
public:
double x = 0.0;
double y = 0.0;
JsVec2() = default;
JsVec2(double xValue, double yValue) : x(xValue), y(yValue) {}
explicit JsVec2(const Vec2& value) : x(value.x), y(value.y) {}
Vec2 toNative() const {
return Vec2(static_cast<float>(x), static_cast<float>(y));
}
};
/**
* @brief Basic bridge base between QuickJS and engine Actor.
*
* This type only exposes the smallest stable surface that all script-side
* Actor wrappers need, so engine bindings and Game-side bindings can share it.
*/
class JsActor {
public:
JsActor() : actor_(MakePtr<Actor>()) {}
explicit JsActor(Ptr<Actor> actor) : actor_(std::move(actor)) {
if (!actor_) {
actor_ = MakePtr<Actor>();
}
}
std::string GetName() const { return actor_->GetName(); }
void SetName(const std::string& name) { actor_->SetName(name); }
std::shared_ptr<JsVec2> GetPosition() const {
return std::make_shared<JsVec2>(actor_->GetPosition());
}
void SetPosition(const std::shared_ptr<JsVec2>& position) {
if (position) {
actor_->SetPosition(position->toNative());
}
}
void SetPositionXY(double x, double y) {
actor_->SetPosition(static_cast<float>(x), static_cast<float>(y));
}
double GetRotation() const { return actor_->GetRotation(); }
void SetRotation(double rotation) {
actor_->SetRotation(static_cast<float>(rotation));
}
std::shared_ptr<JsVec2> GetScale() const {
return std::make_shared<JsVec2>(actor_->GetScale());
}
void SetScale(const std::shared_ptr<JsVec2>& scale) {
if (scale) {
actor_->SetScale(scale->toNative());
}
}
void SetScaleValue(double scale) {
actor_->SetScale(static_cast<float>(scale));
}
bool IsVisible() const { return actor_->IsVisible(); }
void SetVisible(bool visible) { actor_->SetVisible(visible); }
void AddChild(const std::shared_ptr<JsActor>& child) {
if (!actor_ || !child) {
return;
}
actor_->AddChild(child->native());
}
void RemoveAllChildren() {
if (actor_) {
actor_->RemoveAllChildren();
}
}
std::shared_ptr<JsVec2> GetSize() const {
return std::make_shared<JsVec2>(actor_->GetSize());
}
void SetSize(const std::shared_ptr<JsVec2>& size) {
if (size) {
actor_->SetSize(size->toNative());
}
}
void SetSizeWH(double width, double height) {
actor_->SetSize(static_cast<float>(width), static_cast<float>(height));
}
std::shared_ptr<JsVec2> GetAnchor() const {
return std::make_shared<JsVec2>(actor_->GetAnchor());
}
void SetAnchor(const std::shared_ptr<JsVec2>& anchor) {
if (anchor) {
actor_->SetAnchor(anchor->toNative());
}
}
void SetAnchorXY(double x, double y) {
actor_->SetAnchor(static_cast<float>(x), static_cast<float>(y));
}
std::shared_ptr<JsActor> GetParent() const;
std::shared_ptr<JsVec2> GetTopLeftPosition() const;
void SetTopLeftPosition(const std::shared_ptr<JsVec2>& position);
void SetTopLeftPositionXY(double x, double y);
std::shared_ptr<JsVec2> LocalToWorld(const std::shared_ptr<JsVec2>& point) const;
std::shared_ptr<JsVec2> WorldToLocal(const std::shared_ptr<JsVec2>& point) const;
bool ContainsWorldPoint(double x, double y) const;
bool IsEventReceiveEnabled() const {
return actor_ && actor_->IsEventReceiveEnabled();
}
void EnableEventReceive() {
if (actor_) {
actor_->EnableEventReceive();
}
}
void DisableEventReceive() {
if (actor_) {
actor_->DisableEventReceive();
}
}
uint32 AddEventListener(const std::string& type,
std::function<bool(qjs::Value)> callback);
bool RemoveEventListener(uint32 listenerId);
void ClearEventListeners();
const Ptr<Actor>& native() const { return actor_; }
protected:
Ptr<Actor> actor_;
};
} // namespace frostbite2D