/* ----------------------------------------------------------------------------- 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(); } //------------------------------------------------------------------------------