Skip to content

Commit

Permalink
[Scripting] Screen class (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
Imrglop committed Nov 30, 2024
1 parent 2c303c6 commit b6ad268
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 8 deletions.
63 changes: 60 additions & 3 deletions src/client/screen/script/JsScreen.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,76 @@
#include "pch.h"
#include "JsScreen.h"
#include <client/event/impl/RendererInitEvent.h>
#include <client/event/impl/RenderGameEvent.h>
#include "sdk/common/client/gui/controls/VisualTree.h"
#include "sdk/common/client/gui/controls/UIControl.h"

JsScreen::JsScreen(JsValueRef object, JsValueRef renderFunc) : renderFunc(renderFunc) {
JS::JsGetCurrentContext(&this->ctx);

Chakra::GetStringProperty(object, L"name");
key = Chakra::GetIntProperty(object, L"key");


Eventing::get().listen<RenderLayerEvent>(this, (EventListenerFunc)&JsScreen::onRender, 1, true);
Eventing::get().listen<KeyUpdateEvent>(this, (EventListenerFunc)&JsScreen::onKey, 1);
Eventing::get().listen<ClickEvent>(this, (EventListenerFunc)&JsScreen::onClick, 1);

this->eventListeners[L"enable"] = {};
this->eventListeners[L"disable"] = {};
this->eventListeners[L"render"] = {};
this->eventListeners[L"key"] = {};
this->eventListeners[L"click"] = {};
}

void JsScreen::onRender(Event& evG) {
auto& ev = reinterpret_cast<RenderLayerEvent&>(evG);
auto view = ev.getScreenView();
if (view->visualTree->rootControl->name == "debug_screen") {
Chakra::SetContext(ctx);

Event ev{ L"render", {} };
auto ret = dispatchEvent(ev.name, ev);
if (ret != JS_INVALID_REFERENCE) {
Chakra::Release(ret);
}
}
}

void JsScreen::onKey(Event& evG) {
auto ret = dispatchEvent(sEv.name, sEv);
if (ret != JS_INVALID_REFERENCE) {
Chakra::Release(ret);
}
}

void JsScreen::onRender(Event& ev)
{
void JsScreen::onClick(Event& evG) {
auto& ev = reinterpret_cast<ClickEvent&>(evG);
Event sEv{ L"click", {Chakra::MakeInt(ev.getMouseButton()), Chakra::MakeInt(ev.getWheelDelta()), ev.isDown() ? Chakra::GetTrue() : Chakra::GetFalse() } };
auto ret = dispatchEvent(sEv.name, sEv);
if (ret != JS_INVALID_REFERENCE) {
Chakra::Release(ret);
}
}

void JsScreen::onEnable(bool ignoreAnims) {
Latite::get().queueForClientThread([this, ignoreAnims]() {
Chakra::SetContext(ctx);

Event ev{ L"enable", { (ignoreAnims ? Chakra::GetTrue() : Chakra::GetFalse()) }};
auto ret = dispatchEvent(ev.name, ev);
if (ret != JS_INVALID_REFERENCE) {
Chakra::Release(ret);
}
});
}

void JsScreen::onDisable() {
Latite::get().queueForClientThread([this]() {
Chakra::SetContext(ctx);
Event ev{ L"disable", { } };
auto ret = dispatchEvent(ev.name, ev);
if (ret != JS_INVALID_REFERENCE) {
Chakra::Release(ret);
}
});
}
12 changes: 7 additions & 5 deletions src/client/screen/script/JsScreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
#include <array>
#include <map>
#include <optional>
#include "client/script/feature/JsEvented.h"

class JsScreen : public Screen {

class JsScreen : public Screen, public JsEvented {
public:
JsScreen(JsValueRef object, JsValueRef renderFunc);

void onRender(class Event& ev);
void onCleanup(Event& ev);
void onInit(Event& ev);
void onKey(Event& ev);
void onClick(Event& ev);

Expand All @@ -22,7 +22,9 @@ class JsScreen : public Screen {
void onEnable(bool ignoreAnims) override;
void onDisable() override;
private:
JsValueRef object;
JsValueRef renderFunc;
JsValueRef object = JS_INVALID_REFERENCE;
JsValueRef renderFunc = JS_INVALID_REFERENCE;
JsContextRef ctx = JS_INVALID_REFERENCE;

std::string name;
};
2 changes: 2 additions & 0 deletions src/client/script/JsScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "class/impl/JsSettingClass.h"
#include "class/impl/JsCommandClass.h"
#include "class/impl/JsNativeModule.h"
#include "class/impl/JsScreenClass.h"
#include "class/impl/game/JsEntityClass.h"
#include "class/impl/game/JsPlayerClass.h"
#include "class/impl/game/JsLocalPlayerClass.h"
Expand Down Expand Up @@ -497,6 +498,7 @@ void JsScript::loadScriptObjects() {
this->classes.push_back(std::make_shared<JsTextureClass>(this));
this->classes.push_back(std::make_shared<JsNativeModule>(this));
this->classes.push_back(std::make_shared<JsBlock>(this));
this->classes.push_back(std::make_shared<JsScreenClass>(this));
JsErrorCode err;

JsValueRef globalObj = Chakra::GetGlobalObject();
Expand Down
55 changes: 55 additions & 0 deletions src/client/script/class/impl/JsScreenClass.h
Original file line number Diff line number Diff line change
@@ -1 +1,56 @@
#pragma once
#include "../JsWrapperClass.h"
#include "util/ChakraUtil.h"
#include "client/screen/script/JsScreen.h"

class JsScreenClass : public JsWrapperClass<JsScreen> {
protected:
static JsValueRef CALLBACK jsConstructor(JsValueRef callee, bool isConstructor,
JsValueRef* arguments, unsigned short argCount, void* callbackState) {
auto thi = reinterpret_cast<JsScreenClass*>(callbackState);
if (!Chakra::VerifyArgCount(argCount, 2)) return JS_INVALID_REFERENCE;
if (!Chakra::VerifyParameters({ {arguments[1], JsString}, {arguments[2], JsFunction} })) return JS_INVALID_REFERENCE;

auto screen = new JsScreen(arguments[0], arguments[2]);
JsValueRef obj = thi->construct(screen, false);
return obj;
}

static JsValueRef CALLBACK toStringCallback(JsValueRef callee, bool isConstructor,
JsValueRef* arguments, unsigned short argCount, void* callbackState) {
auto thi = reinterpret_cast<JsScreenClass*>(callbackState);
auto scn = Get(arguments[0]);
std::string add = std::format("{} ({})", util::WStrToStr(thi->name), scn->getName());
return Chakra::MakeString(L"[object " + util::StrToWStr(add) + L"]");
}

static JsValueRef CALLBACK isActiveCallback(JsValueRef callee, bool isConstructor,
JsValueRef* arguments, unsigned short argCount, void* callbackState) {

return Get(arguments[0])->isActive() ? Chakra::GetTrue() : Chakra::GetFalse();
}
public:
inline static const wchar_t* class_name = L"Screen";

JsScreenClass(class JsScript* owner) : JsWrapperClass(owner, class_name) {
createConstructor(jsConstructor, this);
}

/// <summary>
/// Constructs a JS screen.
/// </summary>
/// <param name="set">The C++ screen to create from.</param>
/// <param name="finalize">Whether to destroy the C++ screen when the object goes out of scope or not.</param>
/// <returns></returns>
JsValueRef construct(JsScreen* screen, bool finalize) {
auto obj = __super::construct(screen, finalize);

Chakra::SetPropertyString(obj, L"name", util::StrToWStr(screen->getName()), true);
return obj;
}

void prepareFunctions() override {
Chakra::SetPropertyString(prototype, L"name", L"", true);
Chakra::DefineFunc(prototype, isActiveCallback, L"isActive", this);
};
};

0 comments on commit b6ad268

Please sign in to comment.