Merge "Remove navigation frame control" into tizen
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / actors / actor-wrapper.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "actor-wrapper.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23
24 // INTERNAL INCLUDES
25 #include <actors/layer-api.h>
26 #include <actors/actor-api.h>
27 #include <actors/image-actor-api.h>
28 #include <actors/mesh-actor-api.h>
29 #include <actors/camera-actor-api.h>
30 #include <actors/renderable-actor-api.h>
31 #include <v8-utils.h>
32 #include <dali-wrapper.h>
33
34 namespace Dali
35 {
36
37 namespace V8Plugin
38 {
39
40 v8::Persistent<v8::ObjectTemplate> ActorWrapper::mActorTemplate;
41 v8::Persistent<v8::ObjectTemplate> ActorWrapper::mImageActorTemplate;
42 v8::Persistent<v8::ObjectTemplate> ActorWrapper::mMeshActorTemplate;
43 v8::Persistent<v8::ObjectTemplate> ActorWrapper::mCameraActorTemplate;
44 v8::Persistent<v8::ObjectTemplate> ActorWrapper::mLayerActorTemplate;
45 v8::Persistent<v8::ObjectTemplate> ActorWrapper::mTextLabelTemplate;
46
47 namespace
48 {
49
50
51 /**
52  * pointer to a persistent template handle
53  */
54 struct ActorTemplate
55 {
56   v8::Persistent<v8::ObjectTemplate>* actorTemplate;
57 };
58
59 /**
60  * array of templates for each type of actor
61  */
62 const ActorTemplate ActorTemplateLookup[]=
63 {
64     { &ActorWrapper::mActorTemplate },        // ACTOR
65     { &ActorWrapper::mImageActorTemplate },   // IMAGE_ACTOR
66     { &ActorWrapper::mMeshActorTemplate  },   // MESH_ACTOR
67     { &ActorWrapper::mLayerActorTemplate },   // LAYER_ACTOR
68     { &ActorWrapper::mCameraActorTemplate},   // CAMERA_ACTOR
69     { &ActorWrapper::mTextLabelTemplate }
70 };
71
72 /**
73  * Bitmask of API's that an actor can support
74  */
75 enum ActorApiBitMask
76 {
77   ACTOR_API              = 1 << 0,
78   RENDERABLE_ACTOR_API   = 1 << 1,
79   IMAGE_ACTOR_API        = 1 << 2,
80   MESH_ACTOR_API         = 1 << 3,
81   LAYER_API              = 1 << 4,
82   CAMERA_ACTOR_API       = 1 << 5,
83 };
84
85 /**
86  * structure used for the ActorApiLookup.
87  */
88 struct ActorApiStruct
89 {
90   const char* actorName;
91   ActorWrapper::ActorType actorType;
92   Actor (*constructor)( const v8::FunctionCallbackInfo< v8::Value >& args);
93   int supportApis;
94 };
95
96 /**
97  * Lookup table to match a actor type with a constructor and supported API's.
98  */
99 const ActorApiStruct ActorApiLookup[]=
100 {
101   {"Actor",      ActorWrapper::ACTOR,        ActorApi::New,       ACTOR_API },
102   {"ImageActor", ActorWrapper::IMAGE_ACTOR,  ImageActorApi::New,  ACTOR_API | RENDERABLE_ACTOR_API | IMAGE_ACTOR_API   },
103   {"MeshActor",  ActorWrapper::MESH_ACTOR,   MeshActorApi::New,   ACTOR_API | RENDERABLE_ACTOR_API | MESH_ACTOR_API    },
104   {"Layer",      ActorWrapper::LAYER_ACTOR,  LayerApi::New,       ACTOR_API | LAYER_API                                },
105   {"CameraActor",ActorWrapper::CAMERA_ACTOR, CameraActorApi::New, ACTOR_API | CAMERA_ACTOR_API                         },
106   {"TextLabel",  ActorWrapper::TEXT_LABEL,   TextLabelApi::New,   ACTOR_API },
107
108 };
109
110 const unsigned int ActorApiLookupCount = sizeof(ActorApiLookup)/sizeof(ActorApiLookup[0]);
111
112
113
114 /**
115  * Creates an actor given a type name
116  * Uses the type registry to create an actor of the correct type
117  */
118 Actor CreateActor( const v8::FunctionCallbackInfo< v8::Value >& args,
119                         const std::string& typeName )
120 {
121   Actor actor;
122
123   ActorWrapper::ActorType actorType = ActorWrapper::GetActorType( typeName );
124
125   // if we don't currently support the actor type, then use type registry to create it
126   if( actorType == ActorWrapper::UNKNOWN_ACTOR )
127   {
128     Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
129     if( typeInfo ) // handle, check if it has a value
130     {
131       Dali::BaseHandle handle = typeInfo.CreateInstance();
132       if( handle )
133       {
134         actor = Actor::DownCast( handle );
135       }
136     }
137     else
138     {
139       DALI_SCRIPT_EXCEPTION(args.GetIsolate(),"Unknown actor type");
140       return Actor();
141     }
142   }
143   else
144   {
145     // run the constructor for this type of actor so it can pull out
146     // custom parameters, e.g. new ImageActor( MyImage );
147     actor = (ActorApiLookup[actorType].constructor)( args );
148   }
149   return actor;
150 }
151
152
153
154 /**
155  * given an actor type return what api's it supports
156  */
157 int GetActorSupportedApis( ActorWrapper::ActorType type )
158 {
159   return ActorApiLookup[ type].supportApis;
160 }
161
162 /**
163  * Used for the ActorFunctionTable to map function names to functions
164  * with for a specific API
165  */
166 struct ActorFunctions
167 {
168   const char* name;               ///< function name
169   void (*function)( const v8::FunctionCallbackInfo< v8::Value >& args);
170   ActorApiBitMask api;
171 };
172
173 /**
174  * Contains a list of all functions that can be called an
175  * actor / image-actor / mesh-actor/ layer / camera-actor
176  */
177 const ActorFunctions ActorFunctionTable[]=
178 {
179     /**************************************
180     * Actor API (in order of actor.h)
181     * Any properties that have accessor functions are ignored to avoid duplication
182     **************************************/
183     // ignore. GetName()  use Actor.name
184     // ignore. SetName()  use Actor.name
185     { "GetId",             ActorApi::GetId,            ACTOR_API },
186     { "IsRoot",            ActorApi::IsRoot,           ACTOR_API },
187     { "OnStage",           ActorApi::OnStage,          ACTOR_API },
188     { "IsLayer",           ActorApi::IsLayer,          ACTOR_API },
189     { "GetLayer",          ActorApi::GetLayer,         ACTOR_API },
190     { "Add",               ActorApi::AddActor,         ACTOR_API },
191     { "Remove",            ActorApi::RemoveActor,      ACTOR_API },
192     { "IsEqualTo" ,        ActorApi::IsEqualTo,        ACTOR_API },
193     { "Unparent",          ActorApi::Unparent,         ACTOR_API },
194     { "GetChildCount",     ActorApi::GetChildCount,    ACTOR_API },
195     { "GetChildAt"   ,     ActorApi::GetChildAt,       ACTOR_API },
196     { "FindChildByName",   ActorApi::FindChildByName,  ACTOR_API },
197     { "FindChildById",     ActorApi::FindChildById,    ACTOR_API },
198     { "GetParent" ,        ActorApi::GetParent,        ACTOR_API },
199     { "GetActorType" ,     ActorApi::GetActorType,     ACTOR_API }, // custom for javascript
200     { "ApplyPathConstraint",  ActorApi::ApplyPathConstraint,  ACTOR_API }, // custom for javascript
201     { "RemovePathConstraint", ActorApi::RemovePathConstraint, ACTOR_API }, // custom for javascript
202
203     // ignore. SetParentOrigin() use Actor.parentOrigin
204     // ignore. GetCurrentParentOrigin()  use Actor.parentOrigin
205     // ignore. SetAnchorPoint()  use Actor.anchorPoint
206     // ignore. GetCurrentAnchorPoint()  use Actor.anchorPoint
207     // ignore. SetSize() use Actor.size
208     // ignore. GetCurrentSize() use Actor.size
209     // ignore. SetPosition(....) use Actor.position
210     // ignore. SetX, SetY, SetZ,  use Actor.position.x, Actor.position.y, Actor.position.z
211     { "TranslateBy",         ActorApi::TranslateBy,              ACTOR_API },
212     // ignore GetCurrentPosition(). use Actor.position
213     // ignore GetCurrentWorldPosition() use Actor.worldPosition
214     // ignore SetPositionInheritanceMode() use Actor.positionInheritance
215     // ignore GetPositionInheritanceMode()  use Actor.positionInheritance
216     // ignore SetOrientation() use Actor.orientation
217     { "RotateBy",         ActorApi::RotateBy,          ACTOR_API },
218     // ignore GetCurrentOrientation() use Actor.orientation
219     // ignore SetInheritOrientation() use Actor.inheritOrientation
220     // ignore IsOrientationInherited() use Actor.inheritOrientation
221     // ignore GetCurrentWorldOrientation() use Actor.worldOrientation
222     // ignore SetScale() use Actor.scale
223     { "ScaleBy",         ActorApi::ScaleBy,            ACTOR_API },
224     // ignore GetCurrentScale() use Actor.scale
225     // ignore GetCurrentWorldScale() use Actor.worldScale
226     // ignore SetInheritScale() use Actor.inheritScale
227     // ignore IsScaleInherited() use Actor.inheritScale
228     // ignore GetCurrentWorldMatrix() use Actor.worldMatrix
229     // ignore SetVisible() use Actor.visible
230     // ignore IsVisible() use Actor.visible
231     // ignore SetOpacity() use Actor.opacity
232     // ignore GetCurrentOpacity() use Actor.opacity
233     // ignore SetColor() use Actor.color
234     // ignore GetCurrentColor() use Actor.color
235     // ignore SetColorMode() use Actor.colorMode
236     // ignore GetColorMode() use Actor.colorMode
237     // ignore GetCurrentWorldColor() use Actor.worldColor
238     // ignore SetInheritShaderEffect() use Actor.inheritShaderEffect
239     // ignore GetInheritShaderEffect() use Actor.inheritShaderEffect
240     // ignore SetDrawMode() use Actor.drawMode
241     // ignore GetDrawMode() use Actor.drawMode
242     // ignore SetSensitive() use Actor.sensitve
243     // ignore IsSensitive() use Actor.sensitive
244     { "ScreenToLocal"       , ActorApi::ScreenToLocal,         ACTOR_API},
245     // ignore SetLeaveRequired() use Actor.leaveRequired
246     // ignore GetLeaveRequired() use Actor.leaveRequired
247     { "SetKeyboardFocusable", ActorApi::SetKeyboardFocusable,  ACTOR_API }, //-- should this be a property???
248     { "IsKeyboardFocusable" , ActorApi::IsKeyboardFocusable,   ACTOR_API }, //-- should this be a property???
249
250     /**************************************
251      * Renderable Actor API (in order of renderable-actor.h)
252      **************************************/
253     { "SetSortModifier",    RenderableActorApi::SetSortModifier,   RENDERABLE_ACTOR_API  },
254     { "GetSortModifier",    RenderableActorApi::GetSortModifier,   RENDERABLE_ACTOR_API  },
255     { "SetCullFace",        RenderableActorApi::SetCullFace,       RENDERABLE_ACTOR_API  },
256     { "GetCullFace",        RenderableActorApi::GetCullFace,       RENDERABLE_ACTOR_API  },
257     { "SetBlendMode",       RenderableActorApi::SetBlendMode,      RENDERABLE_ACTOR_API  },
258     { "GetBlendMode",       RenderableActorApi::GetBlendMode,      RENDERABLE_ACTOR_API  },
259     { "SetBlendFunc",       RenderableActorApi::SetBlendFunc,      RENDERABLE_ACTOR_API  },
260     { "GetBlendFunc",       RenderableActorApi::GetBlendFunc,      RENDERABLE_ACTOR_API  },
261     { "SetShaderEffect",    RenderableActorApi::SetShaderEffect,   RENDERABLE_ACTOR_API  },
262     { "GetShaderEffect",    RenderableActorApi::GetShaderEffect,   RENDERABLE_ACTOR_API  },
263     { "RemoveShaderEffect", RenderableActorApi::RemoveShaderEffect,RENDERABLE_ACTOR_API  },
264
265
266
267
268     /**************************************
269      * Layer  API (in order of layer.h)
270      **************************************/
271     { "GetDepth",           LayerApi::GetDepth,                 LAYER_API  },
272     { "Raise",              LayerApi::Raise,                    LAYER_API  },
273     { "Lower",              LayerApi::Lower,                    LAYER_API  },
274     { "RaiseAbove",         LayerApi::RaiseAbove,               LAYER_API  },
275     { "RaiseBelow",         LayerApi::LowerBelow,               LAYER_API  },
276     { "RaiseToTop",         LayerApi::RaiseToTop,               LAYER_API  },
277     { "LowerToBottom",      LayerApi::ToBottom,                 LAYER_API  },
278     { "MoveAbove",          LayerApi::MoveAbove,                LAYER_API  },
279     { "MoveBelow",          LayerApi::MoveBelow,                LAYER_API  },
280     // ignore SetClipping, use layer.clippingEnable
281     // ignore IsClipping, use layer.clippingEnable
282     // ignore SetClippingBox, use layer.clippingBox
283     { "SetDepthTestDisabled", LayerApi::SetDepthTestDisabled,   LAYER_API },
284     { "IsDepthTestDisabled",  LayerApi::IsDepthTestDisabled,    LAYER_API },
285     // @todo SetSortFunction
286
287     /**************************************
288      * Image Actor API (in order of image-actor.h)
289      **************************************/
290
291     { "SetImage",           ImageActorApi::SetImage,              IMAGE_ACTOR_API },
292     { "GetImage",           ImageActorApi::GetImage,              IMAGE_ACTOR_API },
293     // ignore SetPixelArea, use imageActor.pixelArea
294     // ignore GetPixelArea, use imageActor.pixelArea
295     // ignore SetStyle, use imageActor.style
296     // ignore GetStyle, use imageActor.style
297     // ignore SetNinePatchBorder use imageActor.border
298     // ignore GetNinePatchBorder use imageActor.border
299     // ignore SetFadeIn use imageActor.fadeIn
300     // ignore GetFadeIn use imageActor.fadeIn
301     // ignore SetFadeInDuration use imageActor.fadeInDuration
302     // ignore GetFadeInDuration use imageActor.fadeInDuration
303     //{ "GetCurrentImageSize", ImageActorApi::GetCurrentImageSize,  IMAGE_ACTOR_API },
304
305     /**************************************
306      * Mesh Actor API (in order of mesh-actor.h)
307      **************************************/
308     // @todo a version of MeshActor::New( mesh )
309     // @todo a version of MeshActor::New( AnimatableMesh )
310     // @todo SetMaterial
311     // @todo GetMaterial
312     // @todo BindBonesToMesh
313
314     /**************************************
315      * Camera Actor API (in order of camera.h)
316      **************************************/
317     // ignore SetType use camera.type
318     // ignore GetType use camera.type
319     // ignore SetProjectionMode use camera.projectionMode
320     // ignore GetProjectionMode use camera.projectionMode
321     // ignore SetFieldOfView use camera.fieldOfView
322     // ignore GetFieldOfView use camera.fieldOfView
323     // ignore SetAspectRatio use camera.aspectRatio
324     // ignore GetAspectRatio use camera.aspectRatio
325     // ignore SetNearClippingPlane use camera.nearPlaneDistance
326     // ignore GetNearClippingPlane use camera.nearPlaneDistance
327     // ignore SetFarClippingPlane use camera.farPlaneDistance
328     // ignore GetFarClippingPlane use camera.farPlaneDistance
329     // ignore GetTargetPosition use camera.targetPosition
330     // ignore SetInvertYAxis use camera.invertYAxis
331     // ignore GetInvertYAxis use camera.invertYAxis
332     { "SetPerspectiveProjection",   CameraActorApi::SetPerspectiveProjection,   CAMERA_ACTOR_API },
333     { "SetOrthographicProjection",  CameraActorApi::SetOrthographicProjection,  CAMERA_ACTOR_API },
334
335 };
336
337 const unsigned int ActorFunctionTableCount = sizeof(ActorFunctionTable)/sizeof(ActorFunctionTable[0]);
338 } //un-named space
339
340
341 ActorWrapper::ActorWrapper( Actor actor,
342               GarbageCollectorInterface& gc )
343 : HandleWrapper( BaseWrappedObject::ACTOR , actor, gc ),
344   mActor( actor )
345
346 {
347 }
348
349 v8::Handle<v8::Object> ActorWrapper::WrapActor(v8::Isolate* isolate, Actor actor )
350 {
351   v8::EscapableHandleScope handleScope( isolate );
352   v8::Local<v8::Object> object = WrapActor( isolate, actor, GetActorType( actor.GetTypeName() ) );
353
354   return handleScope.Escape( object );
355 }
356
357 Actor ActorWrapper::GetActor()
358 {
359   return mActor;
360 }
361
362 v8::Handle<v8::Object> ActorWrapper::WrapActor( v8::Isolate* isolate, Actor actor, ActorType actorType )
363 {
364   v8::EscapableHandleScope handleScope( isolate );
365   v8::Local<v8::ObjectTemplate> objectTemplate;
366
367   objectTemplate = GetActorTemplate( isolate, actorType );
368
369   // create an instance of the template
370   v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
371
372   // create teh actor object
373   ActorWrapper* pointer = new ActorWrapper( actor, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
374
375   // assign the JavaScript object to the wrapper.
376   // This also stores Dali object, in an internal field inside the JavaScript object.
377   pointer->SetJavascriptObject( isolate, localObject );
378
379   return handleScope.Escape( localObject );
380 }
381
382 v8::Local<v8::ObjectTemplate> ActorWrapper::GetActorTemplate( v8::Isolate* isolate, ActorWrapper::ActorType type )
383 {
384   v8::EscapableHandleScope handleScope( isolate );
385   v8::Local<v8::ObjectTemplate> objectTemplate;
386
387   if( ActorTemplateLookup[type].actorTemplate->IsEmpty() )
388   {
389     objectTemplate = MakeDaliActorTemplate( isolate, type );
390     ActorTemplateLookup[type].actorTemplate->Reset( isolate, objectTemplate );
391   }
392   else
393   {
394     // get the object template
395     objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, *ActorTemplateLookup[type].actorTemplate );
396   }
397
398   return handleScope.Escape( objectTemplate );
399 }
400
401 v8::Handle<v8::ObjectTemplate> ActorWrapper::MakeDaliActorTemplate( v8::Isolate* isolate, ActorType actorType )
402 {
403   v8::EscapableHandleScope handleScope( isolate );
404
405   v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
406
407   objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
408
409   // find out what API's this actor supports
410   int supportApis = GetActorSupportedApis( actorType );
411
412   // add our function properties
413   for( unsigned int i = 0; i < ActorFunctionTableCount; ++i )
414   {
415     const ActorFunctions property =  ActorFunctionTable[i];
416
417     // check to see if the actor supports a certain type of API
418     // e.g. ImageActor will support ACTOR_API, RENDERABLE_API and IMAGE_ACTOR_API
419     if( supportApis &  property.api )
420     {
421       std::string funcName = V8Utils::GetJavaScriptFunctionName( property.name);
422
423       objTemplate->Set( v8::String::NewFromUtf8(   isolate, funcName.c_str() ),
424                       v8::FunctionTemplate::New( isolate, property.function ) );
425     }
426   }
427
428   // property handle intercepts property getters and setters and signals
429   HandleWrapper::AddInterceptsToTemplate( isolate, objTemplate );
430
431
432   return handleScope.Escape( objTemplate );
433 }
434
435 void ActorWrapper::NewActor( const v8::FunctionCallbackInfo< v8::Value >& args)
436 {
437   v8::Isolate* isolate = args.GetIsolate();
438   v8::HandleScope handleScope( isolate );
439
440   if( !args.IsConstructCall() )
441   {
442     DALI_SCRIPT_EXCEPTION( isolate, "constructor called without 'new" );
443     return;
444   }
445
446   // find out the callee function name...e.g. ImageActor, MeshActor
447   v8::Local<v8::Function> callee = args.Callee();
448   v8::Local<v8::Value> v8String = callee->GetName();
449   std::string typeName = V8Utils::v8StringToStdString( v8String );
450
451   // create a new actor based on type, using the type registry.
452   Actor actor = CreateActor( args, typeName );
453
454   v8::Local<v8::Object> localObject = WrapActor( isolate, actor );
455
456   args.GetReturnValue().Set( localObject );
457 }
458
459 /**
460  * given an actor type name, e.g. ImageActor returns the type, e.g. ActorWrapper::IMAGE_ACTOR
461  */
462 ActorWrapper::ActorType ActorWrapper::GetActorType( const std::string& name )
463 {
464   for( unsigned int i = 0 ; i < ActorApiLookupCount ; i++ )
465   {
466     if( ActorApiLookup[i].actorName == name )
467     {
468       return ActorApiLookup[i].actorType;
469     }
470   }
471   return ActorWrapper::UNKNOWN_ACTOR;
472 }
473
474
475
476 } // namespace V8Plugin
477
478 } // namespace Dali