279 lines
7.3 KiB
C++
279 lines
7.3 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#include "project/project.h"
|
|
#include "scene3d/scene.h"
|
|
#include "ui/ui.h"
|
|
#include "script/script_engine_types.h"
|
|
#include "script/script_variant.h"
|
|
#include "metafile/nml_object.h"
|
|
#include "platform.h"
|
|
|
|
using namespace GS::Core;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool Project::IsProjectActionAllowed(const char *f)
|
|
{
|
|
if (prohibit_project_action)
|
|
__ERR__(__LOG_E__ << "Cannot call '" << f << "' while rendering or evaluating the project scene stack.\n", false)
|
|
return true;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Project::ResetStatistics()
|
|
{
|
|
ListForeachPtr(ProjectSceneInstance *, i, instance_list)
|
|
switch (i->type)
|
|
{
|
|
case ProjectSceneInstance::Type_Scene2d:
|
|
break;
|
|
|
|
case ProjectSceneInstance::Type_Scene3d:
|
|
i->instance_3d->profiler.ResetProfiles();
|
|
break;
|
|
}
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
uint Project::GetActiveCount() const
|
|
{
|
|
uint count = 0;
|
|
ListForeachPtr(ProjectSceneInstance *, i, instance_list)
|
|
if (i->active)
|
|
++count;
|
|
return count;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
ProjectSceneInstance *Project::FindSceneInstance(const char *name) const
|
|
{
|
|
ListForeachPtr(ProjectSceneInstance *, s, instance_list)
|
|
switch (s->GetType())
|
|
{
|
|
case ProjectSceneInstance::Type_Scene3d:
|
|
if (s->instance_3d->name == name)
|
|
return s;
|
|
break;
|
|
|
|
case ProjectSceneInstance::Type_Scene2d:
|
|
if (s->instance_2d->name == name)
|
|
return s;
|
|
break;
|
|
}
|
|
return NULL;
|
|
}
|
|
ProjectSceneInstance *Project::FindSceneInstance(const GS::S3D::Scene *scene) const
|
|
{
|
|
ListForeachPtr(ProjectSceneInstance *, s, instance_list)
|
|
if (s->instance_3d == scene)
|
|
return s;
|
|
return NULL;
|
|
}
|
|
ProjectSceneInstance *Project::FindSceneInstance(const GS::S2D::Scene *scene) const
|
|
{
|
|
ListForeachPtr(ProjectSceneInstance *, s, instance_list)
|
|
if (s->instance_2d == scene)
|
|
return s;
|
|
return NULL;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
void Project::New()
|
|
{
|
|
Close();
|
|
|
|
name = "New Project";
|
|
|
|
root_script_list.Clear();
|
|
search_path.Clear();
|
|
}
|
|
bool Project::Open(bool project_exec_mode)
|
|
{
|
|
__PROJECT_ACTION_SAFETY_CHECK(false)
|
|
|
|
vm->Set("g_platform", Platform::Get().GetName().c_str());
|
|
vm->Set("g_context_project", project_exec_mode);
|
|
|
|
if (!CompileRootScripts())
|
|
return false;
|
|
if (!script_unit->Open())
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
bool Project::Setup()
|
|
{
|
|
__PROJECT_ACTION_SAFETY_CHECK(false)
|
|
|
|
// Script callback.
|
|
if (script_unit->SetupFunctionCall("OnSetup", script_unit->setup_callback))
|
|
script_unit->DoFunctionCall();
|
|
|
|
return true;
|
|
}
|
|
void Project::Close()
|
|
{
|
|
__PROJECT_ACTION_SAFETY_CHECK_RAW
|
|
|
|
// OnClose callback.
|
|
if (script_unit->SetupFunctionCall("OnClose"))
|
|
script_unit->DoFunctionCall(0);
|
|
|
|
// Drop content.
|
|
file_path.Clear();
|
|
|
|
// Drop all layer/instance/scene.
|
|
layer_list.Clear();
|
|
instance_list.Clear();
|
|
|
|
flags = 0;
|
|
|
|
script_unit->Close();
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
ProjectLayer *Project::AddLayer(ProjectSceneInstance *scene, float zorder)
|
|
{
|
|
ProjectLayer *layer = new ProjectLayer(scene, zorder);
|
|
if (!layer)
|
|
__ERR__(__LOG_E__ << "Failed to allocate a new project scene layer.\n", NULL)
|
|
layer_list.Add(layer);
|
|
return layer;
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
ProjectSceneInstance *Project::Instantiate(GS::S3D::Scene *scene)
|
|
{
|
|
ProjectSceneInstance *inst = new ProjectSceneInstance(scene);
|
|
if (inst)
|
|
instance_list.Add(inst);
|
|
return inst;
|
|
}
|
|
ProjectSceneInstance *Project::Instantiate(GS::S2D::Scene *scene)
|
|
{
|
|
ProjectSceneInstance *inst = new ProjectSceneInstance(scene);
|
|
if (inst)
|
|
instance_list.Add(inst);
|
|
return inst;
|
|
}
|
|
ProjectSceneInstance *Project::Instantiate(const char *name)
|
|
{
|
|
__PROJECT_ACTION_SAFETY_CHECK(NULL)
|
|
|
|
// Scene is already instantiated.
|
|
ProjectSceneInstance *inst = FindSceneInstance(name);
|
|
if (inst)
|
|
return inst;
|
|
|
|
// Create new instance.
|
|
NML::File file;
|
|
if (!NML::Parser::Load(name, file))
|
|
__ERR__(__LOG_E__ << "Could not instantiate scene '" << name << "', file not found.\n", NULL)
|
|
|
|
// Scene 3d
|
|
if (file.GetTag("Scene;"))
|
|
{
|
|
S3D::Scene *scene = new S3D::Scene(vm);
|
|
if (!scene)
|
|
__ERR__(__LOG_E__ << " Failed to allocate scene object.\n", NULL)
|
|
scene->SetClock(clock);
|
|
|
|
if ((inst = new ProjectSceneInstance(scene)) == NULL)
|
|
{
|
|
_safe_delete(scene);
|
|
__ERR__(__LOG_E__ << " Failed to allocate project scene instance.\n", NULL)
|
|
}
|
|
|
|
scene->Create(iproject_factory->NewPhysicWorld());
|
|
NML::LoadFromFile(*scene, file);
|
|
scene->name = name;
|
|
scene->InstanceSetup();
|
|
scene->RenderSetup(factories);
|
|
scene->SetAsScriptGlobalScene();
|
|
scene->Setup(NoTool);
|
|
scene->Reset();
|
|
}
|
|
else if (file.GetTag("UIScene;"))
|
|
{
|
|
S2D::Scene *scene = new S2D::Scene(vm);
|
|
if (!scene)
|
|
__ERR__(__LOG_E__ << " Failed to allocate scene 2D object.\n", NULL)
|
|
scene->SetClock(clock);
|
|
|
|
if ((inst = new ProjectSceneInstance(scene)) == NULL)
|
|
{
|
|
_safe_delete(scene);
|
|
__ERR__(__LOG_E__ << " Failed to allocate project scene instance.\n", NULL)
|
|
}
|
|
|
|
NML::LoadFromFile(*scene, file);
|
|
scene->name = name;
|
|
scene->RenderSetup(factories);
|
|
scene->SetAsScriptGlobalScene();
|
|
scene->Setup();
|
|
scene->Reset();
|
|
}
|
|
|
|
if (inst)
|
|
instance_list.Append(inst);
|
|
return inst;
|
|
}
|
|
void Project::Delete(ProjectSceneInstance *inst)
|
|
{
|
|
__PROJECT_ACTION_SAFETY_CHECK_RAW
|
|
if (!inst)
|
|
return;
|
|
|
|
// Callback.
|
|
if (script_unit->SetupFunctionCall("OnUnloadScene"))
|
|
{
|
|
script_unit->PushFunctionCallArgument(Script::Variant((void *)inst, Script::typetag_ProjectScene));
|
|
script_unit->DoFunctionCall(0);
|
|
}
|
|
|
|
// Drop scene from all layers using it.
|
|
ListForeachPtr(ProjectLayer *, layer, layer_list)
|
|
if (layer->inst == inst)
|
|
layer_list.Remove(layer);
|
|
|
|
instance_list.Remove(inst);
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
Project::Project(ResourceFactories *f, GS::IFontFactory *ff, GS::Script::IVM *_vm) : vm(_vm)
|
|
{
|
|
factories = f;
|
|
|
|
name = "New Project";
|
|
|
|
authors = "Authors";
|
|
description = "New project";
|
|
company = "Empty Notice";
|
|
|
|
clock = new Clock;
|
|
|
|
font_cache = new FontCache(ff);
|
|
font_cache->LoadFont("@core/default.ttf");
|
|
|
|
script_unit = new ProjectScriptUnit(vm);
|
|
script_unit->SetInterfaceObject(this, Script::typetag_Project);
|
|
|
|
prohibit_project_action = false;
|
|
}
|
|
Project::~Project()
|
|
{
|
|
Close();
|
|
}
|
|
//------------------------------------------------------------------------------
|