axmol/extensions/Live2D/Framework/src/CubismFramework.cpp

385 lines
9.9 KiB
C++

/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Open Software license
* that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
*/
#include "CubismFramework.hpp"
#include "Utils/CubismDebug.hpp"
#include "Utils/CubismJson.hpp"
#include "Id/CubismIdManager.hpp"
#include "Rendering/CubismRenderer.hpp"
#ifdef CSM_DEBUG_MEMORY_LEAKING
#include <vector>
#endif
//--------- LIVE2D NAMESPACE ------------
namespace Live2D { namespace Cubism { namespace Framework {
// Framework内で使う定数の宣言
namespace Constant {
const csmInt32 VertexOffset = 0;
const csmInt32 VertexStep = 2;
}
// ファイルスコープの変数を初期化
namespace {
csmBool s_isStarted = false;
csmBool s_isInitialized = false;
ICubismAllocator* s_allocator = NULL;
const CubismFramework::Option* s_option = NULL;
CubismIdManager* s_cubismIdManager = NULL;
}
inline ICubismAllocator* GetAllocator()
{
return s_allocator;
}
#ifdef CSM_DEBUG_MEMORY_LEAKING
namespace {
std::vector<void*>* s_allocationList = NULL;
}
#endif
csmBool CubismFramework::StartUp(ICubismAllocator* allocator, const Option* option)
{
if(s_isStarted)
{
CubismLogInfo("CubismFramework::StartUp() is already done.");
return s_isStarted;
}
s_option = option;
if (s_option != NULL)
{
Core::csmSetLogFunction(s_option->LogFunction);
}
if (allocator == NULL)
{
CubismLogWarning("CubismFramework::StartUp() failed, need allocator instance.");
s_isStarted = false;
}
else
{
s_allocator = allocator;
s_isStarted = true;
}
// Live2D Cubism Coreバージョン情報を表示
if(s_isStarted)
{
const Core::csmVersion version = Core::csmGetVersion();
const csmUint32 major = static_cast<csmUint32>((version & 0xFF000000) >> 24);
const csmUint32 minor = static_cast<csmUint32>((version & 0x00FF0000) >> 16);
const csmUint32 patch = static_cast<csmUint32>((version & 0x0000FFFF));
const csmUint32 vesionNumber = version;
CubismLogInfo("Live2D Cubism Core version: %02d.%02d.%04d (%d)", major, minor, patch, vesionNumber);
}
CubismLogInfo("CubismFramework::StartUp() is complete.");
return s_isStarted;
}
void CubismFramework::CleanUp()
{
s_isStarted = false;
s_isInitialized = false;
s_allocator = NULL;
s_option = NULL;
s_cubismIdManager = NULL;
#ifdef CSM_DEBUG_MEMORY_LEAKING
s_allocationList = NULL;
#endif
}
csmBool CubismFramework::IsStarted()
{
return s_isStarted;
}
void CubismFramework::Initialize()
{
CSM_ASSERT(s_isStarted);
if(!s_isStarted)
{
CubismLogWarning("CubismFramework is not started.");
return;
}
// --- s_isInitializedによる連続初期化ガード ---
// 連続してリソース確保が行われないようにする。
// 再度Initialize()するには先にDispose()を実行する必要がある。
if (s_isInitialized)
{
CubismLogWarning("CubismFramework::Initialize() skipped, already initialized.");
return;
}
#ifdef CSM_DEBUG_MEMORY_LEAKING
s_allocationList = CSM_NEW std::vector<void*>();
#endif
//---- static 初期化 ----
Utils::Value::StaticInitializeNotForClientCall();
s_cubismIdManager = CSM_NEW CubismIdManager();
s_isInitialized = true;
CubismLogInfo("CubismFramework::Initialize() is complete.");
}
void CubismFramework::Dispose()
{
CSM_ASSERT(s_isStarted);
if (!s_isStarted)
{
CubismLogWarning("CubismFramework is not started.");
return;
}
// --- s_isInitializedによる未初期化解放ガード ---
// Dispose()するには先にInitialize()を実行する必要がある。
if (!s_isInitialized) // false...リソース未確保の場合
{
CubismLogWarning("CubismFramework::Dispose() skipped, not initialized.");
return;
}
//---- static 解放 ----
Utils::Value::StaticReleaseNotForClientCall();
CSM_DELETE(s_cubismIdManager);
//レンダラの静的リソース(シェーダプログラム他)を解放する
Rendering::CubismRenderer::StaticRelease();
#ifdef CSM_DEBUG_MEMORY_LEAKING
for (csmUint32 i = 0; i < s_allocationList->size(); ++i)
{
CubismLogInfo("Memory leaking: 0x%p", s_allocationList->at(i));
}
if (s_allocationList->size() == 0)
{
CubismLogInfo("No memory leaking");
}
CSM_DELETE(s_allocationList);
#endif
s_isInitialized = false;
CubismLogInfo("CubismFramework::Dispose() is complete.");
}
csmBool CubismFramework::IsInitialized()
{
return s_isInitialized;
}
void CubismFramework::CoreLogFunction(const csmChar* message)
{
// Return if logging not possible.
if (!Core::csmGetLogFunction())
{
return;
}
Core::csmGetLogFunction()(message);
}
CubismFramework::Option::LogLevel CubismFramework::GetLoggingLevel()
{
if (s_option != NULL)
{
return s_option->LoggingLevel;
}
return Option::LogLevel_Off;
}
CubismIdManager* CubismFramework::GetIdManager()
{
return s_cubismIdManager;
}
#ifdef CSM_DEBUG_MEMORY_LEAKING
void* CubismFramework::Allocate(csmSizeType size, const csmChar* fileName, csmInt32 lineNumber)
{
void* address = GetAllocator()->Allocate(size);
CubismLogVerbose("CubismFramework::Allocate(0x%p, %dbytes) %s(%d)", address, size, fileName, lineNumber);
if (s_allocationList)
{
s_allocationList->push_back(address);
}
return address;
}
void* CubismFramework::AllocateAligned(csmSizeType size, csmUint32 alignment, const csmChar* fileName, csmInt32 lineNumber)
{
void* address = GetAllocator()->AllocateAligned(size, alignment);
CubismLogVerbose("CubismFramework::AllocateAligned(0x%p, a:%d, %dbytes) %s(%d)", address, alignment, size, fileName, lineNumber);
if (s_allocationList)
{
s_allocationList->push_back(address);
}
return address;
}
void CubismFramework::Deallocate(void* address, const csmChar* fileName, csmInt32 lineNumber)
{
if (!address)
{
return;
}
CubismLogVerbose("CubismFramework::Deallocate(0x%p) %s(%d)", address, fileName, lineNumber);
if (s_allocationList)
{
for (std::vector<void*>::iterator iter = s_allocationList->begin(); iter != s_allocationList->end(); ++iter)
{
if (*iter != address)
{
continue;
}
s_allocationList->erase(iter);
break;
}
}
GetAllocator()->Deallocate(address);
}
void CubismFramework::DeallocateAligned(void* address, const csmChar* fileName, csmInt32 lineNumber)
{
if (!address)
{
return;
}
CubismLogVerbose("CubismFramework::DeallocateAligned(0x%p) %s(%d)", address, fileName, lineNumber);
if (s_allocationList)
{
for (std::vector<void*>::iterator iter = s_allocationList->begin(); iter != s_allocationList->end(); ++iter)
{
if (*iter != address)
{
continue;
}
s_allocationList->erase(iter);
break;
}
}
GetAllocator()->DeallocateAligned(address);
}
#else
void* CubismFramework::Allocate(csmSizeType size)
{
return GetAllocator()->Allocate(size);
}
void* CubismFramework::AllocateAligned(csmSizeType size, csmUint32 alignment)
{
return GetAllocator()->AllocateAligned(size, alignment);
}
void CubismFramework::Deallocate(void* address)
{
if (!address)
{
return;
}
GetAllocator()->Deallocate(address);
}
void CubismFramework::DeallocateAligned(void* address)
{
if (!address)
{
return;
}
GetAllocator()->DeallocateAligned(address);
}
#endif
}}}
//--------- LIVE2D NAMESPACE ------------
#ifdef CSM_DEBUG_MEMORY_LEAKING
void* operator new(Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::CubismAllocationTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber)
{
return Live2D::Cubism::Framework::CubismFramework::Allocate(size, fileName, lineNumber);
}
void* operator new (Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::csmUint32 alignment, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber)
{
return Live2D::Cubism::Framework::CubismFramework::AllocateAligned(size, alignment, fileName, lineNumber);
}
void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber)
{
Live2D::Cubism::Framework::CubismFramework::Deallocate(address, fileName, lineNumber);
}
void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber)
{
Live2D::Cubism::Framework::CubismFramework::DeallocateAligned(address, fileName, lineNumber);
}
#else
void* operator new(Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::CubismAllocationTag tag)
{
return Live2D::Cubism::Framework::CubismFramework::Allocate(size);
}
void* operator new (Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::csmUint32 alignment, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag)
{
return Live2D::Cubism::Framework::CubismFramework::AllocateAligned(size, alignment);
}
void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationTag tag)
{
Live2D::Cubism::Framework::CubismFramework::Deallocate(address);
}
void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag)
{
Live2D::Cubism::Framework::CubismFramework::DeallocateAligned(address);
}
#endif