3 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include <dali/internal/network/common/automation.h>
26 #include <dali/public-api/dali-core.h>
27 #include <dali/integration-api/debug.h>
30 namespace // un-named namespace
33 const unsigned int MAX_SET_PROPERTY_STRING_LENGTH = 256; ///< maximum length of a set property command
35 class JsonPropertyValue
38 JsonPropertyValue( const std::string& str )
40 std::size_t strLength = str.length();
42 mString.reserve( strLength );
43 for( std::size_t i = 0; i < strLength; ++i )
45 const char c = str[i];
46 if( (c != '[') && c != ']')
48 mString.push_back( c );
53 std::string GetString() const
57 float GetFloat() const
59 return atof( mString.c_str() );
63 return atoi( mString.c_str() );
67 return (GetInt() != 0);
70 Dali::Vector2 GetVector2()
74 int count = sscanf( mString.c_str(),"%f,%f",&vec2.x,&vec2.y );
77 DALI_LOG_ERROR("Bad format\n");
82 Dali::Vector3 GetVector3()
86 int count = sscanf( mString.c_str(),"%f,%f,%f",&vec3.x,&vec3.y,&vec3.z );
89 DALI_LOG_ERROR("Bad format\n");
94 Dali::Vector4 GetVector4()
98 int count = sscanf( mString.c_str(),"%f,%f,%f,%f", &vec4.x, &vec4.y, &vec4.z, &vec4.w );
101 DALI_LOG_ERROR("Bad format\n");
111 void SetProperty( Dali::Handle handle, int propertyId, JsonPropertyValue& propertyValue )
113 Dali::Property::Type type = handle.GetPropertyType( propertyId );
116 case Dali::Property::FLOAT:
118 float val = propertyValue.GetFloat();
119 handle.SetProperty( propertyId, Dali::Property::Value( val ) );
122 case Dali::Property::INTEGER:
124 int val = propertyValue.GetInt();
125 handle.SetProperty( propertyId, Dali::Property::Value( val ) );
128 case Dali::Property::BOOLEAN:
130 bool val = propertyValue.GetBoolean();
131 handle.SetProperty( propertyId, Dali::Property::Value( val ) );
134 case Dali::Property::STRING:
136 std::string str = propertyValue.GetString();
137 handle.SetProperty( propertyId, Dali::Property::Value( str ) );
140 case Dali::Property::VECTOR2:
142 Dali::Vector2 val = propertyValue.GetVector2();
143 handle.SetProperty( propertyId, Dali::Property::Value( val ) );
146 case Dali::Property::VECTOR3:
148 Dali::Vector3 val = propertyValue.GetVector3();
149 handle.SetProperty( propertyId, Dali::Property::Value( val ) );
152 case Dali::Property::VECTOR4:
154 Dali::Vector4 val = propertyValue.GetVector4();
155 handle.SetProperty( propertyId, Dali::Property::Value( val ) );
165 int SetProperties( const std::string& setPropertyMessage )
167 std::istringstream iss( setPropertyMessage );
169 getline( iss, token, '|' ); // swallow command name
170 while( getline( iss, token, '|' ) )
172 std::string actorId, propName, propValue;
173 if( token.compare( "---" ) != 0 )
175 std::istringstream propss( token );
176 getline( propss, actorId, ';' );
177 getline( propss, propName, ';' );
178 getline( propss, propValue );
180 Dali::Actor root = Dali::Stage::GetCurrent().GetRootLayer();
181 int id = atoi( actorId.c_str() );
182 Dali::Actor a = root.FindChildById( id );
185 // lookup by name for custom properties
186 int propId = a.GetPropertyIndex( propName );
189 JsonPropertyValue pv( propValue );
190 SetProperty( a, propId, pv );
201 }; // un-named namespace
203 inline std::string Quote( const std::string& in )
205 return (std::string( "\"" ) + in + std::string( "\"" ));
209 std::string ToString( T i )
211 std::stringstream ss;
219 std::string GetPropertyValueString( Dali::Handle handle, int propertyIndex )
221 std::ostringstream valueStream;
222 Dali::Property::Value value = handle.GetProperty( propertyIndex );
223 valueStream << value;
224 std::string valueString = valueStream.str();
226 if( value.GetType() == Dali::Property::STRING )
228 // Escape the string (to ensure valid json)
229 // Write out quotes, escapes and control characters using unicode syntax \uXXXX
230 std::ostringstream escapedValue;
231 for( std::string::iterator c = valueString.begin() ; c != valueString.end(); ++c )
235 escapedValue << "\\\"";
237 else if( *c == '\\' )
239 escapedValue << "\\\\";
241 else if( '\x00' <= *c && *c <= '\x1f' )
243 escapedValue << "\\u" << std::hex << std::setw(4) << std::setfill('0') << int(*c);
251 valueString = escapedValue.str();
256 // currently rotations are output in Euler format ( may change)
257 void AppendPropertyNameAndValue( Dali::Handle handle, int propertyIndex, std::ostringstream& outputStream)
259 // get the property name and the value as a string
260 std::string propertyName( handle.GetPropertyName( propertyIndex ) );
262 // Apply quotes around the property name
263 outputStream << "\"" << propertyName << "\"" << ",";
265 // Convert value to a string
266 std::string valueString = GetPropertyValueString( handle, propertyIndex );
268 outputStream << "\"" << valueString << "\"";
271 void AppendRendererPropertyNameAndValue( Dali::Renderer renderer, int rendererIndex, const std::string& name, std::ostringstream& outputStream)
273 outputStream << ",[\"renderer[" << rendererIndex << "]." << name << "\"" << ",";
274 std::string valueString = GetPropertyValueString( renderer, renderer.GetPropertyIndex( name ) );
275 outputStream << "\"" << valueString << "\"]";
278 bool ExcludeProperty( int propIndex )
280 return (propIndex == Dali::Actor::Property::NAME ||
282 // all of these are repeat properties of values in vectors....
283 // We don't really need these in the UI
284 propIndex == Dali::Actor::Property::ANCHOR_POINT_X || propIndex == Dali::Actor::Property::ANCHOR_POINT_Y || propIndex == Dali::Actor::Property::ANCHOR_POINT_Z || propIndex == Dali::Actor::Property::PARENT_ORIGIN_X
285 || propIndex == Dali::Actor::Property::PARENT_ORIGIN_Y || propIndex == Dali::Actor::Property::PARENT_ORIGIN_Z || propIndex == Dali::Actor::Property::COLOR_RED || propIndex == Dali::Actor::Property::COLOR_GREEN
286 || propIndex == Dali::Actor::Property::COLOR_BLUE || propIndex == Dali::Actor::Property::COLOR_ALPHA|| propIndex == Dali::Actor::Property::POSITION_X || propIndex == Dali::Actor::Property::POSITION_Y
287 || propIndex == Dali::Actor::Property::POSITION_Z|| propIndex == Dali::Actor::Property::SIZE_WIDTH|| propIndex == Dali::Actor::Property::SIZE_HEIGHT || propIndex == Dali::Actor::Property::SCALE_X || propIndex == Dali::Actor::Property::SCALE_Y
288 || propIndex == Dali::Actor::Property::SCALE_Z || propIndex == Dali::Actor::Property::SIZE_DEPTH);
291 std::string DumpJson( Dali::Actor actor, int level )
293 // All the information about this actor
294 std::ostringstream msg;
295 msg << "{ " << Quote( "Name" ) << " : " << Quote( actor.GetName() ) << ", " << Quote( "level" ) << " : " << level << ", " << Quote( "id" ) << " : " << actor.GetId() << ", " << Quote( "IsVisible" )
296 << " : " << actor.IsVisible() << ", " << Quote( "IsSensitive" ) << " : " << actor.IsSensitive();
298 msg << ", " << Quote( "properties" ) << ": [ ";
300 Dali::Property::IndexContainer indices;
301 actor.GetPropertyIndices( indices );
303 Dali::Property::IndexContainer::Iterator iter = indices.Begin();
305 for( ; iter != indices.End() ; iter++ )
308 if( !ExcludeProperty( i ) )
310 if( numCustom++ != 0 )
316 AppendPropertyNameAndValue( actor, i,msg );
321 if( actor.GetRendererCount() > 0 )
323 for( unsigned int i=0; i<actor.GetRendererCount(); ++i )
325 auto renderer = actor.GetRendererAt( i );
326 AppendRendererPropertyNameAndValue( renderer, i, "offset", msg );
327 AppendRendererPropertyNameAndValue( renderer, i, "size", msg );
328 AppendRendererPropertyNameAndValue( renderer, i, "offsetSizeMode", msg );
329 AppendRendererPropertyNameAndValue( renderer, i, "origin", msg );
330 AppendRendererPropertyNameAndValue( renderer, i, "anchorPoint", msg );
335 msg << ", " << Quote( "children" ) << " : [ ";
337 // Recursively dump all the children as well
338 for( unsigned int i = 0 ; i < actor.GetChildCount() ; ++i )
344 msg << DumpJson( actor.GetChildAt( i ), level + 1 );
351 std::string GetActorTree()
353 Dali::Actor actor = Dali::Stage::GetCurrent().GetRootLayer();
354 std::string str = DumpJson( actor, 0 );
369 void SetProperty( const std::string& message )
371 // check the set property length is within range
372 if( message.length() > MAX_SET_PROPERTY_STRING_LENGTH )
374 DALI_LOG_ERROR("SetProperty message length too long, size = %ul\n", message.length());
378 SetProperties( message );
381 void DumpScene( unsigned int clientId, ClientSendDataInterface* sendData )
384 std::string json = GetActorTree();
385 int length = json.length();
386 snprintf( buf, 32, "%d\n", length );
387 std::string header( buf );
389 sendData->SendData( json.c_str(), json.length(), clientId );
392 } // namespace Automation
394 } // namespace Internal
396 } // namespace Adaptor