This commit is contained in:
Lenheart 2024-05-08 20:54:36 +08:00
parent 808e4015d3
commit 2fd727b47a
16 changed files with 1945 additions and 53 deletions

116
include/CursorEx.hpp Normal file
View File

@ -0,0 +1,116 @@
#pragma once
#include <mutex>
#include <kiwano/core/Common.h>
#include <kiwano/base/Module.h>
#include "SquirrelClassEx.h"
#include "KiwanoEx/SpriteEx.hpp"
extern HSQUIRRELVM v;
extern std::mutex VmMtx;
extern WThreadPool threadPool;
namespace kiwano
{
namespace cursor
{
class KGE_API CursorModule
: public Singleton<CursorModule>
, public Module
{
friend Singleton<CursorModule>;
public:
~CursorModule() {};
void OnUpdate(UpdateModuleContext& ctx) override;
void OnRender(RenderModuleContext& ctx) override;
private:
CursorModule();
private:
SpriteEx* cursor_actor_;
};
}
}
void InitGameRecFunc() {
PVF_M::getInstance().Init();
}
namespace kiwano
{
namespace cursor {
CursorModule::CursorModule() {
}
bool IsMouseInWindow(HWND hWnd)
{
POINT mousePos;
GetCursorPos(&mousePos);
ScreenToClient(hWnd, &mousePos);
RECT windowRect;
GetClientRect(hWnd, &windowRect);
return PtInRect(&windowRect, mousePos);
}
void CursorModule::OnUpdate(UpdateModuleContext& ctx) {
//确保虚拟机已经初始化了 从虚拟机回调中加载鼠标
if (v && !cursor_actor_) {
if (VmMtx.try_lock()) {
SQUserPointer Cursor;
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table
sq_pushstring(v, _SC("InitCursor"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2))) { //gets the field 'foo' from the global table
sq_pushroottable(v); //push the 'this' (in this case is the global table)
sq_call(v, 1, SQTrue, SQTrue); //calls the function
sq_getuserpointer(v, -1, &Cursor);
cursor_actor_ = (SpriteEx*)Cursor;
}
sq_settop(v, top); //restores the original stack size
VmMtx.unlock();
//分配线程去初始化数据
threadPool.concurrentRun(InitGameRecFunc);
}
}
else {
if (VmMtx.try_lock()) {
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table
sq_pushstring(v, _SC("UpdateCursor"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2))) { //gets the field 'foo' from the global table
sq_pushroottable(v); //push the 'this' (in this case is the global table)
sq_pushinteger(v, ctx.dt.GetMilliseconds());
sq_call(v, 2, SQFalse, SQTrue); //calls the function
}
sq_settop(v, top); //restores the original stack size
VmMtx.unlock();
}
////获取输入
Input& input = Input::GetInstance();
cursor_actor_->SetPosition(input.GetMousePos());
if (IsMouseInWindow(GetForegroundWindow()))
ShowCursor(FALSE);
else
ShowCursor(TRUE);
}
}
void CursorModule::OnRender(RenderModuleContext& ctx) {
if (cursor_actor_)cursor_actor_->Render(ctx.render_ctx);
}
}
}

View File

@ -0,0 +1,60 @@
#pragma once
#include <kiwano/kiwano.h>
using namespace kiwano;
namespace kiwano
{
KGE_DECLARE_SMART_PTR(SpriteEx);
class SpriteEx :public Sprite
{
public:
void OnUpdate(Duration dt) override;
void OnRender(RenderContext& ctx) override;
void Update(Duration dt)override;
void Render(RenderContext& ctx)override;
void RenderBorder(RenderContext& ctx)override;
private:
int MyModel = -1;
public:
void SetMode(const int Type);
};
inline void SpriteEx::SetMode(const int Type) {
MyModel = Type;
}
inline void SpriteEx::OnUpdate(Duration dt) {
Sprite::OnUpdate(dt);
}
inline void SpriteEx::OnRender(RenderContext& ctx) {
switch (MyModel)
{
case -1: //-1ԭʼģʽ
ctx.SetBlendMode(BlendMode::SourceOver);
break;
case 0: //0ÏßÐÔ¼õµ­
ctx.SetBlendMode(BlendMode::Add);
break;
default:
ctx.SetBlendMode(BlendMode::SourceOver);
break;
}
Sprite::OnRender(ctx);
}
inline void SpriteEx::Update(Duration dt) {
Sprite::Update(dt);
}
inline void SpriteEx::Render(RenderContext& ctx) {
Sprite::Render(ctx);
}
inline void SpriteEx::RenderBorder(RenderContext& ctx) {
Sprite::RenderBorder(ctx);
}
}

View File

@ -0,0 +1,53 @@
#pragma once
#include <mutex>
#include <kiwano/kiwano.h>
using namespace kiwano;
extern HSQUIRRELVM v;
extern std::mutex VmMtx;
KGE_DECLARE_SMART_PTR(StageEx);
class StageEx :public Stage
{
public:
void OnUpdate(Duration dt) override;
void SetSqrobj(HSQOBJECT obj);
void OnExit()override;
private:
HSQOBJECT obj;
bool CallBackFlag = false;
};
void StageEx::OnUpdate(Duration dt) {
if (CallBackFlag) {
if (VmMtx.try_lock()) {
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushobject(v, obj);
sq_pushstring(v, _SC("OnUpdate"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2))) {
//sq_pushroottable(v);
sq_pushobject(v, obj);
sq_pushinteger(v, dt.GetMilliseconds());
sq_call(v, 2, SQFalse, SQTrue);
}
sq_settop(v, top); //restores the original stack size
VmMtx.unlock();
}
}
}
void StageEx::OnExit() {
if (this->CallBackFlag) {
if (VmMtx.try_lock()) {
sq_release(v, &this->obj);
VmMtx.unlock();
}
this->CallBackFlag = false;
}
}
void StageEx::SetSqrobj(HSQOBJECT obj) {
this->obj = obj;
this->CallBackFlag = true;
}

30
include/Pvf.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <map>
class PVF_M {
public:
static PVF_M& getInstance() {
static PVF_M instance;
return instance;
}
// 禁止拷贝构造函数和赋值运算符重载
PVF_M(const PVF_M&) = delete;
PVF_M& operator=(const PVF_M&) = delete;
private:
PVF_M() {} // 私有构造函数,防止外部创建实例
struct PvfData
{
char* Data;
int Size;
};
public:
void Init();
int charPtrToInt(const char* ptr);
void intToCharPtr(int value, char* ptr);
void CrcDecode(PvfData &Data, const int crc32);
};

View File

@ -1,15 +1,36 @@
#pragma once
#include "SquirrelClassEx.h"
#include "Tool.hpp"
#include <iostream>
#define SAFE_READN(ptr,len) { \
if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \
}
static SQInteger _stream_myreadstring(HSQUIRRELVM v)
{
SQStream* self = NULL;
if (SQ_FAILED(sq_getinstanceup(v, 1, (SQUserPointer*)&self, (SQUserPointer)((SQUnsignedInteger)SQSTD_STREAM_TYPE_TAG), SQFalse))) \
return sq_throwerror(v, _SC("invalid type tag")); \
if (!self || !self->IsValid()) \
return sq_throwerror(v, _SC("the stream is invalid"));
SQInteger Count;
sq_getinteger(v, 2, &Count);
char* Str = new char[Count+1];
self->Read(Str, Count);
std::string Sstr(Str, Count);
delete[]Str;
sq_pushstring(v, TOOL::charTowchar_t(Sstr).c_str(), -1);
return 1;
}
static SQInteger _file_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size))
{
Actor* Abli = (Actor*)p;
std::cout << "C++对象: " << Abli->GetName() << std::endl;
std::cout << "引用计数: " << Abli->GetRefCount() << std::endl;
std::cout << "C++对象: " << (Abli->GetName().empty() ? "无名字" : Abli->GetName()) << "当前引用计数: " << Abli->GetRefCount() << "已释放一次引用计数" << std::endl;
Abli->Release();
std::cout << "对象引用次数已被减少,如为0将会释放" << std::endl;
return 0;
}
@ -25,21 +46,655 @@ static SQInteger Register_Destruction(HSQUIRRELVM v)
sq_setreleasehook(v, 3, _file_releasehook);
return 0;
}
//内存泄露追踪
static SQInteger BaseObject_DumpTracing(HSQUIRRELVM v)
{
ObjectBase::DumpTracingObjects();
return 0;
}
//角色类通用添加子对象
static SQInteger BaseObject_Addchild(HSQUIRRELVM v)
{
SQUserPointer Pb;
sq_getuserpointer(v, 2, &Pb);
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQUserPointer Cb;
sq_getuserpointer(v, 3, &Cb);
SQUserPointer B_obj;
sq_getuserpointer(v, 3, &B_obj);
Actor* XPb = (Actor*)Pb;
Actor* XCb = (Actor*)Cb;
XPb->AddChild(XCb);
Actor* Aobj = (Actor*)A_obj;
Actor* Bobj = (Actor*)B_obj;
Aobj->AddChild(Bobj);
return 0;
}
//角色类通用移除子对象
static SQInteger BaseObject_Removechild(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQUserPointer B_obj;
sq_getuserpointer(v, 3, &B_obj);
Actor* Aobj = (Actor*)A_obj;
Actor* Bobj = (Actor*)B_obj;
Aobj->RemoveChild(Bobj);
return 0;
}
//角色类通用设置名字
static SQInteger BaseObject_SetName(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
const SQChar* Name;
sq_getstring(v, 3, &Name);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetName(TOOL::SquirrelU2W(Name));
return 0;
}
//角色类通用获取名字
static SQInteger BaseObject_GetName(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
std::string Name = Aobj->GetName();
sq_pushstring(v, TOOL::charTowchar_t(Name).c_str(), -1);
return 1;
}
//角色类通用获取ObjectId
static SQInteger BaseObject_GetId(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushinteger(v, Aobj->GetObjectID());
return 1;
}
//角色类通用 获取显示状态
static SQInteger BaseObject_IsVisible(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushbool(v, Aobj->IsVisible());
return 1;
}
//角色类通用 是否启用级联透明度
static SQInteger BaseObject_IsCascadeOpacityEnabled(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushbool(v, Aobj->IsCascadeOpacityEnabled());
return 1;
}
//角色类通用 是否启用事件分发
static SQInteger BaseObject_IsEventDispatchEnabled(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushbool(v, Aobj->IsEventDispatchEnabled());
return 1;
}
//角色类通用 获取名称的 Hash 值
static SQInteger BaseObject_GetHashName(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushinteger(v, Aobj->GetHashName());
return 1;
}
//角色类通用 获取 Z 轴顺序
static SQInteger BaseObject_GetZOrder(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushinteger(v, Aobj->GetZOrder());
return 1;
}
//角色类通用 获取坐标
static SQInteger BaseObject_GetPosition(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Point Pos = Aobj->GetPosition();
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v,Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
//角色类通用 获取大小
static SQInteger BaseObject_GetSize(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Size Pos = Aobj->GetSize();
sq_newtable(v);
sq_pushstring(v, _SC("w"), -1);
sq_pushfloat(v, Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("h"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
//角色类通用 获取缩放后的大小
static SQInteger BaseObject_GetScaledSize(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Size Pos = Aobj->GetScaledSize();
sq_newtable(v);
sq_pushstring(v, _SC("w"), -1);
sq_pushfloat(v, Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("h"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
//角色类通用 获取锚点
static SQInteger BaseObject_GetAnchor(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Point Pos = Aobj->GetAnchor();
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
//角色类通用 获取透明度
static SQInteger BaseObject_GetOpacity(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushfloat(v, Aobj->GetOpacity());
return 1;
}
//角色类通用 获取显示透明度
static SQInteger BaseObject_GetDisplayedOpacity(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushfloat(v, Aobj->GetDisplayedOpacity());
return 1;
}
//角色类通用 获取旋转角度
static SQInteger BaseObject_GetRotation(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
sq_pushfloat(v, Aobj->GetRotation());
return 1;
}
//角色类通用 获取缩放比例
static SQInteger BaseObject_GetScale(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Point Pos = Aobj->GetScale();
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
//角色类通用 获取错切角度
static SQInteger BaseObject_GetSkew(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Point Pos = Aobj->GetSkew();
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Pos.x);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Pos.y);
sq_newslot(v, 3, SQFalse);
return 1;
}
//角色类通用 获取变换
static SQInteger BaseObject_GetTransform(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Transform Tf = Aobj->GetTransform();
sq_newtable(v);
sq_pushstring(v, _SC("pos"), -1);
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Tf.position.x);
sq_newslot(v, 5, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Tf.position.y);
sq_newslot(v, 5, SQFalse);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("scale"), -1);
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Tf.scale.x);
sq_newslot(v, 5, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Tf.scale.y);
sq_newslot(v, 5, SQFalse);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("skew"), -1);
sq_newtable(v);
sq_pushstring(v, _SC("x"), -1);
sq_pushfloat(v, Tf.skew.x);
sq_newslot(v, 5, SQFalse);
sq_pushstring(v, _SC("y"), -1);
sq_pushfloat(v, Tf.skew.y);
sq_newslot(v, 5, SQFalse);
sq_newslot(v, 3, SQFalse);
sq_pushstring(v, _SC("rotation"), -1);
sq_pushfloat(v, Tf.rotation);
sq_newslot(v, 3, SQFalse);
return 1;
}
//角色类通用 获取父角色
static SQInteger BaseObject_GetParent(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
Actor* P = Aobj->GetParent();
sq_pushuserpointer(v, P);
return 1;
}
//角色类通用 获取所在舞台
static SQInteger BaseObject_GetStage(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
Actor* Aobj = (Actor*)A_obj;
StageEx* P = (StageEx*)Aobj->GetStage();
sq_pushuserpointer(v, P);
return 1;
}
//角色类通用 设置角色是否可见
static SQInteger BaseObject_SetVisible(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQBool Value;
sq_getbool(v, 3, &Value);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetVisible(Value);
return 0;
}
//角色类通用 设置坐标
static SQInteger BaseObject_SetPosition(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3) {
Point Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar* key;
sq_getstring(v, -2, &key);
if (wcscmp(key, _SC("x")) == 0) {
Pos.x = value;
}
else if (wcscmp(key, _SC("y")) == 0) {
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetPosition(Pos);
}
else if (sq_gettop(v) == 4) {
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetPosition(X,Y);
}
return 0;
}
//角色类通用 设置缩放比例
static SQInteger BaseObject_SetScale(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3) {
Point Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar* key;
sq_getstring(v, -2, &key);
if (wcscmp(key, _SC("x")) == 0) {
Pos.x = value;
}
else if (wcscmp(key, _SC("y")) == 0) {
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetScale(Pos);
}
else if (sq_gettop(v) == 4) {
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetScale(X, Y);
}
return 0;
}
//角色类通用 设置错切角度
static SQInteger BaseObject_SetSkew(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3) {
Point Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar* key;
sq_getstring(v, -2, &key);
if (wcscmp(key, _SC("x")) == 0) {
Pos.x = value;
}
else if (wcscmp(key, _SC("y")) == 0) {
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetSkew(Pos);
}
else if (sq_gettop(v) == 4) {
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetSkew(X, Y);
}
return 0;
}
//角色类通用 设置锚点位置
static SQInteger BaseObject_SetAnchor(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3) {
Point Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar* key;
sq_getstring(v, -2, &key);
if (wcscmp(key, _SC("x")) == 0) {
Pos.x = value;
}
else if (wcscmp(key, _SC("y")) == 0) {
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetAnchor(Pos);
}
else if (sq_gettop(v) == 4) {
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetAnchor(X, Y);
}
return 0;
}
//角色类通用 修改大小
static SQInteger BaseObject_SetSize(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3) {
Size Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar* key;
sq_getstring(v, -2, &key);
if (wcscmp(key, _SC("w")) == 0) {
Pos.x = value;
}
else if (wcscmp(key, _SC("h")) == 0) {
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetSize(Pos);
}
else if (sq_gettop(v) == 4) {
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetSize(X, Y);
}
return 0;
}
//角色类通用 设置旋转角度
static SQInteger BaseObject_SetRotation(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQFloat Value;
sq_getfloat(v, 3, &Value);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetRotation(Value);
return 0;
}
//角色类通用 设置透明度
static SQInteger BaseObject_SetOpacity(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQFloat Value;
sq_getfloat(v, 3, &Value);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetOpacity(Value);
return 0;
}
//角色类通用 启用或禁用级联透明度
static SQInteger BaseObject_SetCascadeOpacityEnabled(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQBool Value;
sq_getbool(v, 3, &Value);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetCascadeOpacityEnabled(Value);
return 0;
}
//角色类通用 设置 Z 轴顺序
static SQInteger BaseObject_SetZOrder(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQInteger Value;
sq_getinteger(v, 3, &Value);
Actor* Aobj = (Actor*)A_obj;
Aobj->SetZOrder(Value);
return 0;
}
//角色类通用 判断点是否在角色内
static SQInteger BaseObject_IsContainsPoint(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
if (sq_gettop(v) == 3) {
Point Pos;
sq_pushnull(v); // null iterator
while (SQ_SUCCEEDED(sq_next(v, 3)))
{
SQFloat value;
sq_getfloat(v, -1, &value);
const SQChar* key;
sq_getstring(v, -2, &key);
if (wcscmp(key, _SC("w")) == 0) {
Pos.x = value;
}
else if (wcscmp(key, _SC("h")) == 0) {
Pos.y = value;
}
sq_pop(v, 2);
}
sq_pop(v, 1);
Actor* Aobj = (Actor*)A_obj;
sq_pushbool(v, Aobj->ContainsPoint(Pos));
}
else if (sq_gettop(v) == 4) {
SQFloat X, Y;
sq_getfloat(v, 3, &X);
sq_getfloat(v, 4, &Y);
Point Pos(X,Y);
Actor* Aobj = (Actor*)A_obj;
sq_pushbool(v, Aobj->ContainsPoint(Pos));
}
return 1;
}
//角色类通用 渲染角色边界
static SQInteger BaseObject_ShowBorder(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQBool Value;
sq_getbool(v, 3, &Value);
Actor* Aobj = (Actor*)A_obj;
Aobj->ShowBorder(Value);
return 0;
}
//角色类通用 旋轉
static SQInteger BaseObject_SetRotate(HSQUIRRELVM v)
{
SQUserPointer A_obj;
sq_getuserpointer(v, 2, &A_obj);
SQInteger Duration;
sq_getinteger(v, 3, &Duration);
SQFloat Rotation;
sq_getfloat(v, 4, &Rotation);
//通过时间和角度设置动画
auto rotate_by = animation::RotateBy(Duration, Rotation);
//设置无限循环
rotate_by.Loops(-1);
Actor* Aobj = (Actor*)A_obj;
Aobj->StartAnimation(rotate_by);
return 0;
}
void RegisterBaseNutApi(const SQChar* funcName, void* funcAddr, HSQUIRRELVM v)
{
@ -51,8 +706,49 @@ void RegisterBaseNutApi(const SQChar* funcName, void* funcAddr, HSQUIRRELVM v)
}
void RegisterBase(HSQUIRRELVM v) {
//打印全部kiwano对象个数
RegisterBaseNutApi(_SC("BaseObject_DumpTracing"), BaseObject_DumpTracing, v);
//读取流的字符串
RegisterBaseNutApi(_SC("stream_myreadstring"), _stream_myreadstring, v);
//析构函数
RegisterBaseNutApi(_SC("Register_Destruction"), Register_Destruction, v);
//添加子对象
RegisterBaseNutApi(_SC("BaseObject_Addchild"), BaseObject_Addchild, v);
RegisterBaseNutApi(_SC("BaseObject_Removechild"), BaseObject_Removechild, v);
RegisterBaseNutApi(_SC("BaseObject_SetName"), BaseObject_SetName, v);
RegisterBaseNutApi(_SC("BaseObject_GetName"), BaseObject_GetName, v);
RegisterBaseNutApi(_SC("BaseObject_GetId"), BaseObject_GetId, v);
RegisterBaseNutApi(_SC("BaseObject_IsVisible"), BaseObject_IsVisible, v);
RegisterBaseNutApi(_SC("BaseObject_IsCascadeOpacityEnabled"), BaseObject_IsCascadeOpacityEnabled, v);
RegisterBaseNutApi(_SC("BaseObject_IsEventDispatchEnabled"), BaseObject_IsEventDispatchEnabled, v);
RegisterBaseNutApi(_SC("BaseObject_GetHashName"), BaseObject_GetHashName, v);
RegisterBaseNutApi(_SC("BaseObject_GetZOrder"), BaseObject_GetZOrder, v);
RegisterBaseNutApi(_SC("BaseObject_GetPosition"), BaseObject_GetPosition, v);
RegisterBaseNutApi(_SC("BaseObject_GetSize"), BaseObject_GetSize, v);
RegisterBaseNutApi(_SC("BaseObject_GetScaledSize"), BaseObject_GetScaledSize, v);
RegisterBaseNutApi(_SC("BaseObject_GetAnchor"), BaseObject_GetAnchor, v);
RegisterBaseNutApi(_SC("BaseObject_GetOpacity"), BaseObject_GetOpacity, v);
RegisterBaseNutApi(_SC("BaseObject_GetDisplayedOpacity"), BaseObject_GetDisplayedOpacity, v);
RegisterBaseNutApi(_SC("BaseObject_GetRotation"), BaseObject_GetRotation, v);
RegisterBaseNutApi(_SC("BaseObject_GetScale"), BaseObject_GetScale, v);
RegisterBaseNutApi(_SC("BaseObject_GetSkew"), BaseObject_GetSkew, v);
RegisterBaseNutApi(_SC("BaseObject_GetTransform"), BaseObject_GetTransform, v);
RegisterBaseNutApi(_SC("BaseObject_GetParent"), BaseObject_GetParent, v);
RegisterBaseNutApi(_SC("BaseObject_GetStage"), BaseObject_GetStage, v);
RegisterBaseNutApi(_SC("BaseObject_SetVisible"), BaseObject_SetVisible, v);
RegisterBaseNutApi(_SC("BaseObject_SetPosition"), BaseObject_SetPosition, v);
RegisterBaseNutApi(_SC("BaseObject_SetScale"), BaseObject_SetScale, v);
RegisterBaseNutApi(_SC("BaseObject_SetSkew"), BaseObject_SetSkew, v);
RegisterBaseNutApi(_SC("BaseObject_SetAnchor"), BaseObject_SetAnchor, v);
RegisterBaseNutApi(_SC("BaseObject_SetSize"), BaseObject_SetSize, v);
RegisterBaseNutApi(_SC("BaseObject_SetRotation"), BaseObject_SetRotation, v);
RegisterBaseNutApi(_SC("BaseObject_SetOpacity"), BaseObject_SetOpacity, v);
RegisterBaseNutApi(_SC("BaseObject_SetCascadeOpacityEnabled"), BaseObject_SetCascadeOpacityEnabled, v);
RegisterBaseNutApi(_SC("BaseObject_SetZOrder"), BaseObject_SetZOrder, v);
RegisterBaseNutApi(_SC("BaseObject_IsContainsPoint"), BaseObject_IsContainsPoint, v);
RegisterBaseNutApi(_SC("BaseObject_ShowBorder"), BaseObject_ShowBorder, v);
RegisterBaseNutApi(_SC("BaseObject_SetRotate"), BaseObject_SetRotate, v);
}

View File

@ -13,7 +13,7 @@ static SQInteger Director_EnterStage(HSQUIRRELVM v)
SQUserPointer P;
sq_getuserpointer(v, 2, &P);
Director::GetInstance().EnterStage((Stage*)P);
Director::GetInstance().EnterStage((StageEx*)P);
return 0;
}

View File

@ -0,0 +1,53 @@
#pragma once
#include "squirrel.h"
#include "sqstdaux.h"
#include "sqstdblob.h"
#include "sqstdio.h"
#include "sqstdmath.h"
#include "sqstdstring.h"
#include "sqstdsystem.h"
#include <kiwano/kiwano.h>
using namespace kiwano;
static SQInteger Input_IsDown(HSQUIRRELVM v)
{
//»ñµÃ¼ü
SQInteger Key, Model;
sq_getinteger(v, 2, &Key);
//»ñȡģʽ
sq_getinteger(v, 3, &Model);
//»ñÈ¡ÊäÈë
Input& input = Input::GetInstance();
bool Flag = false;
switch (Model)
{
case 0:
Flag = input.IsDown(static_cast<MouseButton>(Key));
break;
case 1:
Flag = input.IsDown(static_cast<KeyCode>(Key));
break;
}
sq_pushbool(v, Flag);
return 1;
}
static void RegisterInputNutApi(const SQChar* funcName, void* funcAddr, HSQUIRRELVM v)
{
sq_pushroottable(v);
sq_pushstring(v, funcName, -1);
sq_newclosure(v, (SQFUNCTION)funcAddr, 0);
sq_newslot(v, -3, false);
sq_poptop(v);
}
static void RegisterInput(HSQUIRRELVM v) {
RegisterInputNutApi(_SC("Input_IsDown"), Input_IsDown, v);
}

View File

@ -1,24 +1,23 @@
#pragma once
#include "SquirrelClassEx.h"
#include "Npk.h"
#include "KiwanoEx/SpriteEx.hpp"
#include <kiwano/kiwano.h>
using namespace kiwano;
std::unordered_map<std::string, std::map<int, Texture*>>ImageRecObject;
std::unordered_map<std::string, std::map<int, TexturePtr>>ImageRecObject;
extern NPK_M* npk;
static SQInteger Sprite_Create(HSQUIRRELVM v)
{
Sprite* sprite = new Sprite;
SpriteExPtr sprite = new SpriteEx;
//如果用这个方式new 增加一次引用计数
sprite->Retain();
sq_pushuserpointer(v, sprite);
sq_pushuserpointer(v, sprite.Get());
return 1;
}
Texture* GetTexturePtrByImg(const std::string ImgPath, const int Frame) {
TexturePtr GetTexturePtrByImg(const std::string ImgPath, const int Frame) {
if (ImageRecObject.count(ImgPath) && ImageRecObject[ImgPath].count(Frame)) {
return ImageRecObject[ImgPath][Frame];
@ -30,7 +29,7 @@ Texture* GetTexturePtrByImg(const std::string ImgPath, const int Frame) {
BYTE* Data = img->lp_lplist[Frame].PNGdata;
BinaryData data = { ((void*)Data) ,Height * Width * 4 };
Texture* t = new Texture;
TexturePtr t = new Texture;
//如果用这个方式new 增加一次引用计数
t->Retain();
t->Load(PixelSize(Width, Height), data, PixelFormat::Bpp32BGRA);
@ -51,9 +50,9 @@ static SQInteger SpriteFrame_Create(HSQUIRRELVM v)
std::wstring wstr(ImgPath);
std::string str(wstr.begin(), wstr.end());
Texture* Sf = GetTexturePtrByImg(str, Idx);
TexturePtr Sf = GetTexturePtrByImg(str, Idx);
sq_pushuserpointer(v, Sf);
sq_pushuserpointer(v, Sf.Get());
return 1;
}
@ -64,13 +63,26 @@ static SQInteger Sprite_SetFrame(HSQUIRRELVM v)
SQUserPointer SF;
sq_getuserpointer(v, 3, &SF);
Sprite* X = (Sprite*)SP;
SpriteEx* X = (SpriteEx*)SP;
Texture* XSF = (Texture*)SF;
SpriteFrame A = SpriteFrame(XSF);
X->SetFrame(A);
return 0;
}
static SQInteger Sprite_SetMode(HSQUIRRELVM v)
{
SQUserPointer SP;
sq_getuserpointer(v, 2, &SP);
SQInteger Mode;
sq_getinteger(v, 3, &Mode);
SpriteEx* X = (SpriteEx*)SP;
X->SetMode(Mode);
return 0;
}
void RegisterSpriteNutApi(const SQChar* funcName, void* funcAddr, HSQUIRRELVM v)
{
@ -88,4 +100,6 @@ void RegisterSprite(HSQUIRRELVM v) {
RegisterSpriteNutApi(_SC("SpriteFrame_Create"), SpriteFrame_Create, v);
//设置精灵帧
RegisterSpriteNutApi(_SC("Sprite_SetFrame"), Sprite_SetFrame, v);
//ÉèÖûìºÏģʽ
RegisterSpriteNutApi(_SC("Sprite_SetMode"), Sprite_SetMode, v);
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "SquirrelClassEx.h"
#include "KiwanoEx/StageEx.hpp"
#include <kiwano/kiwano.h>
using namespace kiwano;
#include <kiwano-audio/kiwano-audio.h>
@ -7,23 +8,27 @@ using namespace kiwano::audio;
SQInteger Stage_Create(HSQUIRRELVM v)
{
Stage* stage = new Stage;
StageExPtr stage = new StageEx;
//如果用这个方式new 增加一次引用计数
stage->Retain();
sq_pushuserpointer(v, stage);
sq_pushuserpointer(v, stage.Get());
return 1;
}
SQInteger Stage_Output(HSQUIRRELVM v)
SQInteger Stage_BindenvUpdate(HSQUIRRELVM v)
{
SQUserPointer P;
sq_getuserpointer(v, 2, &P);
Stage* X = (Stage*)P;
std::cout << X->GetName() << std::endl;
StageEx* X = (StageEx*)P;
HSQOBJECT obj;
sq_getstackobj(v, 3, &obj);
sq_addref(v, &obj);
X->SetSqrobj(obj);
return 0;
}
@ -40,6 +45,6 @@ void RegisterStageNutApi(const SQChar* funcName, void* funcAddr, HSQUIRRELVM v)
void RegisterStage(HSQUIRRELVM v) {
//创建场景
RegisterStageNutApi(_SC("Stage_Create"), Stage_Create, v);
//´´½¨³¡¾°
RegisterStageNutApi(_SC("Stage_Output"), Stage_Output, v);
//°ó¶¨update
RegisterStageNutApi(_SC("Stage_BindenvUpdate"), Stage_BindenvUpdate, v);
}

95
include/Tool.hpp Normal file
View File

@ -0,0 +1,95 @@
#pragma once
#include <Windows.h>
#include <locale>
#include <codecvt>
#include "squirrel.h"
#include "sqstdaux.h"
#include "sqstdblob.h"
#include "sqstdio.h"
#include "sqstdmath.h"
#include "sqstdstring.h"
#include "sqstdsystem.h"
class TOOL
{
public:
TOOL() {};
~TOOL() {};
private:
public:
static char* U8ToU16(const char* szU8)
{
//预转换,得到所需空间的大小
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
//分配空间要给'\0'留个空间MultiByteToWideChar不会给'\0'空间
wchar_t* wszString = new wchar_t[wcsLen + 1];
//转换
::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
//最后加上'\0'
wszString[wcsLen] = '\0';
char* m_char;
int len = WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
m_char = new char[len + 1];
WideCharToMultiByte(CP_ACP, 0, wszString, wcslen(wszString), m_char, len, NULL, NULL);
delete[]wszString;
m_char[len] = '\0';
return m_char;
}
static std::string SquirrelU2W(const SQChar* Str)
{
char* wbuffer = (char*)(Str);
size_t len = 0;
while (wbuffer[len] != 0 || wbuffer[len - 1] != 0)
{
++len;
}
char* cbuffer = new char[len / 2 + 1];
int k = 0;
for (size_t i = 0; i < len; i += 2)
{
cbuffer[k] = wbuffer[i];
++k;
}
cbuffer[k] = '\0';
char* Text = U8ToU16(cbuffer);
delete[]cbuffer;
std::string RetStr(Text);
delete[]Text;
return RetStr;
}
static char* ConvertAnsiToUtf8(const char* szAnsi) {
// 第一步将ANSI字符串转换为宽字符字符串
int wcsLen = ::MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, NULL, 0);
wchar_t* wszString = new wchar_t[wcsLen];
::MultiByteToWideChar(CP_ACP, 0, szAnsi, -1, wszString, wcsLen);
// 第二步将宽字符字符串转换回UTF-8字符串
int utf8Len = ::WideCharToMultiByte(CP_UTF8, 0, wszString, wcsLen, NULL, 0, NULL, NULL);
char* szUtf8 = new char[utf8Len];
::WideCharToMultiByte(CP_UTF8, 0, wszString, wcsLen, szUtf8, utf8Len, NULL, NULL);
delete[] wszString; // 释放宽字符字符串的内存
szUtf8[utf8Len - 1] = '\0'; // 确保字符串以'\0'结尾
return szUtf8;
}
static std::wstring charTowchar_t(std::string Str)
{
char* Sn = ConvertAnsiToUtf8(Str.c_str());
std::string B(Sn);
std::wstring Ret(B.begin(), B.end());
delete[]Sn;
//std::wcout << Ret << std::endl;
return Ret;
}
};

178
include/WThreadPool.h Normal file
View File

@ -0,0 +1,178 @@
#pragma once
#include <functional>
#include <mutex>
#include <list>
#include <thread>
#include <memory>
#include <atomic>
#include <stdio.h>
#include <map>
#include <sstream>
#include <condition_variable>
#include <assert.h>
#define WThreadPool_log(fmt, ...) {printf(fmt, ##__VA_ARGS__);printf("\n");fflush(stdout);}
#define WPOOL_MIN_THREAD_NUM 4
#define WPOOL_MAX_THREAD_NUM 256
#define WPOOL_MANAGE_SECONDS 20
#define ADD_THREAD_BOUNDARY 1
using EventFun = std::function<void ()>;
using int64 = long long int;
template <typename T>
class LockQueue
{
public:
LockQueue()
{
QueueNode* node = new QueueNode();
node->next = nullptr;
// head->next is the first node, _tail point to last node, not _tail->next
_head = node;
_tail = _head;
};
virtual ~LockQueue()
{
clear();
delete _head;
_head = nullptr;
_tail = nullptr;
};
struct QueueNode
{
T value;
QueueNode* next;
};
bool enQueue(T data)
{
QueueNode* node = new (std::nothrow) QueueNode();
if (!node)
{
return false;
}
node->value = data;
node->next = nullptr;
std::unique_lock<std::mutex> locker(_mutex);
_tail->next = node;
_tail = node;
_queueSize++;
return true;
}
bool deQueue(T& data)
{
std::unique_lock<std::mutex> locker(_mutex);
QueueNode* currentFirstNode = _head->next;
if (!currentFirstNode)
{
return false;
}
_head->next = currentFirstNode->next;
data = currentFirstNode->value;
delete currentFirstNode;
_queueSize--;
if (_queueSize == 0)
{
_tail = _head;
}
return true;
}
int64_t size()
{
return _queueSize;
}
void clear()
{
T data;
while (deQueue(data));
}
bool empty()
{
return (_queueSize <= 0);
}
private:
QueueNode* _head;
QueueNode* _tail;
int64_t _queueSize = 0;
std::mutex _mutex;
};
class WThreadPool
{
public:
WThreadPool();
virtual ~WThreadPool();
static WThreadPool * globalInstance();
void setMaxThreadNum(int maxNum);
bool waitForDone(int waitMs = -1);
template<typename Func, typename ...Arguments >
void concurrentRun(Func func, Arguments... args) {
EventFun queunFun = std::bind(func, args...);
enQueueEvent(queunFun);
if (((int)_workThreadList.size() < _maxThreadNum) &&
(_eventQueue.size() >= ((int)_workThreadList.size() - _busyThreadNum - ADD_THREAD_BOUNDARY)))
{
_mgrCondVar.notify_one();
}
_workCondVar.notify_one();
}
template<typename T> static int64_t threadIdToint64(T threadId)
{
std::string stid;
stid.resize(32);
snprintf((char *)stid.c_str(), 32, "%lld", threadId);
long long int tid = std::stoll(stid);
return tid;
}
private:
int _minThreadNum = WPOOL_MIN_THREAD_NUM;
int _maxThreadNum = 8;
std::atomic<int> _busyThreadNum = {0};
int _stepThreadNum = 4;
volatile bool _exitAllFlag = false;
std::atomic<int> _reduceThreadNum = {0};
std::shared_ptr<std::thread> _mgrThread;
LockQueue<EventFun> _eventQueue;
std::list<std::shared_ptr<std::thread>> _workThreadList;
std::mutex _threadIsRunMutex;
std::map<std::thread::id, bool> _threadIsRunMap;
std::condition_variable _workCondVar;
std::mutex _workMutex;
std::condition_variable _mgrCondVar;
std::mutex _mgrMutex;
static std::shared_ptr<WThreadPool> s_threadPool;
static std::mutex s_globleMutex;
void enQueueEvent(EventFun fun);
EventFun deQueueEvent();
void run();
void managerThread();
void stop();
void startWorkThread();
void stopWorkThread();
void adjustWorkThread();
};

View File

@ -1,26 +1,31 @@
#include "SquirrelClassEx.h"
#include "GameState.h"
#include "Npk.h"
#include "Pvf.h"
#include "WThreadPool.h"
#include <kiwano/kiwano.h>
using namespace kiwano;
#include <kiwano-audio/kiwano-audio.h>
using namespace kiwano::audio;
#include "CursorEx.hpp"
using namespace kiwano::cursor;
extern SquirrelClassEx* TObject;
extern NPK_M* npk;
extern HSQUIRRELVM v;
WThreadPool threadPool;
//#include <irrKlang.h>
//KGE_DECLARE_SMART_PTR(ISound);
void Setup()
{
//线程池初始化
threadPool.setMaxThreadNum(2);
//打开输入法
WindowPtr window = Application::GetInstance().GetWindow();
@ -30,9 +35,6 @@ void Setup()
//打开渲染模式
Director::GetInstance().SetRenderBorderEnabled(true);
//irrklang::ISoundEngine* engine = irrklang::createIrrKlangDevice();
SQInteger top = sq_gettop(v); //saves the stack size before the call
sq_pushroottable(v); //pushes the global table
@ -43,11 +45,9 @@ void Setup()
}
sq_settop(v, top); //restores the original stack size
/*SoundPtr SP = new Sound();
SP*/
/*loader.Load(fileData.get(), "ogg", memory.buffer);*/
//鼠标指针 必须在这里处于最上级
Application::GetInstance().Use(CursorModule::GetInstance());
//Renderer::GetInstance().GetContext().SetTextAntialiasMode(TextAntialiasMode::None);
}

302
src/Pvf.cpp Normal file
View File

@ -0,0 +1,302 @@
#include "Pvf.h"
#include <iostream>
#include <fstream>
#include <Windows.h>
#include <vector>
#include <sstream>
#include <filesystem>
#include <mutex>
#include "Tool.hpp"
extern HSQUIRRELVM v;
extern std::mutex VmMtx;
#ifdef SQUNICODE
#define scfprintf fwprintf
#define scvprintf vfwprintf
#else
#define scfprintf fprintf
#define scvprintf vfprintf
#endif
class ReadPvf :public std::ifstream
{
const BYTE Key[256] = { 112,117,99,104,105,107,111,110,64,110,101,111,112,108,101,32,100,117,110,103,101,111,110,32,97,110,100,32,102,105,103,104,116,101,114,32,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,0 };
public:
//char* 转整数
int CharToInt(char* Str)
{
return *(int*)Str;
}
//char* 转Long
long CharToLong(char* Str)
{
return *(long long*)Str;
}
//读整数
int ReadInt()
{
int intValue;
std::ifstream::read(reinterpret_cast<char*>(&intValue), sizeof(int)); // 读取int类型数据
return intValue;
}
//读字符串
std::string ReadString()
{
char* buffer = new char[1025];
std::ifstream::read(buffer, 1024); // 读取指定长度的字节流
std::string Str(buffer);
delete[] buffer;
return Str;
}
//读字符串给定长度
std::string ReadString(int Size)
{
char* buffer = new char[Size + 1];
std::ifstream::read(buffer, Size); // 读取指定长度的字节流
std::string Str(buffer);
delete[] buffer;
return Str;
}
//读指定长度数据
char* ReadCustomSize(int Size)
{
char* Ret = new char[Size];
std::ifstream::read(Ret, Size);
return Ret;
}
};
class ReadPvfBuffer
{
const BYTE Key[256] = { 112,117,99,104,105,107,111,110,64,110,101,111,112,108,101,32,100,117,110,103,101,111,110,32,97,110,100,32,102,105,103,104,116,101,114,32,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,68,78,70,0 };
public:
char* BaseData;
char* NowData;
int idx = 0;
ReadPvfBuffer(char* GData) {
BaseData = GData;
NowData = GData;
}
//读整数
int ReadInt()
{
// 从ptr指向的地址开始读取4个字节并转换为int
// 假设系统使用的是小端字节序
int value = (static_cast<unsigned char>(NowData[0]) << 0) |
(static_cast<unsigned char>(NowData[1]) << 8) |
(static_cast<unsigned char>(NowData[2]) << 16) |
(static_cast<unsigned char>(NowData[3]) << 24);
NowData += 4;
return value;
}
//读指定长度数据
char* ReadCustomSize(int Size)
{
char* Ret = new char[Size];
memcpy(Ret, NowData, Size);
NowData += Size;
return Ret;
}
void seekg(const int l) {
NowData = BaseData + l;
}
};
int PVF_M::charPtrToInt(const char* ptr) {
// 确保ptr不是nullptr
if (ptr == nullptr) {
throw std::invalid_argument("ptr is nullptr");
}
// 从ptr指向的地址开始读取4个字节并转换为int
// 假设系统使用的是小端字节序
int value = (static_cast<unsigned char>(ptr[0]) << 0) |
(static_cast<unsigned char>(ptr[1]) << 8) |
(static_cast<unsigned char>(ptr[2]) << 16) |
(static_cast<unsigned char>(ptr[3]) << 24);
return value;
}
void PVF_M::intToCharPtr(int value, char* ptr) {
// 确保ptr不是nullptr
if (ptr == nullptr) {
throw std::invalid_argument("ptr is nullptr");
}
// 将int按小端字节序写入ptr数组
ptr[0] = static_cast<char>((value >> 0) & 0xFF);
ptr[1] = static_cast<char>((value >> 8) & 0xFF);
ptr[2] = static_cast<char>((value >> 16) & 0xFF);
ptr[3] = static_cast<char>((value >> 24) & 0xFF);
}
//Crc解密
void PVF_M::CrcDecode(PvfData& Data, const int crc32)
{
unsigned long num = 2175242257;
for (int i = 0; i < Data.Size; i += 4) {
unsigned int anInt = charPtrToInt(Data.Data + i);
std::cout << anInt << std::endl;
unsigned int val = (anInt ^ num ^ crc32);
unsigned int jiemi = (val >> 6) | ((val << (32 - 6)) & 0xFFFFFFFF);
intToCharPtr(jiemi, Data.Data + i);
}
}
void PVF_M::Init()
{
VmMtx.lock();
ReadPvf Fs;
Fs.open("Script.pvf", std::ios::in | std::ios::binary);
if (Fs) {
//读取UUID的长度
int UUID_LENGTH = Fs.ReadInt();
//UUID 读 1 - 36位 构造 UTF8 string
std::string UUID = Fs.ReadString(UUID_LENGTH);
//版本号
int Version = Fs.ReadInt();
// 文件路径数据的大小
int AlignedIndexHeaderSize = Fs.ReadInt();
// 解密密钥
int IndexHeaderCrc = Fs.ReadInt();
// 文件数量
int IndexSize = Fs.ReadInt();
// 文件数据
char* DataBuf = Fs.ReadCustomSize(AlignedIndexHeaderSize);
SQInteger topa = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC("CB_InitPvfTreeHeader"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2))) {
sq_pushroottable(v);
SQUserPointer Blobobj = sqstd_createblob(v, AlignedIndexHeaderSize);
memcpy(Blobobj, DataBuf, AlignedIndexHeaderSize);
delete[] DataBuf;
sq_pushinteger(v, IndexHeaderCrc);
sq_pushinteger(v, IndexSize);
sq_call(v, 4, SQFalse, SQTrue);
}
sq_settop(v, topa);
Fs.seekg(0, std::ios::end);
SQInteger FsSize = Fs.tellg();
Fs.seekg(0);
SQInteger top = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC("CB_InitPvfData"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2))) {
sq_pushroottable(v);
//SQUserPointer Blobobj = sqstd_createblob(v, FsSize);
//Fs.read((char*)Blobobj, FsSize);
//memcpy(Blobobj, DataBuf, FsSize);
sq_call(v, 1, SQFalse, SQTrue);
//sq_getstackobj(v, 4, &PVFDATAOBJ);
//sq_addref(v, &PVFDATAOBJ);
}
sq_settop(v, top);
Fs.close();
/*
PvfData Data;
Data.Data = DataBuf;
Data.Size = AlignedIndexHeaderSize;
//解密
CrcDecode(Data, IndexHeaderCrc);
int CurrPos = 0;
int StartPos = AlignedIndexHeaderSize + 56;
ReadPvfBuffer AW(Data.Data);
for (size_t i = 0; i < IndexSize; i++)
{
AW.seekg(CurrPos);
int FileNumber = AW.ReadInt();
int FilePathLength = AW.ReadInt();
char* FilePath = AW.ReadCustomSize(FilePathLength);
std::string RealPath(FilePath, FilePathLength);
delete[]FilePath;
int FileLength = AW.ReadInt();
int Cre32 = AW.ReadInt();
int RelativeOffset = AW.ReadInt();
if (FileLength > 0) {
int RealFileLength = (FileLength + 3) & 4294967292;
Fs.seekg(StartPos + RelativeOffset);
char* RealBuf = Fs.ReadCustomSize(RealFileLength);
PvfData DataBuf;
DataBuf.Data = RealBuf;
DataBuf.Size = RealFileLength;
CrcDecode(DataBuf, Cre32);
SQInteger top = sq_gettop(v);
sq_pushroottable(v);
sq_pushstring(v, _SC("CB_InitPvfTree"), -1);
if (SQ_SUCCEEDED(sq_get(v, -2))) {
sq_pushroottable(v);
const wchar_t* Str = TOOL::charTowchar_t(RealPath).c_str();
sq_pushstring(v, Str, -1);
SQUserPointer Blobobj = sqstd_createblob(v, RealFileLength);
memcpy(Blobobj, RealBuf, RealFileLength);
sq_call(v, 3, SQFalse, SQTrue);
}
sq_settop(v, top);
//这个需要销毁
delete[]RealBuf;
}
CurrPos += 20;
CurrPos += FilePathLength;
}
*/
//top = sq_gettop(v); //saves the stack size before the call
//sq_pushroottable(v);
//sq_pushstring(v, _SC("CB_InitDataSync"), -1);
//if (SQ_SUCCEEDED(sq_get(v, -2))) {
// sq_pushroottable(v);
// sq_pushobject(v, PVFDATAOBJ);
// sq_call(v, 2, SQFalse, SQTrue);
// //sq_release(v, &PVFDATAOBJ);
//}
//sq_settop(v, top); //restores the original stack size
}
else {
MessageBoxA(0, "读取不了PVF", 0, 0);
}
VmMtx.unlock();
}

View File

@ -2,6 +2,7 @@
#include "SquirrelClassEx.h"
#include <iostream>
#include <filesystem>
#include <mutex>
#ifdef SQUNICODE
#define scfprintf fwprintf
@ -21,27 +22,49 @@ using namespace kiwano::audio;
#include "SqrRegister/RegisterBase.hpp"
#include "SqrRegister/RegisterDirector.hpp"
#include "SqrRegister/RegisterSprite.hpp"
#include "SqrRegister/RegisterInput.hpp"
HSQUIRRELVM v;
std::mutex VmMtx;
//原生输出函数
void printfunc(HSQUIRRELVM v, const SQChar* s, ...)
{
va_list vl;
va_start(vl, s);
scvprintf(stdout, s, vl);
// 计算格式化后的字符串长度
int len = vswprintf(nullptr, 0, s, vl);
// 动态分配足够的内存空间
wchar_t* buffer = new wchar_t[len + 1];
// 将格式化后的字符串拼接到动态分配的内存中
vswprintf(buffer, len + 1, s, vl);
va_end(vl);
std::cout << std::endl;
std::cout << TOOL::SquirrelU2W(buffer) << std::endl;
// 释放动态分配的内存
delete[] buffer;
}
void errorfunc(HSQUIRRELVM v, const SQChar* s, ...)
{
va_list vl;
va_start(vl, s);
scvprintf(stderr, s, vl);
// 计算格式化后的字符串长度
int len = vswprintf(nullptr, 0, s, vl);
// 动态分配足够的内存空间
wchar_t* buffer = new wchar_t[len + 1];
// 将格式化后的字符串拼接到动态分配的内存中
vswprintf(buffer, len + 1, s, vl);
va_end(vl);
std::cout << std::endl;
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
// 将文字颜色设置为红色
SetConsoleTextAttribute(hConsole, FOREGROUND_RED);
std::cout << TOOL::SquirrelU2W(buffer) << std::endl;
// 将文字颜色重置为默认颜色
SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
// 释放动态分配的内存
delete[] buffer;
}
@ -51,7 +74,7 @@ void traverseDirectory(const std::filesystem::path& path , std::vector<std::wstr
traverseDirectory(entry.path(), PathV);
}
else {
if (entry.path().string().find("Main.nut") == std::string::npos) {
if (entry.path().string().find(".nut") != std::string::npos) {
PathV.push_back(entry.path().wstring());
}
}
@ -61,7 +84,7 @@ void traverseDirectory(const std::filesystem::path& path , std::vector<std::wstr
SQInteger SquirrelClassEx::ReloadingScript()
{
std::vector<std::wstring> PathV;
traverseDirectory("Script", PathV);
traverseDirectory("sqr", PathV);
while (PathV.size() != 0)
{
@ -105,12 +128,10 @@ void SquirrelClassEx::Init()
R_Register_Nut(v);
//输出版本信息
scfprintf(stdout, _SC("%s %s (%d bits)\n"), SQUIRREL_VERSION, SQUIRREL_COPYRIGHT, (int)sizeof(SQInteger) * 8);
scfprintf(stdout, _SC("%s %s %s (%d bits)\n"), _SC("Main Vm"), SQUIRREL_VERSION, SQUIRREL_COPYRIGHT, (int)sizeof(SQInteger) * 8);
//第一次加载脚本
ReloadingScript();
sqstd_dofile(v, _SC("Script/Main.nut"), false, true);
}
@ -133,6 +154,8 @@ void SquirrelClassEx::R_Register_Nut(HSQUIRRELVM v)
RegisterDirector(v);
//精灵及精灵帧类
RegisterSprite(v);
//输入类
RegisterInput(v);
RegisterNutApi(_SC("sq_ReloadingScript"), ReloadingScript, v);
RegisterNutApi(_SC("sq_Exit"), Exit, v);

267
src/WThreadPool.cpp Normal file
View File

@ -0,0 +1,267 @@
#include "WThreadPool.h"
using namespace std;
shared_ptr<WThreadPool> WThreadPool::s_threadPool;
std::mutex WThreadPool::s_globleMutex;
WThreadPool::WThreadPool()
{
_mgrThread = make_shared<thread>(&WThreadPool::managerThread, this);
}
WThreadPool::~WThreadPool()
{
stop();
}
WThreadPool *WThreadPool::globalInstance()
{
if (!s_threadPool.get())
{
unique_lock<mutex> locker(s_globleMutex);
if (!s_threadPool.get())
{
s_threadPool = make_shared<WThreadPool>();
}
}
return s_threadPool.get();
}
void WThreadPool::setMaxThreadNum(int maxNum)
{
if (maxNum > WPOOL_MAX_THREAD_NUM)
{
maxNum = WPOOL_MAX_THREAD_NUM;
}
else if (maxNum < WPOOL_MIN_THREAD_NUM)
{
maxNum = WPOOL_MIN_THREAD_NUM;
}
_maxThreadNum = maxNum;
}
bool WThreadPool::waitForDone(int waitMs)
{
int waitedMs = 0;
while(_busyThreadNum != 0 || !_eventQueue.empty())
{
this_thread::sleep_for(chrono::milliseconds(1));
waitedMs++;
if (waitMs > 0 && waitedMs >= waitMs)
{
return false;
}
}
return true;
}
void WThreadPool::enQueueEvent(EventFun fun)
{
bool res = _eventQueue.enQueue(fun);
assert(res);
}
EventFun WThreadPool::deQueueEvent()
{
EventFun fun;
if (_eventQueue.deQueue(fun))
{
return fun;
}
else
{
return nullptr;
}
return fun;
}
void WThreadPool::run()
{
{
unique_lock<mutex> locker(_threadIsRunMutex);
_threadIsRunMap[this_thread::get_id()] = true;
}
while (!_exitAllFlag)
{
{
unique_lock<mutex> locker(_workMutex);
if (_eventQueue.empty() && !_exitAllFlag)
{
_workCondVar.wait(locker);
}
if (_reduceThreadNum > 0)
{
_reduceThreadNum--;
break;
}
}
_busyThreadNum++;
while (!_exitAllFlag)
{
EventFun fun = deQueueEvent();
if (!fun)
{
break;
}
fun();
}
_busyThreadNum--;
}
{
unique_lock<mutex> locker(_threadIsRunMutex);
_threadIsRunMap[this_thread::get_id()] = false;
}
}
void WThreadPool::stop()
{
_exitAllFlag = true;
{
unique_lock<mutex> locker(_mgrMutex);
_mgrCondVar.notify_all();
}
if (_mgrThread->joinable())
{
_mgrThread->join();
}
}
void WThreadPool::managerThread()
{
startWorkThread();
while (!_exitAllFlag)
{
{
unique_lock<mutex> locker(_mgrMutex);
auto now = std::chrono::system_clock::now();
// if the number of threads reaches the maximum or the number of idle threads is enough to
// complete the task, sleep will be started
if (((int)_workThreadList.size() >= _maxThreadNum ||
_eventQueue.size() < ((int)_workThreadList.size() - _busyThreadNum - ADD_THREAD_BOUNDARY)) && !_exitAllFlag)
{
_mgrCondVar.wait_until(locker, now + chrono::seconds(WPOOL_MANAGE_SECONDS));
}
}
if (_exitAllFlag)
{
break;
}
adjustWorkThread();
// WThreadPool_log("get here to show work thread num:%d", _workThreadList.size());
}
stopWorkThread();
}
void WThreadPool::startWorkThread()
{
for (int i = 0; i < _minThreadNum; i++)
{
shared_ptr<thread> threadPtr = make_shared<thread>(&WThreadPool::run, this);
_workThreadList.emplace_back(threadPtr);
}
}
void WThreadPool::stopWorkThread()
{
{
unique_lock<mutex> locker(_mgrMutex);
_workCondVar.notify_all();
}
for (auto it = _workThreadList.begin(); it != _workThreadList.end(); it++)
{
if ((*it)->joinable())
{
(*it)->join();
}
}
_workThreadList.clear();
_threadIsRunMap.clear();
_eventQueue.clear();
}
void WThreadPool::adjustWorkThread()
{
int queueSize = _eventQueue.size();
int busyThreadNum = _busyThreadNum;
int liveThreadNum = _workThreadList.size();
int maxThreadNum = _maxThreadNum;
int stepThreadNum = _stepThreadNum;
int minThreadNum = _minThreadNum;
// if rest thread can not run all task concurrently, add the thread
if ((liveThreadNum < maxThreadNum) && (queueSize >= (liveThreadNum - busyThreadNum - ADD_THREAD_BOUNDARY)))
{
int restAllAddNum = maxThreadNum - liveThreadNum;
int addThreadNum = restAllAddNum > stepThreadNum ? stepThreadNum : restAllAddNum;
for (int i = 0; i < addThreadNum; i++)
{
shared_ptr<thread> threadPtr = make_shared<thread>(&WThreadPool::run, this);
_workThreadList.emplace_back(threadPtr);
}
}
else if ((liveThreadNum > minThreadNum) && (busyThreadNum*2 < liveThreadNum))
{
int resAllReduceNum = liveThreadNum - minThreadNum;
int reduceThreadNum = resAllReduceNum > stepThreadNum ? stepThreadNum : resAllReduceNum;
_reduceThreadNum = reduceThreadNum;
int findExitThreadNum = 0;
do
{
if (_exitAllFlag)
{
return;
}
for (int i = 0; i < (reduceThreadNum - findExitThreadNum); i++)
{
_workCondVar.notify_one();
}
this_thread::sleep_for(chrono::milliseconds(1));
{
unique_lock<mutex> locker(_threadIsRunMutex);
for (auto it = _workThreadList.begin(); it != _workThreadList.end();)
{
std::thread::id threadId = (*it)->get_id();
auto threadIdIt = _threadIsRunMap.find(threadId);
if ((threadIdIt != _threadIsRunMap.end()) && (_threadIsRunMap[threadId] == false))
{
findExitThreadNum++;
_threadIsRunMap.erase(threadIdIt);
(*it)->join();
_workThreadList.erase(it++);
}
else
{
it++;
}
}
}
if (findExitThreadNum < reduceThreadNum)
{
this_thread::sleep_for(chrono::milliseconds(1));
}
/*
WThreadPool_log("get here 3 to show findExitThreadNum:%d, reduceThreadNum:%d, _reduceThreadNum:%d", findExitThreadNum, reduceThreadNum, (int)_reduceThreadNum);
for (auto it = _workThreadList.begin(); it != _workThreadList.end(); it++)
{
WThreadPool_log("work thread pid:%lld", (*it)->get_id());
}
for (auto it = _threadIsRunMap.begin(); it != _threadIsRunMap.end(); it++)
{
WThreadPool_log("it->first:%lld, it->second:%d", it->first, it->second);
}
*/
} while(!(findExitThreadNum >= reduceThreadNum && _reduceThreadNum <= 0));
}
}

View File

@ -16,9 +16,9 @@
SquirrelClassEx* TObject;
NPK_M* npk;
int main(int argc, char** argv)
{
//³õʼ»¯Í¼Ïñ×ÊÔ´
npk = new NPK_M();
npk->init();