11213213
This commit is contained in:
parent
808e4015d3
commit
2fd727b47a
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -16,9 +16,9 @@
|
|||
SquirrelClassEx* TObject;
|
||||
NPK_M* npk;
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
|
||||
//³õʼ»¯Í¼Ïñ×ÊÔ´
|
||||
npk = new NPK_M();
|
||||
npk->init();
|
||||
|
|
|
|||
Loading…
Reference in New Issue