[dali_1.1.9] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / toolkit / builder / builder-api.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 "builder-api.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <string>
24 #include <fstream>
25 #include <streambuf>
26
27 // INTERNAL INCLUDES
28 #include <v8-utils.h>
29 #include <object/property-value-wrapper.h>
30 #include <object/handle-wrapper.h>
31 #include <toolkit/builder/builder-wrapper.h>
32 #include <actors/actor-wrapper.h>
33 #include <image/image-wrapper.h>
34 #include <animation/animation-wrapper.h>
35 #include <shader-effects/shader-effect-wrapper.h>
36 #include <rendering/shader-wrapper.h>
37
38
39 namespace Dali
40 {
41
42 namespace V8Plugin
43 {
44
45 namespace // un named namespace
46 {
47
48
49 Dali::Toolkit::Builder GetBuilder( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
50 {
51   v8::HandleScope handleScope( isolate );
52
53   v8::Local<v8::Object> object = args.This();
54   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField( 0 ) );
55   void* ptr = field->Value();
56
57   BuilderWrapper* wrapper = static_cast<BuilderWrapper *>( ptr );
58   return wrapper->GetBuilder();
59 }
60
61
62 void GetMapAndString( v8::Isolate* isolate,
63                       std::string stringKey,
64                       std::string& stringValue,
65                       std::string mapKey,
66                       Dali::Property::Map& map,
67                       v8::Local<v8::Object> object)
68 {
69     v8::Local<v8::Value> stringNameValue = object->Get( v8::String::NewFromUtf8( isolate, stringKey.c_str() ) );
70     if( !stringNameValue->IsString() )
71     {
72       std::string message = "missing field :"+stringKey;
73       DALI_SCRIPT_EXCEPTION( isolate,  message);
74       return;
75     }
76     stringValue = V8Utils::v8StringToStdString( stringNameValue );
77
78     // constants is optional
79
80     v8::Local<v8::Value> constants = object->Get( v8::String::NewFromUtf8( isolate, mapKey.c_str() ) );
81     if( constants->IsObject() )
82     {
83       map = V8Utils::GetPropertyMapFromObject( isolate, constants->ToObject() );
84     }
85 }
86
87
88 } // un-named namespace
89
90
91 Dali::Toolkit::Builder BuilderApi::New( const v8::FunctionCallbackInfo< v8::Value >& args )
92 {
93   v8::Isolate* isolate = args.GetIsolate();
94   v8::HandleScope handleScope( isolate );
95
96   return Dali::Toolkit::Builder::New();
97 }
98
99 void BuilderApi::LoadFromString( const v8::FunctionCallbackInfo< v8::Value >& args )
100 {
101   v8::Isolate* isolate = args.GetIsolate();
102   v8::HandleScope handleScope( isolate );
103
104   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
105
106   bool found(false);
107   std::string str = V8Utils::GetStringParameter( 0, found, isolate, args );
108   if( found )
109   {
110     builder.LoadFromString( str );
111   }
112   else
113   {
114     DALI_SCRIPT_EXCEPTION( isolate,  "missing string parameter");
115   }
116 }
117
118 void BuilderApi::LoadFromFile( const v8::FunctionCallbackInfo< v8::Value >& args )
119 {
120   v8::Isolate* isolate = args.GetIsolate();
121   v8::HandleScope handleScope( isolate );
122
123   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
124
125   bool found(false);
126   std::string fileName= V8Utils::GetStringParameter( 0, found, isolate, args );
127   if( !found )
128   {
129     DALI_SCRIPT_EXCEPTION( isolate,  "missing string parameter");
130     return;
131   }
132
133   std::ifstream fileStream( fileName.c_str() );
134   if( !fileStream.is_open() )
135   {
136     std::string message = "failed to open JSON file" + fileName;
137     DALI_SCRIPT_EXCEPTION( isolate,  message );
138     return;
139   }
140
141   //single-pass input iterator that reads successive characters from the input stream
142   std::string json = std::string( (std::istreambuf_iterator< char >( fileStream )), std::istreambuf_iterator< char >() );
143
144   builder.LoadFromString( json );
145
146 }
147
148 void BuilderApi::AddConstants( const v8::FunctionCallbackInfo< v8::Value >& args )
149 {
150   v8::Isolate* isolate = args.GetIsolate();
151   v8::HandleScope handleScope( isolate );
152
153   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
154
155   bool found(false);
156   Dali::Property::Map map = V8Utils::GetPropertyMapParameter( 0,found, isolate, args );
157
158   if( found )
159   {
160     builder.AddConstants( map );
161   }
162   else
163   {
164     DALI_SCRIPT_EXCEPTION( isolate,  "no constants found" );
165   }
166
167 }
168
169 void BuilderApi::GetConstants( const v8::FunctionCallbackInfo< v8::Value >& args )
170 {
171   v8::Isolate* isolate = args.GetIsolate();
172   v8::HandleScope handleScope( isolate );
173
174   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
175
176   const Dali::Property::Map& map  = builder.GetConstants();
177
178   v8::Local<v8::Object> object = v8::Object::New( isolate );
179
180   V8Utils::CreatePropertyMap( isolate, map, object );
181
182   args.GetReturnValue().Set( object );
183
184 }
185 void BuilderApi::CreateAnimation( const v8::FunctionCallbackInfo< v8::Value >& args )
186 {
187   v8::Isolate* isolate = args.GetIsolate();
188   v8::HandleScope handleScope( isolate );
189
190   // options =
191   // {
192   //    animation: ..
193   //    constants:
194   //    actor:
195   // }
196   //
197
198   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
199
200   if( !args[0]->IsObject() )
201   {
202     DALI_SCRIPT_EXCEPTION( isolate,  "invalid property map, expecting { animation: x, constants: y, actor: z}" );
203     return;
204   }
205   v8::Local<v8::Object> object = args[0]->ToObject();
206
207   std::string animationName;
208   Dali::Property::Map map;
209
210   //  get the animation name and constant map
211
212   GetMapAndString( isolate,
213                    "animation",
214                    animationName,
215                    "constants",
216                    map,
217                    object );
218
219   // actor is optional
220   Actor actor;
221   v8::Local<v8::Value> actorValue = object->Get( v8::String::NewFromUtf8( isolate, "actor" ) );
222   if( actorValue->IsObject() )
223   {
224     HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, actorValue->ToObject() );
225     if( handleWrapper )
226     {
227       actor = Actor::DownCast( handleWrapper->mHandle );
228     }
229   }
230   Animation anim;
231   if( actor )
232   {
233     //  Animation CreateAnimation( const std::string& animationName, const Dali::Property::Map& map, Dali::Actor sourceActor );
234     anim = builder.CreateAnimation( animationName, map, actor );
235   }
236   else
237   {
238     anim = builder.CreateAnimation( animationName, map);
239   }
240   v8::Local<v8::Object> localObject = AnimationWrapper::WrapAnimation( isolate, anim );
241   args.GetReturnValue().Set( localObject );
242 }
243
244 void BuilderApi::Create( const v8::FunctionCallbackInfo< v8::Value >& args )
245 {
246   v8::Isolate* isolate = args.GetIsolate();
247   v8::HandleScope handleScope( isolate );
248
249   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
250
251   if( !args[0]->IsObject() )
252   {
253     DALI_SCRIPT_EXCEPTION( isolate,  "invalid param");
254     return;
255   }
256   v8::Local<v8::Object> object = args[0]->ToObject();
257
258   // options =
259   // {
260   //    template: "myTemplate",
261   //    constants: {  IMAGE_DIR: "/usr/apps" ,  SHADER_DIR: "/usr/apps/.."}
262   // }
263   //
264   std::string templateName;
265   Dali::Property::Map map;
266
267   GetMapAndString( isolate,
268                    "template",
269                    templateName,
270                    "constants",
271                    map,
272                    object );
273
274   BaseHandle handle = builder.Create( templateName, map );
275   std::string typeName = handle.GetTypeName();
276   ActorWrapper::ActorType actorType = ActorWrapper::GetActorType( typeName );
277
278   if( actorType != ActorWrapper::UNKNOWN_ACTOR )
279   {
280     v8::Local<v8::Object> actorObject =  ActorWrapper::WrapActor(isolate, Actor::DownCast(handle),actorType);
281     args.GetReturnValue().Set( actorObject );
282     return;
283   }
284
285   if( typeName == "Animation")
286   {
287     v8::Local<v8::Object> animation = AnimationWrapper::WrapAnimation(isolate, Animation::DownCast(handle) );
288     args.GetReturnValue().Set( animation );
289   }
290
291   if( typeName == "Image")
292   {
293     v8::Local<v8::Object> image = ImageWrapper::WrapImage(isolate, Image::DownCast(handle) );
294     args.GetReturnValue().Set( image );
295   }
296   if( typeName == "ShaderEffect")
297   {
298     v8::Local<v8::Object> shaderEffect = ShaderEffectWrapper::WrapShaderEffect(isolate, ShaderEffect::DownCast( handle ));
299     args.GetReturnValue().Set( shaderEffect );
300   }
301   if( typeName == "Shader")
302   {
303     v8::Local<v8::Object> shader = ShaderWrapper::WrapShader(isolate, Shader::DownCast( handle ));
304     args.GetReturnValue().Set( shader );
305   }
306 }
307 void BuilderApi::ApplyStyle( const v8::FunctionCallbackInfo< v8::Value >& args )
308 {
309   v8::Isolate* isolate = args.GetIsolate();
310   v8::HandleScope handleScope( isolate );
311   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
312
313   // bool ApplyStyle( const std::string& styleName, Handle& handle );
314
315   bool found(false);
316   std::string styleName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args);
317   if( !found )
318   {
319     DALI_SCRIPT_EXCEPTION( isolate,  "missing style name" );
320     return;
321   }
322
323   Dali::Handle handle = V8Utils::GetHandleParameter( PARAMETER_1, found, isolate, args  );
324   if( !found )
325   {
326     DALI_SCRIPT_EXCEPTION( isolate,  "missing handle parameter" );
327     return;
328   }
329
330   builder.ApplyStyle( styleName, handle );
331
332 }
333
334 void BuilderApi::ApplyFromJson( const v8::FunctionCallbackInfo< v8::Value >& args )
335 {
336   v8::Isolate* isolate = args.GetIsolate();
337   v8::HandleScope handleScope( isolate );
338   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
339
340   bool found;
341
342   Dali::Handle handle = V8Utils::GetHandleParameter( PARAMETER_0, found, isolate, args  );
343   if( !found )
344   {
345     DALI_SCRIPT_EXCEPTION( isolate,  "missing handle parameter" );
346     return;
347   }
348   std::string jsonString = V8Utils::GetStringParameter( PARAMETER_1, found, isolate, args);
349   if( !found )
350   {
351     DALI_SCRIPT_EXCEPTION( isolate,  "missing JSON string" );
352     return;
353   }
354   builder.ApplyFromJson( handle, jsonString );
355 }
356
357 void BuilderApi::AddActors( const v8::FunctionCallbackInfo< v8::Value >& args )
358 {
359   v8::Isolate* isolate = args.GetIsolate();
360   v8::HandleScope handleScope( isolate );
361   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
362
363   //{
364   //  actor:actor
365   //  section: name
366   //}
367
368   Actor actor;
369
370   if( !args[0]->IsObject() )
371   {
372     DALI_SCRIPT_EXCEPTION( isolate,  "invalid param");
373     return;
374   }
375   v8::Local<v8::Object> object = args[0]->ToObject();
376
377   v8::Local<v8::Value> actorValue = object->Get( v8::String::NewFromUtf8( isolate, "actor" ) );
378   if( actorValue->IsObject() )
379   {
380     HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, actorValue->ToObject() );
381     if( handleWrapper )
382     {
383       actor = Actor::DownCast( handleWrapper->mHandle );
384     }
385   }
386   else
387   {
388     DALI_SCRIPT_EXCEPTION( isolate,  "actor field not found in param");
389     return;
390   }
391
392   v8::Local<v8::Value> stringNameValue = object->Get( v8::String::NewFromUtf8( isolate, "section" ) );
393   if( !stringNameValue->IsString() )
394   {
395     std::string message = "missing field: section";
396     DALI_SCRIPT_EXCEPTION( isolate,  message);
397     return;
398   }
399   std::string sectionName = V8Utils::v8StringToStdString( stringNameValue );
400   if( !sectionName.empty() )
401   {
402     builder.AddActors( sectionName, actor );
403   }
404   else
405   {
406     builder.AddActors(  actor );
407   }
408
409 }
410
411 void BuilderApi::CreateRenderTask( const v8::FunctionCallbackInfo< v8::Value >& args )
412 {
413   v8::Isolate* isolate = args.GetIsolate();
414   v8::HandleScope handleScope( isolate );
415   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
416   bool found(false);
417   std::string str = V8Utils::GetStringParameter( 0, found, isolate, args );
418
419   if( found )
420   {
421     builder.CreateRenderTask( str );
422   }
423   else
424   {
425      DALI_SCRIPT_EXCEPTION( isolate, "render task name");
426   }
427 }
428
429 void BuilderApi::GetShaderEffect( const v8::FunctionCallbackInfo< v8::Value >& args )
430 {
431   v8::Isolate* isolate = args.GetIsolate();
432   v8::HandleScope handleScope( isolate );
433   Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
434
435   bool found(false);
436   std::string str = V8Utils::GetStringParameter( 0, found, isolate, args );
437   if( found )
438   {
439     ShaderEffect handle = builder.GetShaderEffect( str );
440     v8::Local<v8::Object> shader = ShaderEffectWrapper::WrapShaderEffect(isolate, handle);
441     args.GetReturnValue().Set( shader );
442   }
443   else
444   {
445     DALI_SCRIPT_EXCEPTION( isolate, "missing shader name");
446   }
447 }
448
449 void BuilderApi::GetFrameBufferImage( const v8::FunctionCallbackInfo< v8::Value >& args )
450 {
451   v8::Isolate* isolate = args.GetIsolate();
452    v8::HandleScope handleScope( isolate );
453    Dali::Toolkit::Builder builder = GetBuilder( isolate, args );
454
455    bool found(false);
456    std::string str = V8Utils::GetStringParameter( 0, found, isolate, args );
457    if( found )
458    {
459      // wrap the image
460      // @TODO Test this, may need to implement a Framebuffer image wrapper.?
461      v8::Local<v8::Object> localObject = ImageWrapper::WrapImage( isolate, builder.GetFrameBufferImage(str)  );
462      args.GetReturnValue().Set( localObject );
463    }
464    else
465    {
466      DALI_SCRIPT_EXCEPTION( isolate,  "frame buffer name");
467    }
468
469 }
470
471 } // namespace V8Plugin
472
473 } // namespace Dali