JavaScript binding for new mesh APIs
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / dali-wrapper.cpp
index 5bce721..cc905a3 100644 (file)
 #include <dali/integration-api/debug.h>
 #include <actors/actor-wrapper.h>
 #include <stage/stage-wrapper.h>
-#include <image/image-attributes-wrapper.h>
 #include <image/image-wrapper.h>
-#include <text/font-wrapper.h>
+#include <animation/linear-constrainer-wrapper.h>
+#include <animation/path-constrainer-wrapper.h>
 #include <animation/path-wrapper.h>
-#include <animation/path-constraint-wrapper.h>
 #include <animation/animation-wrapper.h>
 #include <events/pan-gesture-detector-wrapper.h>
 #include <shader-effects/shader-effect-wrapper.h>
+#include <object/property-buffer-wrapper.h>
+#include <rendering/geometry-wrapper.h>
+#include <rendering/material-wrapper.h>
+#include <rendering/renderer-wrapper.h>
+#include <rendering/shader-wrapper.h>
+#include <rendering/sampler-wrapper.h>
 #include <shared/object-template-helper.h>
 #include <constants/constants-wrapper.h>
 #include <toolkit/builder/builder-wrapper.h>
@@ -60,23 +65,26 @@ const ApiFunction ConstructorFunctionTable[]=
 {
     { "Rotation",           PropertyValueWrapper::NewRotation},
     { "Matrix",             PropertyValueWrapper::NewMatrix},
-    { "Font",               FontWrapper::NewFont },
     { "Path",               PathWrapper::NewPath },
-    { "PathConstraint",     PathConstraintWrapper::NewPathConstraint },
+    { "PathConstrainer",    PathConstrainerWrapper::NewPathConstrainer},
+    { "LinearConstrainer",  LinearConstrainerWrapper::NewLinearConstrainer},
     { "Actor",              ActorWrapper::NewActor },
-    { "TextActor",          ActorWrapper::NewActor },
     { "ImageActor",         ActorWrapper::NewActor },
-    { "MeshActor",          ActorWrapper::NewActor },
     { "CameraActor",        ActorWrapper::NewActor },
     { "Layer",              ActorWrapper::NewActor },
-    { "TextView",           ActorWrapper::NewActor },
+    { "Control",            ActorWrapper::NewControl },
     { "ResourceImage",      ImageWrapper::NewImage },
     { "BufferImage",        ImageWrapper::NewImage },
     { "NinePatchImage",     ImageWrapper::NewImage },
     { "FrameBufferImage",   ImageWrapper::NewImage },
-    { "ImageAttributes",    ImageAttributesWrapper::NewImageAttributes },
     { "Animation",          AnimationWrapper::NewAnimation},
     { "ShaderEffect",       ShaderEffectWrapper::NewShaderEffect},
+    { "Shader",             ShaderWrapper::NewShader},
+    { "Sampler",            SamplerWrapper::NewSampler},
+    { "Material",           MaterialWrapper::NewMaterial},
+    { "Geometry",           GeometryWrapper::NewGeometry},
+    { "Renderer",           RendererWrapper::NewRenderer},
+    { "PropertyBuffer",     PropertyBufferWrapper::NewPropertyBuffer},
     { "Builder",            BuilderWrapper::NewBuilder},
     { "PanGestureDetector", PanGestureDetectorWrapper::NewPanGestureDetector},
 
@@ -101,8 +109,9 @@ Integration::Log::Filter* gLogExecuteFilter( Integration::Log::Filter::New(Debug
 bool DaliWrapper::mInstanceCreated = false;
 DaliWrapper* DaliWrapper::mWrapper = NULL;
 
-DaliWrapper::DaliWrapper()
-:mIsolate( NULL )
+DaliWrapper::DaliWrapper( RunMode runMode, v8::Isolate* isolate )
+:mIsolate( isolate ),
+ mRunMode(runMode)
 {
 }
 
@@ -113,20 +122,60 @@ DaliWrapper::~DaliWrapper()
 
 DaliWrapper& DaliWrapper::Get()
 {
-  if(!mInstanceCreated)
+  if( !mInstanceCreated )
   {
-    mWrapper = new DaliWrapper();
+    mWrapper = new DaliWrapper( RUNNING_STANDALONE, NULL );
+
     mInstanceCreated = true;
 
-    if(mWrapper)
-    {
-      mWrapper->Initialize();
-    }
-  }
+    mWrapper->InitializeStandAlone();
 
+  }
   return *mWrapper;
 }
 
+v8::Local<v8::Object> DaliWrapper::CreateWrapperForNodeJS( v8::Isolate* isolate )
+{
+  v8::EscapableHandleScope handleScope( isolate);
+
+  mInstanceCreated = true;
+
+  mWrapper = new DaliWrapper( RUNNING_IN_NODE_JS, isolate );
+
+  v8::Local<v8::Object> dali = mWrapper->CreateDaliObject();
+
+  // As we running inside node, we already have an isolate and context
+  return handleScope.Escape( dali );
+}
+
+v8::Local<v8::Object>  DaliWrapper::CreateDaliObject()
+{
+  v8::EscapableHandleScope handleScope( mIsolate  );
+
+  // Create dali object used for creating objects, and accessing constant values
+  // e.g. var x =  new dali.Actor(), or var col = dali.COLOR_RED;
+
+  v8::Local<v8::ObjectTemplate> daliObjectTemplate = NewDaliObjectTemplate( mIsolate );
+
+  // add dali.staqe
+  v8::Local<v8::Object> stageObject = StageWrapper::WrapStage( mIsolate, Stage::GetCurrent() );
+  daliObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "stage") , stageObject );
+
+  v8::Local<v8::Object> keyboardObject = KeyboardFocusManagerWrapper::WrapKeyboardFocusManager( mIsolate,Toolkit::KeyboardFocusManager::Get() );
+  daliObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "keyboardFocusManager") , keyboardObject );
+
+
+  //create an instance of the template
+  v8::Local<v8::Object> daliObject = daliObjectTemplate->NewInstance();
+
+  ConstantsWrapper::AddDaliConstants( mIsolate, daliObject);
+
+  daliObject->Set( v8::String::NewFromUtf8( mIsolate,  "V8_VERSION") ,v8::String::NewFromUtf8( mIsolate, v8::V8::GetVersion() ));
+
+  return handleScope.Escape( daliObject  );
+}
+
+
 void DaliWrapper::SetFlagsFromString(const std::string &flags)
 {
   v8::V8::SetFlagsFromString(flags.c_str(), flags.size());
@@ -134,6 +183,12 @@ void DaliWrapper::SetFlagsFromString(const std::string &flags)
 
 void DaliWrapper::Shutdown()
 {
+  // if we're running inside node then we don't have ownership of the context
+  if( mRunMode == RUNNING_IN_NODE_JS )
+  {
+    return;
+  }
+
   DALI_LOG_WARNING("Destroying V8 DALi context\n");
 
   if( !mContext.IsEmpty())
@@ -145,16 +200,16 @@ void DaliWrapper::Shutdown()
   }
 }
 
-void DaliWrapper::ExecuteBuffer(const std::string &sourceCode, const std::string &sourceFileName)
+bool DaliWrapper::ExecuteBuffer(const std::string &sourceCode, const std::string &sourceFileName)
 {
-  mModuleLoader.ExecuteScript( mIsolate,  sourceCode, sourceFileName );
+  return mModuleLoader.ExecuteScript( mIsolate,  sourceCode, sourceFileName );
 }
 
-void DaliWrapper::ExecuteFile( const std::string& sourceFileName )
+bool DaliWrapper::ExecuteFile( const std::string& sourceFileName )
 {
   DALI_LOG_INFO( gLogExecuteFilter, Debug::Verbose, "Executing source file %s \n",sourceFileName.c_str() );
 
-  mModuleLoader.ExecuteScriptFromFile( mIsolate,  sourceFileName );
+  return mModuleLoader.ExecuteScriptFromFile( mIsolate,  sourceFileName );
 }
 
 GarbageCollectorInterface& DaliWrapper::GetDaliGarbageCollector()
@@ -162,35 +217,33 @@ GarbageCollectorInterface& DaliWrapper::GetDaliGarbageCollector()
   return mGarbageCollector;
 }
 
-void DaliWrapper::CreateContext( )
+void DaliWrapper::ApplyGlobalObjectsToContext( v8::Local<v8::Context> context )
 {
   v8::HandleScope handleScope( mIsolate );
 
-  // Create a  global JavaScript object so we can set built-in global functions, like Log.
-  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New( mIsolate );
+  // Add global objects ( functions/ values ) e.g. log function
+  // create a console.log and console.error functions
+  v8::Local<v8::ObjectTemplate> consoleObjectTemplate = v8::ObjectTemplate::New( mIsolate );
+  consoleObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "log"),   v8::FunctionTemplate::New( mIsolate, V8Utils::Log));
+  consoleObjectTemplate->Set( v8::String::NewFromUtf8( mIsolate, "error"), v8::FunctionTemplate::New( mIsolate, V8Utils::LogError));
 
-  // Add global objects ( functions/ values ) e.g. log function and V8_VERSION
-  global->Set( v8::String::NewFromUtf8( mIsolate,  "log"),        v8::FunctionTemplate::New( mIsolate, V8Utils::Log) );
-  global->Set( v8::String::NewFromUtf8( mIsolate,  "logError"),   v8::FunctionTemplate::New( mIsolate, V8Utils::LogError) );
-  global->Set( v8::String::NewFromUtf8( mIsolate,  "require"),    v8::FunctionTemplate::New( mIsolate, DaliWrapper::Require));
-  global->Set( v8::String::NewFromUtf8( mIsolate,  "V8_VERSION") ,v8::String::NewFromUtf8( mIsolate, v8::V8::GetVersion() ));
+  context->Global()->Set( v8::String::NewFromUtf8( mIsolate, "console"), consoleObjectTemplate->NewInstance() );
 
-   // add the dali object to it, assume it won't be garbage collected until global is deleted
-  global->Set(v8::String::NewFromUtf8( mIsolate, DALI_API_NAME) ,  NewDaliObjectTemplate( mIsolate ));
+  // add require functionality
+  context->Global()->Set( v8::String::NewFromUtf8( mIsolate, "require"), v8::FunctionTemplate::New( mIsolate, DaliWrapper::Require)->GetFunction());
 
+  // Create the Dali object
+  // @todo consider forcing developers to perform require('dali') if we want to avoid polluting the global namespace
+  v8::Local<v8::Object> daliObject = CreateDaliObject();
 
-  // create a new context.
-  // Isolate = isolated copy of the V8 including a heap manager, a garbage collector
-  // Only 1 thread can access a single Isolate at a given time. However, multiple Isolates can be run in parallel.
-  // Context = multiple contexts can exist in a given Isolate, and share data between contexts
-  v8::Handle<v8::Context> context  = v8::Context::New( mIsolate, NULL, global);
+  // allow developers to require('dali'); // this is to maintain compatibility with node.js where dali is not part of the global namespace
+  mModuleLoader.StorePreBuiltModule( mIsolate, daliObject, DALI_API_NAME );
 
-  mGlobalObjectTemplate.Reset( mIsolate,  global);
+  context->Global()->Set( v8::String::NewFromUtf8( mIsolate, DALI_API_NAME),daliObject );
 
-  mContext.Reset( mIsolate, context);
 }
 
-void DaliWrapper::Initialize()
+void DaliWrapper::InitializeStandAlone()
 {
   if( !mIsolate )
   {
@@ -200,42 +253,35 @@ void DaliWrapper::Initialize()
 
     // default isolate removed from V8 version 3.27.1 and beyond.
     mIsolate = v8::Isolate::New();
+
     mIsolate->Enter();
 
     v8::V8::SetFatalErrorHandler( FatalErrorCallback );
-
   }
+
   // if context is null, create it and add dali object to the global object.
   if( mContext.IsEmpty())
   {
      v8::HandleScope handleScope( mIsolate );
-     CreateContext();
-     v8::Local<v8::Context> context = v8::Local<v8::Context>::New(mIsolate, mContext);
-
-     context->Enter();
-
-     // Add the dali global object. Used for creating objects, and accessing constant values
-     // e.g. var x =  new dali.ImageActor(), or var col = dali.COLOR_RED;
 
-     v8::Local<v8::Object> daliObject = v8::Local<v8::Object>::Cast( context->Global()->Get( v8::String::NewFromUtf8( mIsolate, DALI_API_NAME)));
+     // create a new context.
+     // Isolate = isolated copy of the V8 including a heap manager, a garbage collector
+     // Only 1 thread can access a single Isolate at a given time. However, multiple Isolates can be run in parallel.
+     // Context = multiple contexts can exist in a given Isolate, and share data between contexts
+     v8::Local<v8::Context> context  = v8::Context::New( mIsolate );
 
-     v8::Local<v8::Object> stageObject = StageWrapper::WrapStage( mIsolate, Stage::GetCurrent() );
-     daliObject->Set( v8::String::NewFromUtf8( mIsolate, "stage") , stageObject );
-
-     // fontObject provides static font functionality like GetFontList...
-     v8::Local<v8::Object> fontObject = FontWrapper::GetStaticFontObject( mIsolate );
-     daliObject->Set( v8::String::NewFromUtf8( mIsolate, "font") , fontObject );
-
-     // keyboard focus manager is a singleton
-     v8::Local<v8::Object> keyboardObject = KeyboardFocusManagerWrapper::WrapKeyboardFocusManager( mIsolate,Toolkit::KeyboardFocusManager::Get() );
-     daliObject->Set( v8::String::NewFromUtf8( mIsolate, "keyboardFocusManager") , keyboardObject );
+     context->Enter();
 
-     ConstantsWrapper::AddDaliConstants( mIsolate, daliObject);
+     // Apply global objects like dali and console to the context
+     ApplyGlobalObjectsToContext(context);
 
+     mContext.Reset( mIsolate, context);
   }
+
   DALI_LOG_INFO( gLogExecuteFilter, Debug::Verbose, "V8 Library %s loaded \n", v8::V8::GetVersion() );
 }
 
+
 v8::Handle<v8::ObjectTemplate> DaliWrapper::NewDaliObjectTemplate( v8::Isolate* isolate )
 {
   v8::EscapableHandleScope handleScope( isolate );
@@ -247,11 +293,11 @@ v8::Handle<v8::ObjectTemplate> DaliWrapper::NewDaliObjectTemplate( v8::Isolate*
   objTemplate->Set( v8::String::NewFromUtf8( isolate, "BUILD"),
                     v8::String::NewFromUtf8( isolate, "Dali binary built on:" __DATE__ ", at " __TIME__));
 
-
+#ifdef DALI_DATA_READ_ONLY_DIR
   // add the data data directory,
   objTemplate->Set( v8::String::NewFromUtf8( isolate, "DALI_DATA_DIRECTORY"),
-                      v8::String::NewFromUtf8( isolate, DALI_DATA_READ_ONLY_DIR));
-
+                    v8::String::NewFromUtf8( isolate, DALI_DATA_READ_ONLY_DIR));
+#endif
   // add our constructor functions
   ObjectTemplateHelper::InstallFunctions( isolate,
                                           objTemplate,
@@ -265,12 +311,10 @@ v8::Handle<v8::ObjectTemplate> DaliWrapper::NewDaliObjectTemplate( v8::Isolate*
 void DaliWrapper::Require(const v8::FunctionCallbackInfo< v8::Value >& args)
 {
   DaliWrapper& wrapper( DaliWrapper::Get() );
-  wrapper.mModuleLoader.Require( args, wrapper.mGlobalObjectTemplate );
+  wrapper.mModuleLoader.Require( args );
 }
 
 
-
-
 } // namespace V8Plugin
 
 } // namespace Dali