(Builder) Added Constants that can be used by Custom shaders
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / builder-impl.cpp
index e4ef639..88c51b6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/public-api/object/type-info.h>
 #include <dali/public-api/object/type-registry.h>
 #include <dali/public-api/render-tasks/render-task-list.h>
+#include <dali/public-api/rendering/shader.h>
 #include <dali/public-api/signals/functor-delegate.h>
+#include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/scripting/scripting.h>
 #include <dali/integration-api/debug.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control.h>
+#include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
 #include <dali-toolkit/devel-api/builder/json-parser.h>
 
 #include <dali-toolkit/internal/builder/builder-declarations.h>
@@ -154,13 +157,16 @@ Builder::Builder()
 {
   mParser = Dali::Toolkit::JsonParser::New();
 
-  Property::Map defaultDirs;
-  defaultDirs[ TOKEN_STRING(DALI_IMAGE_DIR) ]       = DALI_IMAGE_DIR;
-  defaultDirs[ TOKEN_STRING(DALI_SOUND_DIR) ]       = DALI_SOUND_DIR;
-  defaultDirs[ TOKEN_STRING(DALI_STYLE_DIR) ]       = DALI_STYLE_DIR;
-  defaultDirs[ TOKEN_STRING(DALI_STYLE_IMAGE_DIR) ] = DALI_STYLE_IMAGE_DIR;
+  Property::Map defaultConstants;
+  defaultConstants[TOKEN_STRING(DALI_IMAGE_DIR)]              = AssetManager::GetDaliImagePath();
+  defaultConstants[TOKEN_STRING(DALI_SOUND_DIR)]              = AssetManager::GetDaliSoundPath();
+  defaultConstants[TOKEN_STRING(DALI_STYLE_DIR)]              = AssetManager::GetDaliStylePath();
+  defaultConstants[TOKEN_STRING(DALI_STYLE_IMAGE_DIR)]        = AssetManager::GetDaliStyleImagePath();
+  defaultConstants[TOKEN_STRING(DALI_SHADER_VERSION_PREFIX)]  = Shader::GetShaderVersionPrefix();
+  defaultConstants[TOKEN_STRING(DALI_VERTEX_SHADER_PREFIX)]   = Shader::GetVertexShaderPrefix();
+  defaultConstants[TOKEN_STRING(DALI_FRAGMENT_SHADER_PREFIX)] = Shader::GetFragmentShaderPrefix();
 
-  AddConstants( defaultDirs );
+  AddConstants(defaultConstants);
 }
 
 void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::UIFormat format )
@@ -181,7 +187,8 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U
   {
     // load constant map (allows the user to override the constants in the json after loading)
     LoadConstants( *parser.GetRoot(), mReplacementMap );
-
+    // load configuration map
+    LoadConfiguration( *parser.GetRoot(), mConfigurationMap );
     // merge includes
     if( OptionalChild includes = IsChild(*parser.GetRoot(), KEYNAME_INCLUDES) )
     {
@@ -201,7 +208,12 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U
       }
     }
 
-    if( !mParser.Parse( data ) )
+    if( mParser.Parse( data ) )
+    {
+      // Drop the styles and get them to be rebuilt against the new parse tree as required.
+      mStyles.Clear();
+    }
+    else
     {
       DALI_LOG_WARNING( "JSON Parse Error:%d:%d:'%s'\n",
                         mParser.GetErrorLineNumber(),
@@ -212,8 +224,8 @@ void Builder::LoadFromString( std::string const& data, Dali::Toolkit::Builder::U
     }
   }
 
-  DUMP_PARSE_TREE(parser); // This macro only writes out if DEBUG is enabled and the "DUMP_TREE" constant is defined in the stylesheet.
-  DUMP_TEST_MAPPINGS(parser);
+  DUMP_PARSE_TREE(mParser); // This macro only writes out if DEBUG is enabled and the "DUMP_TREE" constant is defined in the stylesheet.
+  DUMP_TEST_MAPPINGS(mParser);
 
   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Cannot parse JSON");
 }
@@ -228,6 +240,11 @@ void Builder::AddConstant( const std::string& key, const Property::Value& value
   mReplacementMap[key] = value;
 }
 
+const Property::Map& Builder::GetConfigurations() const
+{
+  return mConfigurationMap;
+}
+
 const Property::Map& Builder::GetConstants() const
 {
   return mReplacementMap;
@@ -447,48 +464,6 @@ void Builder::CreateRenderTask( const std::string &name )
   }
 }
 
-FrameBufferImage Builder::GetFrameBufferImage( const std::string &name )
-{
-  Replacement constant( mReplacementMap );
-  return GetFrameBufferImage(name, constant);
-}
-
-FrameBufferImage Builder::GetFrameBufferImage( const std::string &name, const Replacement& constant )
-{
-  DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
-
-  FrameBufferImage ret;
-
-  ImageLut::const_iterator iter( mFrameBufferImageLut.find( name ) );
-  if( iter != mFrameBufferImageLut.end() )
-  {
-    ret = iter->second;
-  }
-  else
-  {
-    if( OptionalChild images = IsChild( *mParser.GetRoot(), "frameBufferImages") )
-    {
-      if( OptionalChild image = IsChild( *images, name ) )
-      {
-        Dali::Property::Value property(Property::MAP);
-        if( DeterminePropertyFromNode( *image, Property::MAP, property, constant ) )
-        {
-          Property::Map* map = property.GetMap();
-
-          if( map )
-          {
-            (*map)[ KEYNAME_TYPE ] = Property::Value(std::string("FrameBufferImage") );
-            ret = FrameBufferImage::DownCast( Dali::Scripting::NewImage( property ) );
-            mFrameBufferImageLut[ name ] = ret;
-          }
-        }
-      }
-    }
-  }
-
-  return ret;
-}
-
 Path Builder::GetPath( const std::string& name )
 {
   DALI_ASSERT_ALWAYS(mParser.GetRoot() && "Builder script not loaded");
@@ -773,6 +748,80 @@ Builder::~Builder()
 {
 }
 
+void Builder::LoadConfiguration( const TreeNode& root, Property::Map& intoMap )
+{
+  Replacement replacer(intoMap);
+
+  if( OptionalChild constants = IsChild(root, "config") )
+  {
+    for(TreeNode::ConstIterator iter = (*constants).CBegin();
+        iter != (*constants).CEnd(); ++iter)
+    {
+      Dali::Property::Value property;
+      if( (*iter).second.GetName() )
+      {
+        DeterminePropertyFromNode( (*iter).second, property, replacer );
+
+        // If config is string, find constant and replace it to original value.
+        if( (*iter).second.GetType() == TreeNode::STRING )
+        {
+          std::string stringConfigValue;
+          if( property.Get( stringConfigValue ) )
+          {
+            std::size_t pos = 0;
+
+            while( pos < stringConfigValue.size() )
+            {
+              // If we can't find "{","}" pair in stringConfigValue, will out loop.
+              std::size_t leftPos = stringConfigValue.find( "{", pos );
+              if( leftPos != std::string::npos )
+              {
+                std::size_t rightPos = stringConfigValue.find( "}", pos+1 );
+
+                if( rightPos != std::string::npos )
+                {
+                  // If we find "{","}" pair but can't find matched constant
+                  // try to find other "{","}" pair after current left position.
+                  pos = leftPos+1;
+
+                  for( uint32_t i = 0; i < mReplacementMap.Count() ; i++ )
+                  {
+                    Property::Key constant = mReplacementMap.GetKeyAt(i);
+
+                    // Compare string which is between "{" and "}" with constant string
+                    // If they are same, change string in stringConfigValue to mapped constant value.
+                    if ( 0 == stringConfigValue.compare( leftPos+1, rightPos-leftPos-1, constant.stringKey ) )
+                    {
+                      std::string replaceString;
+                      mReplacementMap.GetValue(i).Get( replaceString );
+
+                      stringConfigValue.replace( leftPos, rightPos-leftPos+1, replaceString );
+                      pos = leftPos + replaceString.size();
+                      break;
+                    }
+                  }
+                }
+                else
+                {
+                  // If we cannot find constant in const value, will out loop.
+                  pos = stringConfigValue.size();
+                }
+              }
+              else
+              {
+                // If we cannot find constant in const value, will out loop.
+                pos = stringConfigValue.size();
+              }
+            }
+            property = Property::Value( stringConfigValue );
+          }
+        }
+        intoMap[ (*iter).second.GetName() ] = property;
+      }
+    }
+  }
+}
+
 void Builder::LoadConstants( const TreeNode& root, Property::Map& intoMap )
 {
   Replacement replacer(intoMap);
@@ -941,13 +990,13 @@ BaseHandle Builder::DoCreate( const TreeNode& root, const TreeNode& node,
 
       if(actor)
       {
-        DALI_SCRIPT_VERBOSE("  Is Actor id=%d\n", actor.GetId());
+        DALI_SCRIPT_VERBOSE("  Is Actor id=%d\n", actor.GetProperty< int >( Actor::Property::ID ));
       }
 
       Toolkit::Control control  = Toolkit::Control::DownCast(handle);
       if(control)
       {
-        DALI_SCRIPT_VERBOSE("  Is Control id=%d\n", actor.GetId());
+        DALI_SCRIPT_VERBOSE("  Is Control id=%d\n", actor.GetProperty< int >( Actor::Property::ID ));
       }
 #endif // DEBUG_ENABLED
 
@@ -1029,19 +1078,6 @@ void Builder::SetupTask( RenderTask& task, const TreeNode& node, const Replaceme
     }
   }
 
-  if( OptionalString s = constant.IsString( IsChild(node, "targetFrameBuffer") ) )
-  {
-    FrameBufferImage fb = GetFrameBufferImage( *s, constant );
-    if(fb)
-    {
-      task.SetTargetFrameBuffer( fb );
-    }
-    else
-    {
-      DALI_SCRIPT_WARNING("Cannot find target frame buffer '%s'\n", (*s).c_str() );
-    }
-  }
-
   if( OptionalString s = constant.IsString( IsChild(node, "screenToFrameBufferFunction") ) )
   {
     if("DEFAULT_SCREEN_TO_FRAMEBUFFER_FUNCTION" == *s)
@@ -1213,7 +1249,11 @@ void Builder::RecordStyle( StylePtr           style,
           }
           else
           {
-            style->visuals.Add(visual.first, *property.GetMap());
+            Property::Map* map = property.GetMap();
+            if( map )
+            {
+              style->visuals.Add( visual.first, *map );
+            }
           }
         }
       }