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