Changes for std::vector removal from api
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / builder-impl.cpp
1 /*
2  * Copyright (c) 2014 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 <dali-toolkit/internal/builder/builder-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <sys/stat.h>
23 #include <boost/function.hpp>
24 #include <sstream>
25 #include <dali/public-api/render-tasks/render-task-list.h>
26 #include <dali/public-api/object/type-info.h>
27 #include <dali/public-api/object/type-registry.h>
28 #include <dali/public-api/object/property-array.h>
29 #include <dali/public-api/actors/layer.h>
30 #include <dali/public-api/actors/image-actor.h>
31 #include <dali/public-api/actors/camera-actor.h>
32 #include <dali/devel-api/scripting/scripting.h>
33 #include <dali/integration-api/debug.h>
34
35 // INTERNAL INCLUDES
36 #include <dali-toolkit/public-api/controls/control.h>
37 #include <dali-toolkit/devel-api/builder/json-parser.h>
38
39 #include <dali-toolkit/internal/builder/builder-get-is.inl.h>
40 #include <dali-toolkit/internal/builder/builder-filesystem.h>
41 #include <dali-toolkit/internal/builder/builder-declarations.h>
42 #include <dali-toolkit/internal/builder/replacement.h>
43
44 namespace Dali
45 {
46
47 namespace Toolkit
48 {
49
50 namespace Internal
51 {
52 class Replacement;
53
54 extern Animation CreateAnimation(const TreeNode& child, const Replacement& replacements, const Dali::Actor searchRoot, Builder* const builder );
55 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value );
56 extern bool SetPropertyFromNode( const TreeNode& node, Property::Value& value, const Replacement& replacements );
57 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value );
58 extern bool SetPropertyFromNode( const TreeNode& node, Property::Type type, Property::Value& value, const Replacement& replacements );
59 extern Actor SetupSignalAction(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction, Dali::Toolkit::Internal::Builder* const builder);
60 extern Actor SetupPropertyNotification(ConnectionTracker* tracker, const TreeNode &root, const TreeNode &child, Actor actor, boost::function<void (void)> quitAction, Dali::Toolkit::Internal::Builder* const builder);
61 extern Actor SetupActor( const TreeNode& node, Actor& actor, const Replacement& constant );
62
63 #if defined(DEBUG_ENABLED)
64 Integration::Log::Filter* gFilterScript  = Integration::Log::Filter::New(Debug::NoLogging, false, "LOG_SCRIPT");
65 #endif
66
67 namespace
68 {
69
70 const std::string KEYNAME_STYLES    = "styles";
71 const std::string KEYNAME_TYPE      = "type";
72 const std::string KEYNAME_ACTORS    = "actors";
73 const std::string KEYNAME_SIGNALS   = "signals";
74 const std::string KEYNAME_NAME      = "name";
75 const std::string KEYNAME_TEMPLATES = "templates";
76 const std::string KEYNAME_INCLUDES  = "includes";
77
78 typedef std::vector<const TreeNode*> TreeNodeList;
79
80 template <typename T>
81 std::string ToString(const T& value)
82 {
83   std::stringstream ss;
84   ss << value;
85   return ss.str();
86 }
87
88 template <>
89 std::string ToString(const Rect<int>& value)
90 {
91   std::stringstream ss;
92   ss << value.x << "," << value.y << "," << value.width << "," << value.height;
93   return ss.str();
94 }
95
96 #if defined(DEBUG_ENABLED)
97
98 std::string PropertyValueToString( const Property::Value& value )
99 {
100   std::string ret;
101
102   switch( value.GetType() )
103   {
104     case Property::NONE:
105     {
106       ret = "NONE";
107       break;
108     }            ///< No type
109     case Property::BOOLEAN:
110     {
111       ret = value.Get<bool>() ? "True" : "False";
112       break;
113     }
114     case Property::FLOAT:
115     {
116
117       ret = ToString( value.Get<float>() );
118       break;
119     }
120     case Property::INTEGER:
121     {
122       ret = ToString( value.Get<int>() );
123       break;
124     }
125     case Property::UNSIGNED_INTEGER:
126     {
127       ret = ToString( value.Get<unsigned int>() );
128       break;
129     }
130     case Property::VECTOR2:
131     {
132       ret = ToString( value.Get<Vector2>() );
133       break;
134     }
135     case Property::VECTOR3:
136     {
137       ret = ToString( value.Get<Vector3>() );
138       break;
139     }
140     case Property::VECTOR4:
141     {
142       ret = ToString( value.Get<Vector4>() );
143       break;
144     }
145     case Property::MATRIX3:
146     {
147       ret = ToString( value.Get<Matrix3>() );
148       break;
149     }
150     case Property::MATRIX:
151     {
152       ret = ToString( value.Get<Matrix>() );
153       break;
154     }
155     case Property::RECTANGLE:
156     {
157       ret = ToString( value.Get< Rect<int> >() );
158       break;
159     }
160     case Property::ROTATION:
161     {
162       break;
163     }
164     case Property::STRING:
165     {
166       ret = value.Get<std::string>();
167       break;
168     }
169     case Property::ARRAY:
170     {
171       ret = std::string("Array Size=") + ToString( value.Get<Property::Array>().Size() );
172       break;
173     }
174     case Property::MAP:
175     {
176       ret = std::string("Map Size=") + ToString( value.Get<Property::Map>().Count() );
177       break;
178     }
179     case Property::TYPE_COUNT:
180     {
181       ret = "";
182       break;
183     }
184   }
185
186   return ret;
187 }
188 #endif // DEBUG_ENABLED
189
190 /*
191  * Recursively collects all stylesin a node (An array of style names).
192  *
193  * stylesCollection The set of styles from the json file (a json object of named styles)
194  * style The style array to begin the collection from
195  * styleList The style list to add nodes to apply
196  */
197 void CollectAllStyles( const TreeNode& stylesCollection, const TreeNode& style, TreeNodeList& styleList )
198 {
199   // style is an array of style names
200   if( TreeNode::ARRAY == style.GetType() )
201   {
202     for(TreeNode::ConstIterator iter = style.CBegin(); iter != style.CEnd(); ++iter)
203     {
204       if( OptionalString styleName = IsString( (*iter).second ) )
205       {
206         if( OptionalChild node = IsChild( stylesCollection, *styleName) )
207         {
208           styleList.push_back( &(*node) );
209
210           if( OptionalChild subStyle = IsChild( *node, KEYNAME_STYLES ) )
211           {
212             CollectAllStyles( stylesCollection, *subStyle, styleList );
213           }
214         }
215       }
216     }
217   }
218 }
219
220 struct QuitAction
221 {
222 public:
223   QuitAction( Builder& builder )
224   : mBuilder( builder )
225   {
226   }
227
228   void operator()(void)
229   {
230     mBuilder.EmitQuitSignal();
231   }
232
233 private:
234   Builder& mBuilder;
235 };
236
237 } // namespace anon
238
239 /*
240  * Sets the handle properties found in the tree node
241  */
242 void Builder::SetProperties( const TreeNode& node, Handle& handle, const Replacement& constant )
243 {
244   if( handle )
245   {
246     for( TreeNode::ConstIterator iter = node.CBegin(); iter != node.CEnd(); ++iter )
247     {
248       const TreeNode::KeyNodePair& keyChild = *iter;
249
250       std::string key( keyChild.first );
251
252       // ignore special fields; type,actors,signals,styles
253       if(key == KEYNAME_TYPE || key == KEYNAME_ACTORS || key == KEYNAME_SIGNALS || key == KEYNAME_STYLES)
254       {
255         continue;
256       }
257
258       // special field 'image' usually contains an json object description
259       // although sometimes refers to a framebuffer
260       if( 0 == keyChild.second.Size() )
261       {
262         if(key == "image")
263         {
264           ImageActor imageActor = ImageActor::DownCast(handle);
265           if(imageActor)
266           {
267             if( OptionalString s = constant.IsString( keyChild.second ) )
268             {
269               FrameBufferImage fb = GetFrameBufferImage(*s, constant);
270               if(fb)
271               {
272                 imageActor.SetImage( fb );
273               }
274             }
275           }
276         }
277       }
278
279       // special field 'effect' references the shader effect instances
280       if(key == "effect")
281       {
282         RenderableActor actor = RenderableActor::DownCast(handle);
283         if( actor )
284         {
285           OptionalString str = constant.IsString( keyChild.second );
286           if( str )
287           {
288             ShaderEffect effect = GetShaderEffect( *str, constant );
289             actor.SetShaderEffect(effect);
290           }
291         }
292         else
293         {
294           DALI_SCRIPT_WARNING("Could not find or set shader effect\n");
295         }
296
297         continue;
298       }
299
300       Handle propertyObject( handle );
301
302       Dali::Property::Index index = propertyObject.GetPropertyIndex( key );
303
304       if( Property::INVALID_INDEX == index )
305       {
306         RenderableActor actor = RenderableActor::DownCast(handle);
307         if( actor )
308         {
309           if( ShaderEffect effect = actor.GetShaderEffect() )
310           {
311             index = effect.GetPropertyIndex( key );
312             if(index != Property::INVALID_INDEX)
313             {
314               propertyObject = effect;
315             }
316           }
317         }
318       }
319
320       if( Property::INVALID_INDEX != index )
321       {
322         Property::Type type = propertyObject.GetPropertyType(index);
323
324         Property::Value value;
325         if( !SetPropertyFromNode( keyChild.second, type, value, constant ) )
326         {
327           // verbose as this might not be a problem
328           // eg parent-origin can be a string which is picked up later
329           DALI_SCRIPT_VERBOSE("Could not convert property:%s\n", key.c_str());
330         }
331         else
332         {
333           DALI_SCRIPT_VERBOSE("SetProperty '%s' Index=:%d Value Type=%d Value '%s'\n", key.c_str(), index, value.GetType(), PropertyValueToString(value).c_str() );
334
335           propertyObject.SetProperty( index, value );
336         }
337       }
338       else
339       {
340         DALI_SCRIPT_VERBOSE("SetProperty INVALID '%s' Index=:%d\n", key.c_str(), index);
341       }
342
343     } // for property nodes
344   }
345   else
346   {
347     DALI_SCRIPT_WARNING("Style applied to empty handle\n");
348   }
349 }
350
351 // Set properties from node on handle.
352 void Builder::ApplyProperties( const TreeNode& root, const TreeNode& node,
353                                Dali::Handle& handle, const Replacement& constant )
354 {
355   if( Actor actor = Actor::DownCast(handle) )
356   {
357     SetProperties( node, actor, constant );
358
359     if( actor )
360     {
361       SetupActor( node, actor, constant );
362
363       // add signals
364       QuitAction quitAction( *this );
365       SetupSignalAction( mSlotDelegate.GetConnectionTracker(), root, node, actor, quitAction, this );
366       SetupPropertyNotification( mSlotDelegate.GetConnectionTracker(), root, node, actor, quitAction, this );
367    }
368   }
369   else
370   {
371     SetProperties( node, handle, constant );
372   }
373 }
374
375 // Appling by style helper
376 // use FindChildByName() to apply properties referenced in KEYNAME_ACTORS in the node
377 void Builder::ApplyStylesByActor(  const TreeNode& root, const TreeNode& node,
378                                    Dali::Handle& handle, const Replacement& constant )
379 {
380   if( Dali::Actor actor = Dali::Actor::DownCast( handle ) )
381   {
382     if( const TreeNode* actors = node.GetChild( KEYNAME_ACTORS ) )
383     {
384       // in a style the actor subtree properties referenced by actor name
385       for( TreeConstIter iter = actors->CBegin(); iter != actors->CEnd(); ++iter )
386       {
387         Dali::Actor foundActor;
388
389         if( (*iter).first )
390         {
391           foundActor = actor.FindChildByName( (*iter).first );
392         }
393
394         if( !foundActor )
395         {
396           // debug log cannot find searched for actor
397 #if defined(DEBUG_ENABLED)
398           DALI_SCRIPT_VERBOSE("Cannot find actor in style application '%s'\n", (*iter).first);
399 #endif
400         }
401         else
402         {
403 #if defined(DEBUG_ENABLED)
404           DALI_SCRIPT_VERBOSE("Styles applied to actor '%s'\n", (*iter).first);
405 #endif
406           ApplyProperties( root, (*iter).second, foundActor, constant );
407         }
408       }
409     }
410   }
411 }
412
413
414 void Builder::ApplyAllStyleProperties( const TreeNode& root, const TreeNode& node,
415                                        Dali::Handle& handle, const Replacement& constant )
416 {
417   OptionalChild styles = IsChild(root, KEYNAME_STYLES);
418   OptionalChild style  = IsChild(node, KEYNAME_STYLES);
419
420   if( styles && style )
421   {
422     TreeNodeList additionalStyles;
423
424     CollectAllStyles( *styles, *style, additionalStyles );
425
426 #if defined(DEBUG_ENABLED)
427     for(TreeNode::ConstIterator iter = (*style).CBegin(); iter != (*style).CEnd(); ++iter)
428     {
429       if( OptionalString styleName = IsString( (*iter).second ) )
430       {
431         DALI_SCRIPT_VERBOSE("Style Applied '%s'\n", (*styleName).c_str());
432       }
433     }
434 #endif
435
436     // a style may have other styles, which has other styles etc so we apply in reverse by convention.
437     for(TreeNodeList::reverse_iterator iter = additionalStyles.rbegin(); iter != additionalStyles.rend(); ++iter)
438     {
439       ApplyProperties( root, *(*iter), handle, constant );
440
441       ApplyStylesByActor( root, *(*iter), handle, constant );
442     }
443   }
444
445   // applying given node last
446   ApplyProperties( root, node, handle, constant );
447
448   ApplyStylesByActor( root, node, handle, constant );
449
450 }
451
452
453 /*
454  * Create a dali type from a node.
455  * If parent given and an actor type was created then add it to the parent and
456  * recursively add nodes children.
457  */
458 BaseHandle Builder::DoCreate( const TreeNode& root, const TreeNode& node,
459                               Actor parent, const Replacement& replacements )
460 {
461   BaseHandle baseHandle;
462   TypeInfo typeInfo;
463   const TreeNode* templateNode = NULL;
464
465   if( OptionalString typeName = IsString(node, KEYNAME_TYPE) )
466   {
467     typeInfo = TypeRegistry::Get().GetTypeInfo( *typeName );
468
469     if( !typeInfo )
470     {
471       // a template name is also allowed inplace of the type name
472       OptionalChild templates = IsChild( root, KEYNAME_TEMPLATES);
473
474       if( templates )
475       {
476         if( OptionalChild isTemplate = IsChild( *templates, *typeName ) )
477         {
478           templateNode = &(*isTemplate);
479
480           if( OptionalString templateTypeName = IsString(*templateNode, KEYNAME_TYPE) )
481           {
482             typeInfo = TypeRegistry::Get().GetTypeInfo( *templateTypeName );
483           }
484         }
485       }
486     }
487   }
488
489   if(!typeInfo)
490   {
491     DALI_SCRIPT_WARNING("Cannot create Dali type from node '%s'\n", node.GetName());
492   }
493   else
494   {
495     baseHandle       = typeInfo.CreateInstance();
496     Handle handle    = Handle::DownCast(baseHandle);
497     Actor actor      = Actor::DownCast(handle);
498
499     if(handle)
500     {
501
502       DALI_SCRIPT_VERBOSE("Create:%s\n", typeInfo.GetName().c_str());
503
504 #if defined(DEBUG_ENABLED)
505       if(handle)
506       {
507         DALI_SCRIPT_VERBOSE("  Is Handle Object=%d\n", (long*)handle.GetObjectPtr());
508         DALI_SCRIPT_VERBOSE("  Is Handle Property Count=%d\n", handle.GetPropertyCount());
509       }
510
511       if(actor)
512       {
513         DALI_SCRIPT_VERBOSE("  Is Actor id=%d\n", actor.GetId());
514       }
515
516       Toolkit::Control control  = Toolkit::Control::DownCast(handle);
517       if(control)
518       {
519         DALI_SCRIPT_VERBOSE("  Is Control id=%d\n", actor.GetId());
520       }
521 #endif // DEBUG_ENABLED
522
523       if( templateNode )
524       {
525         ApplyProperties( root, *templateNode, handle, replacements );
526
527         if( OptionalChild actors = IsChild( *templateNode, KEYNAME_ACTORS ) )
528         {
529           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
530           {
531             DoCreate( root, (*iter).second, actor, replacements );
532           }
533         }
534       }
535
536       if( actor )
537       {
538         // add children of all the styles
539         if( OptionalChild actors = IsChild( node, KEYNAME_ACTORS ) )
540         {
541           for( TreeConstIter iter = (*actors).CBegin(); iter != (*actors).CEnd(); ++iter )
542           {
543             DoCreate( root, (*iter).second, actor, replacements );
544           }
545         }
546
547         // apply style on top as they need the children to exist
548         ApplyAllStyleProperties( root, node, actor, replacements );
549
550         // then add to parent
551         if( parent )
552         {
553           parent.Add( actor );
554         }
555       }
556       else
557       {
558         ApplyProperties( root, node, handle, replacements );
559       }
560     }
561     else
562     {
563       DALI_SCRIPT_WARNING("Cannot create handle from type '%s'\n", typeInfo.GetName().c_str());
564     }
565   }
566
567   return baseHandle;
568 }
569
570 void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replacement& constant )
571 {
572   const Stage& stage = Stage::GetCurrent();
573   Layer root  = stage.GetRootLayer();
574
575   if( OptionalString s = constant.IsString( IsChild(node, "source-actor") ) )
576   {
577     Actor actor = root.FindChildByName(*s);
578     if(actor)
579     {
580       task.SetSourceActor( actor );
581     }
582     else
583     {
584       DALI_SCRIPT_WARNING("Cannot find source actor on stage for render task called '%s'\n", (*s).c_str() );
585     }
586   }
587
588   if( OptionalString s = constant.IsString( IsChild(node, "camera-actor") ) )
589   {
590     CameraActor actor = CameraActor::DownCast( root.FindChildByName(*s) );
591     if(actor)
592     {
593       task.SetCameraActor( actor );
594     }
595     else
596     {
597       DALI_SCRIPT_WARNING("Cannot find camera actor on stage for render task called '%s'\n", (*s).c_str() );
598     }
599   }
600
601   if( OptionalString s = constant.IsString( IsChild(node, "target-frame-buffer") ) )
602   {
603     FrameBufferImage fb = GetFrameBufferImage( *s, constant );
604     if(fb)
605     {
606       task.SetTargetFrameBuffer( fb );
607     }
608     else
609     {
610       DALI_SCRIPT_WARNING("Cannot find target frame buffer '%s'\n", (*s).c_str() );
611     }
612   }
613
614   if( OptionalString s = constant.IsString( IsChild(node, "screen-to-frame-buffer-function") ) )
615   {
616     if("DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION" == *s)
617     {
618       task.SetScreenToFrameBufferFunction( RenderTask::DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION );
619     }
620     else if("FULLSCREEN_FRAMEBUFFER_FUNCTION" == *s)
621     {
622       task.SetScreenToFrameBufferFunction( RenderTask::FULLSCREEN_FRAMEBUFFER_FUNCTION );
623     }
624     else
625     {
626       DALI_SCRIPT_WARNING("todo");
627     }
628   }
629
630   // other setup is via the property system
631   SetProperties( node, task, constant ); // @ todo, remove 'source-actor', 'camera-actor'?
632
633 }
634
635 void Builder::CreateRenderTask( const std::string &name )
636 {
637   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
638
639   Replacement constant(mReplacementMap);
640
641   const Stage& stage = Stage::GetCurrent();
642
643   OptionalChild tasks = IsChild(*mParser.GetRoot(), "render-tasks");
644
645   if(tasks)
646   {
647     //
648     // Create the tasks from the current task as generally we want
649     // to setup task zero and onwards. Although this does overwrite
650     // the properties of the current task.
651     //
652     if( OptionalChild renderTask = IsChild(*tasks, name ) )
653     {
654       RenderTaskList list = stage.GetRenderTaskList();
655       unsigned int start = list.GetTaskCount();
656
657       RenderTask task;
658       if(0 == start)
659       {
660         // zero should have already been created by the stage so really
661         // this case should never happen
662         task = list.CreateTask();
663         start++;
664       }
665
666       TreeNode::ConstIterator iter = (*renderTask).CBegin();
667       task = list.GetTask( start - 1 );
668
669       SetupTask( task, (*iter).second, constant  );
670
671       ++iter;
672
673       for(; iter != (*renderTask).CEnd(); ++iter )
674       {
675         task = list.CreateTask();
676         SetupTask( task, (*iter).second, constant );
677       }
678     }
679   }
680 }
681
682 ShaderEffect Builder::GetShaderEffect( const std::string &name)
683 {
684   Replacement constant( mReplacementMap );
685   return GetShaderEffect( name, constant );
686 }
687
688 ShaderEffect Builder::GetShaderEffect( const std::string &name, const Replacement& constant )
689 {
690   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
691
692   ShaderEffect ret;
693
694   ShaderEffectLut::const_iterator iter( mShaderEffectLut.find( name ) );
695   if( iter != mShaderEffectLut.end() )
696   {
697     ret = iter->second;
698   }
699   else
700   {
701     if( OptionalChild effects = IsChild( *mParser.GetRoot(), "shader-effects") )
702     {
703       if( OptionalChild effect = IsChild( *effects, name ) )
704       {
705         Dali::Property::Value propertyMap(Property::MAP);
706         if( SetPropertyFromNode( *effect, Property::MAP, propertyMap, constant ) )
707         {
708           ret = Dali::Scripting::NewShaderEffect( propertyMap );
709           mShaderEffectLut[ name ] = ret;
710         }
711       }
712     }
713   }
714
715   return ret;
716 }
717
718 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name )
719 {
720   Replacement constant( mReplacementMap );
721   return GetFrameBufferImage(name, constant);
722 }
723
724 FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Replacement& constant )
725 {
726   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
727
728   FrameBufferImage ret;
729
730   ImageLut::const_iterator iter( mFrameBufferImageLut.find( name ) );
731   if( iter != mFrameBufferImageLut.end() )
732   {
733     ret = iter->second;
734   }
735   else
736   {
737     if( OptionalChild images = IsChild( *mParser.GetRoot(), "frame-buffer-images") )
738     {
739       if( OptionalChild image = IsChild( *images, name ) )
740       {
741         Dali::Property::Value propertyMap(Property::MAP);
742         if( SetPropertyFromNode( *image, Property::MAP, propertyMap, constant ) )
743         {
744           propertyMap.SetValue(KEYNAME_TYPE, Property::Value(std::string("FrameBufferImage")));
745           ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( propertyMap ) );
746           mFrameBufferImageLut[ name ] = ret;
747         }
748       }
749     }
750   }
751
752   return ret;
753 }
754
755 Path Builder::GetPath( const std::string& name )
756 {
757   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
758
759   Path ret;
760
761   PathLut::const_iterator iter( mPathLut.find( name ) );
762   if( iter != mPathLut.end() )
763   {
764     ret = iter->second;
765   }
766   else
767   {
768     if( OptionalChild paths = IsChild( *mParser.GetRoot(), "paths") )
769     {
770       if( OptionalChild path = IsChild( *paths, name ) )
771       {
772         //points property
773         if( OptionalChild pointsProperty = IsChild( *path, "points") )
774         {
775           Dali::Property::Value points(Property::ARRAY);
776           if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
777           {
778             ret = Path::New();
779             ret.SetProperty( Path::Property::POINTS, points);
780
781             //control-points property
782             if( OptionalChild pointsProperty = IsChild( *path, "control-points") )
783             {
784               Dali::Property::Value points(Property::ARRAY);
785               if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
786               {
787                 ret.SetProperty( Path::Property::CONTROL_POINTS, points);
788               }
789             }
790             else
791             {
792               //Curvature
793               float curvature(0.25f);
794               if( OptionalFloat pointsProperty = IsFloat( *path, "curvature") )
795               {
796                 curvature = *pointsProperty;
797               }
798               ret.GenerateControlPoints(curvature);
799             }
800
801             //Add the new path to the hash table for paths
802             mPathLut[ name ] = ret;
803           }
804         }
805         else
806         {
807           //Interpolation points not specified
808           DALI_SCRIPT_WARNING("Interpolation points not specified for path '%s'\n", name.c_str() );
809         }
810       }
811
812     }
813   }
814
815   return ret;
816 }
817
818 PathConstrainer Builder::GetPathConstrainer( const std::string& name )
819 {
820   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
821
822   //Search the pathConstrainer in the LUT
823   size_t count( mPathConstrainerLut.size() );
824   for( size_t i(0); i!=count; ++i )
825   {
826     if( mPathConstrainerLut[i].name == name )
827     {
828       //PathConstrainer has already been created
829       return mPathConstrainerLut[i].pathConstrainer;
830     }
831   }
832
833   //Create a new PathConstrainer
834   PathConstrainer ret;
835   if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
836   {
837     if( OptionalChild pathConstrainer = IsChild( *constrainers, name ) )
838     {
839       OptionalString constrainerType(IsString(IsChild(*pathConstrainer, "type")));
840       if(!constrainerType)
841       {
842         DALI_SCRIPT_WARNING("Constrainer type not specified for constrainer '%s'\n", name.c_str() );
843       }
844       else if( *constrainerType == "PathConstrainer")
845       {
846         //points property
847         if( OptionalChild pointsProperty = IsChild( *pathConstrainer, "points") )
848         {
849           Dali::Property::Value points(Property::ARRAY);
850           if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
851           {
852             ret = PathConstrainer::New();
853             ret.SetProperty( PathConstrainer::Property::POINTS, points);
854
855             //control-points property
856             if( OptionalChild pointsProperty = IsChild( *pathConstrainer, "control-points") )
857             {
858               Dali::Property::Value points(Property::ARRAY);
859               if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
860               {
861                 ret.SetProperty( PathConstrainer::Property::CONTROL_POINTS, points);
862               }
863
864               //Forward vector
865               OptionalVector3 forward( IsVector3( IsChild(*pathConstrainer, "forward" ) ) );
866               if( forward )
867               {
868                 ret.SetProperty( PathConstrainer::Property::FORWARD, *forward);
869               }
870
871               //Add the new constrainer to the vector of PathConstrainer
872               PathConstrainerEntry entry = {name,ret};
873               mPathConstrainerLut.push_back( entry );
874             }
875             else
876             {
877               //Control points not specified
878               DALI_SCRIPT_WARNING("Control points not specified for pathConstrainer '%s'\n", name.c_str() );
879             }
880           }
881         }
882         else
883         {
884           //Interpolation points not specified
885           DALI_SCRIPT_WARNING("Interpolation points not specified for pathConstrainer '%s'\n", name.c_str() );
886         }
887       }
888       else
889       {
890         DALI_SCRIPT_WARNING("Constrainer '%s' is not a PathConstrainer\n", name.c_str() );
891       }
892     }
893   }
894
895   return ret;
896 }
897
898 bool Builder::IsPathConstrainer( const std::string& name )
899 {
900   size_t count( mPathConstrainerLut.size() );
901   for( size_t i(0); i!=count; ++i )
902   {
903     if( mPathConstrainerLut[i].name == name )
904     {
905       return true;
906     }
907   }
908
909   if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
910   {
911     if( OptionalChild constrainer = IsChild( *constrainers, name ) )
912     {
913       OptionalString constrainerType(IsString(IsChild(*constrainer, "type")));
914       if(!constrainerType)
915       {
916         return false;
917       }
918       else
919       {
920          return *constrainerType == "PathConstrainer";
921       }
922     }
923   }
924   return false;
925 }
926
927 Dali::LinearConstrainer Builder::GetLinearConstrainer( const std::string& name )
928 {
929   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
930
931   //Search the LinearConstrainer in the LUT
932   size_t count( mLinearConstrainerLut.size() );
933   for( size_t i(0); i!=count; ++i )
934   {
935     if( mLinearConstrainerLut[i].name == name )
936     {
937       //LinearConstrainer has already been created
938       return mLinearConstrainerLut[i].linearConstrainer;
939     }
940   }
941
942   //Create a new LinearConstrainer
943   LinearConstrainer ret;
944   if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
945   {
946     if( OptionalChild linearConstrainer = IsChild( *constrainers, name ) )
947     {
948       OptionalString constrainerType(IsString(IsChild(*linearConstrainer, "type")));
949       if(!constrainerType)
950       {
951         DALI_SCRIPT_WARNING("Constrainer type not specified for constrainer '%s'\n", name.c_str() );
952       }
953       else if( *constrainerType == "LinearConstrainer")
954       {
955         //points property
956         if( OptionalChild pointsProperty = IsChild( *linearConstrainer, "value") )
957         {
958           Dali::Property::Value points(Property::ARRAY);
959           if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
960           {
961             ret = Dali::LinearConstrainer::New();
962             ret.SetProperty( LinearConstrainer::Property::VALUE, points);
963
964             //control-points property
965             if( OptionalChild pointsProperty = IsChild( *linearConstrainer, "progress") )
966             {
967               Dali::Property::Value points(Property::ARRAY);
968               if( SetPropertyFromNode( *pointsProperty, Property::ARRAY, points ) )
969               {
970                 ret.SetProperty( LinearConstrainer::Property::PROGRESS, points);
971               }
972             }
973             //Add the new constrainer to vector of LinearConstrainer
974             LinearConstrainerEntry entry = {name,ret};
975             mLinearConstrainerLut.push_back( entry );
976           }
977         }
978         else
979         {
980           //Interpolation points not specified
981           DALI_SCRIPT_WARNING("Values not specified for LinearConstrainer '%s'\n", name.c_str() );
982         }
983       }
984       else
985       {
986         DALI_SCRIPT_WARNING("Constrainer '%s' is not a LinearConstrainer\n", name.c_str() );
987       }
988     }
989   }
990
991   return ret;
992 }
993
994 bool Builder::IsLinearConstrainer( const std::string& name )
995 {
996   //Search the LinearConstrainer in the LUT
997   size_t count( mLinearConstrainerLut.size() );
998   for( size_t i(0); i!=count; ++i )
999   {
1000     if( mLinearConstrainerLut[i].name == name )
1001     {
1002       return true;
1003     }
1004   }
1005
1006   if( OptionalChild constrainers = IsChild( *mParser.GetRoot(), "constrainers") )
1007   {
1008     if( OptionalChild constrainer = IsChild( *constrainers, name ) )
1009     {
1010       OptionalString constrainerType(IsString(IsChild(*constrainer, "type")));
1011       if(!constrainerType)
1012       {
1013         return false;
1014       }
1015       else
1016       {
1017          return *constrainerType == "LinearConstrainer";
1018       }
1019     }
1020   }
1021   return false;
1022 }
1023
1024 Toolkit::Builder::BuilderSignalType& Builder::QuitSignal()
1025 {
1026   return mQuitSignal;
1027 }
1028
1029 void Builder::EmitQuitSignal()
1030 {
1031   mQuitSignal.Emit();
1032 }
1033
1034 void Builder::AddActors( Actor toActor )
1035 {
1036   // 'stage' is the default/by convention section to add from
1037   AddActors( "stage", toActor );
1038 }
1039
1040 void Builder::AddActors( const std::string &sectionName, Actor toActor )
1041 {
1042   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1043
1044   Property::Map overrideMap;
1045   Replacement replacements(overrideMap, mReplacementMap);
1046
1047   OptionalChild add = IsChild(*mParser.GetRoot(), sectionName);
1048
1049   if( add )
1050   {
1051     for( TreeNode::ConstIterator iter = (*add).CBegin(); iter != (*add).CEnd(); ++iter )
1052     {
1053       // empty actor adds directly to the stage
1054       BaseHandle baseHandle = DoCreate( *mParser.GetRoot(), (*iter).second, Actor(), replacements );
1055       Actor actor = Actor::DownCast(baseHandle);
1056       if(actor)
1057       {
1058         toActor.Add( actor );
1059       }
1060     }
1061
1062     // if were adding the 'stage' section then also check for a render task called stage
1063     // to add automatically
1064     if( "stage" == sectionName )
1065     {
1066       if( OptionalChild renderTasks = IsChild(*mParser.GetRoot(), "render-tasks") )
1067       {
1068         if( OptionalChild tasks = IsChild(*renderTasks, "stage") )
1069         {
1070           CreateRenderTask( "stage" );
1071         }
1072       }
1073     }
1074   }
1075 }
1076
1077 Animation Builder::CreateAnimation( const std::string& animationName, const Replacement& replacement, Dali::Actor sourceActor )
1078 {
1079   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1080
1081   Animation anim;
1082
1083   if( OptionalChild animations = IsChild(*mParser.GetRoot(), "animations") )
1084   {
1085     if( OptionalChild animation = IsChild(*animations, animationName) )
1086     {
1087       anim = Dali::Toolkit::Internal::CreateAnimation( *animation, replacement, sourceActor, this );
1088     }
1089     else
1090     {
1091       DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed\n", animationName.c_str() );
1092     }
1093   }
1094   else
1095   {
1096     DALI_SCRIPT_WARNING( "Request for Animation called '%s' failed (no animation section)\n", animationName.c_str() );
1097   }
1098
1099   return anim;
1100 }
1101
1102 Animation Builder::CreateAnimation( const std::string& animationName, const Property::Map& map, Dali::Actor sourceActor )
1103 {
1104   Replacement replacement(map, mReplacementMap);
1105   return CreateAnimation( animationName, replacement, sourceActor);
1106 }
1107
1108 Animation Builder::CreateAnimation( const std::string& animationName, const Property::Map& map )
1109 {
1110   Replacement replacement(map, mReplacementMap);
1111   return CreateAnimation( animationName, replacement, Stage::GetCurrent().GetRootLayer() );
1112 }
1113
1114 Animation Builder::CreateAnimation( const std::string& animationName, Dali::Actor sourceActor )
1115 {
1116   Replacement replacement( mReplacementMap );
1117
1118   return CreateAnimation( animationName, replacement, sourceActor );
1119 }
1120
1121 Animation Builder::CreateAnimation( const std::string& animationName )
1122 {
1123   Replacement replacement( mReplacementMap );
1124
1125   return CreateAnimation( animationName, replacement, Dali::Stage::GetCurrent().GetRootLayer() );
1126 }
1127
1128 void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::UIFormat format )
1129 {
1130   // parser to get constants and includes only
1131   Dali::Toolkit::JsonParser parser = Dali::Toolkit::JsonParser::New();
1132
1133   if( !parser.Parse( data ) )
1134   {
1135     DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
1136                       parser.GetErrorLineNumber(),
1137                       parser.GetErrorColumn(),
1138                       parser.GetErrorDescription().c_str() );
1139
1140     DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
1141
1142   }
1143   else
1144   {
1145     // load constant map (allows the user to override the constants in the json after loading)
1146     LoadConstants( *parser.GetRoot(), mReplacementMap );
1147
1148     // merge includes
1149     if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) )
1150     {
1151       Replacement replacer( mReplacementMap );
1152
1153       for(TreeNode::ConstIterator iter = (*includes).CBegin(); iter != (*includes).CEnd(); ++iter)
1154       {
1155         OptionalString filename = replacer.IsString( (*iter).second );
1156
1157         if( filename )
1158         {
1159 #if defined(DEBUG_ENABLED)
1160           DALI_SCRIPT_VERBOSE("Loading Include '%s'\n", (*filename).c_str());
1161 #endif
1162           LoadFromString( GetFileContents(*filename) );
1163         }
1164       }
1165     }
1166
1167     if( !mParser.Parse( data ) )
1168     {
1169       DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
1170                         mParser.GetErrorLineNumber(),
1171                         mParser.GetErrorColumn(),
1172                         mParser.GetErrorDescription().c_str() );
1173
1174       DALI_ASSERT_ALWAYS(!"Cannot parse JSON");
1175     }
1176   }
1177
1178   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
1179
1180 }
1181
1182 void Builder::AddConstants( const Property::Map& map )
1183 {
1184   mReplacementMap.Merge( map );
1185 }
1186
1187 void Builder::AddConstant( const std::string& key, const Property::Value& value )
1188 {
1189   mReplacementMap[key] = value;
1190 }
1191
1192 const Property::Map& Builder::GetConstants() const
1193 {
1194   return mReplacementMap;
1195 }
1196
1197 const Property::Value& Builder::GetConstant( const std::string& key ) const
1198 {
1199   Property::Value* match = mReplacementMap.Find( key );
1200   if( match )
1201   {
1202     return (*match);
1203   }
1204   else
1205   {
1206     static Property::Value invalid;
1207     return invalid;
1208   }
1209 }
1210
1211 void Builder::LoadConstants( const TreeNode& root, Property::Map& intoMap )
1212 {
1213   Replacement replacer(intoMap);
1214
1215   if( OptionalChild constants = IsChild(root, "constants") )
1216   {
1217     for(TreeNode::ConstIterator iter = (*constants).CBegin();
1218         iter != (*constants).CEnd(); ++iter)
1219     {
1220       Dali::Property::Value property;
1221       if( (*iter).second.GetName() )
1222       {
1223 #if defined(DEBUG_ENABLED)
1224         DALI_SCRIPT_VERBOSE("Constant set from json '%s'\n", (*iter).second.GetName());
1225 #endif
1226         if( SetPropertyFromNode( (*iter).second, property, replacer ) )
1227         {
1228           intoMap[ (*iter).second.GetName() ] = property;
1229         }
1230         else
1231         {
1232           DALI_SCRIPT_WARNING("Cannot convert property for constant %s\n",
1233                               (*iter).second.GetName() == NULL ? "no name?" : (*iter).second.GetName());
1234         }
1235       }
1236     }
1237   }
1238
1239 #if defined(DEBUG_ENABLED)
1240   Property::Value* iter = intoMap.Find( "CONFIG_SCRIPT_LOG_LEVEL" );
1241   if( iter && iter->GetType() == Property::STRING )
1242   {
1243     std::string logLevel( iter->Get< std::string >() );
1244     if( logLevel == "NoLogging" )
1245     {
1246       gFilterScript->SetLogLevel( Integration::Log::NoLogging );
1247     }
1248     else if( logLevel == "Concise" )
1249     {
1250       gFilterScript->SetLogLevel( Integration::Log::Concise );
1251     }
1252     else if( logLevel == "General" )
1253     {
1254       gFilterScript->SetLogLevel( Integration::Log::General );
1255     }
1256     else if( logLevel == "Verbose" )
1257     {
1258       gFilterScript->SetLogLevel( Integration::Log::Verbose );
1259     }
1260   }
1261 #endif
1262
1263 }
1264
1265 bool Builder::ApplyStyle( const std::string& styleName, Handle& handle )
1266 {
1267   Replacement replacer( mReplacementMap );
1268   return ApplyStyle( styleName, handle, replacer );
1269 }
1270
1271 bool Builder::ApplyStyle( const std::string& styleName, Handle& handle, const Replacement& replacement )
1272 {
1273   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1274
1275   OptionalChild styles = IsChild( *mParser.GetRoot(), KEYNAME_STYLES );
1276   OptionalChild style  = IsChild( *styles, styleName );
1277
1278   if( styles && style )
1279   {
1280     ApplyAllStyleProperties( *mParser.GetRoot(), *style, handle, replacement );
1281     return true;
1282   }
1283   else
1284   {
1285     return false;
1286   }
1287 }
1288
1289 BaseHandle Builder::Create( const std::string& templateName, const Property::Map& map )
1290 {
1291   Replacement replacement( map, mReplacementMap );
1292   return Create( templateName, replacement );
1293 }
1294
1295 BaseHandle Builder::Create( const std::string& templateName, const Replacement& constant )
1296 {
1297   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
1298
1299   BaseHandle baseHandle;
1300
1301   OptionalChild templates = IsChild(*mParser.GetRoot(), KEYNAME_TEMPLATES);
1302
1303   if( !templates )
1304   {
1305     DALI_SCRIPT_WARNING("No template section found to CreateFromTemplate\n");
1306   }
1307   else
1308   {
1309     OptionalChild childTemplate = IsChild(*templates, templateName);
1310     if(!childTemplate)
1311     {
1312       DALI_SCRIPT_WARNING("Template '%s' does not exist in template section\n", templateName.c_str());
1313     }
1314     else
1315     {
1316       OptionalString type = constant.IsString( IsChild(*childTemplate, KEYNAME_TYPE) );
1317
1318       if(!type)
1319       {
1320         DALI_SCRIPT_WARNING("Cannot create template '%s' as template section is missing 'type'\n", templateName.c_str());
1321       }
1322       else
1323       {
1324         baseHandle = DoCreate( *mParser.GetRoot(), *childTemplate, Actor(), constant );
1325       }
1326     }
1327   }
1328
1329   return baseHandle;
1330 }
1331
1332 BaseHandle Builder::CreateFromJson( const std::string& json )
1333 {
1334   BaseHandle ret;
1335
1336   // merge in new template, hoping no one else has one named '@temp@'
1337   std::string newTemplate =
1338     std::string("{\"templates\":{\"@temp@\":") +                      \
1339     json +                                                            \
1340     std::string("}}");
1341
1342   if( mParser.Parse(newTemplate) )
1343   {
1344     Replacement replacement( mReplacementMap );
1345     ret = Create( "@temp@", replacement );
1346   }
1347
1348   return ret;
1349 }
1350
1351 bool Builder::ApplyFromJson(  Handle& handle, const std::string& json )
1352 {
1353   bool ret = false;
1354
1355   // merge new style, hoping no one else has one named '@temp@'
1356   std::string newStyle =
1357     std::string("{\"styles\":{\"@temp@\":") +                           \
1358     json +                                                              \
1359     std::string("}}");
1360
1361   if( mParser.Parse(newStyle) )
1362   {
1363     Replacement replacement( mReplacementMap );
1364     ret = ApplyStyle( "@temp@", handle, replacement );
1365   }
1366
1367   return ret;
1368 }
1369
1370
1371 BaseHandle Builder::Create( const std::string& templateName )
1372 {
1373   Replacement replacement( mReplacementMap );
1374   return Create( templateName, replacement );
1375 }
1376
1377 Builder::Builder()
1378 : mSlotDelegate( this )
1379 {
1380   mParser = Dali::Toolkit::JsonParser::New();
1381 }
1382
1383 Builder::~Builder()
1384 {
1385 }
1386
1387 } // namespace Internal
1388
1389 } // namespace Toolkit
1390
1391 } // namespace Dali