2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include "property-value-wrapper.h"
21 #include <dali/integration-api/debug.h>
22 #include <dali/public-api/object/property-array.h>
26 #include <dali-wrapper.h>
39 Dali::Property::Type propertyType;
40 BaseWrappedObject::Type wrappedType;
43 * lookup table to convert between dali property types and wrapped types
44 * Wrapped types includes actors / timers / render tasks, hence we can't just
45 * use the dali property types to encode what a wrapped pointer contains
47 const WrapTypeInfo WrapTypeInfoLookup[]=
49 { Dali::Property::VECTOR2, BaseWrappedObject::VECTOR2 },
50 { Dali::Property::VECTOR3, BaseWrappedObject::VECTOR3 },
51 { Dali::Property::VECTOR4, BaseWrappedObject::VECTOR4 },
52 { Dali::Property::RECTANGLE, BaseWrappedObject::RECTANGLE },
53 { Dali::Property::ROTATION, BaseWrappedObject::ROTATION },
54 { Dali::Property::MATRIX, BaseWrappedObject::MATRIX },
55 { Dali::Property::MATRIX3, BaseWrappedObject::MATRIX3 },
59 const unsigned int WrapTypeLookupCount = sizeof( WrapTypeInfoLookup ) / sizeof( WrapTypeInfo );
61 BaseWrappedObject::Type GetWrappedType( Dali::Property::Type type )
63 for( unsigned int i = 0; i < WrapTypeLookupCount; ++i)
65 if( WrapTypeInfoLookup[ i ].propertyType == type )
67 return WrapTypeInfoLookup[ i ].wrappedType;
70 DALI_LOG_ERROR("GetWrappedType failed \n");
71 return BaseWrappedObject::UNKNOWN;
74 // Templates for setting members on propertys, like, x,y,z on a vector
75 template <typename T, typename S>
76 void SetX( Dali::Property::Value &value, S& v)
78 // to set a property value, we need to read into a temporary
79 // then assign it back.
80 // E.g. Vector2 temp = value.Get<Vector2>();
83 T tmp( value.Get<T>() );
88 template <typename T, typename S>
89 void SetY( Dali::Property::Value &value, S& v)
91 T tmp = value.Get<T>();
96 template <typename T, typename S>
97 void SetZ( Dali::Property::Value &value, S& v)
99 T tmp = value.Get<T>();
104 template <typename T, typename S>
105 void SetW( Dali::Property::Value &value, S& v)
107 T tmp = value.Get<T>();
111 template <typename T, typename S>
112 void SetWidth( Dali::Property::Value &value, S& v)
114 T tmp = value.Get<T>();
119 template <typename T, typename S>
120 void SetHeight( Dali::Property::Value &value, S& v)
122 T tmp = value.Get<T>();
127 v8::Handle< v8::Value > GetV8ValueFrom( v8::Isolate* isolate,
128 const Dali::Property::Value& value,
129 const std::string& field)
131 v8::EscapableHandleScope handleScope( isolate );
132 v8::Local<v8::Value> ret;
134 Dali::Property::Type type = value.GetType();
135 std::string objectType="Unknown type";
137 // simple property values are handled by the actor wrapper so we just handle property values with sub fields
140 case Dali::Property::VECTOR2:
142 objectType = "Vector2";
144 if( field == "x" || field == "width" )
146 Dali::Vector2 v2 = value.Get<Dali::Vector2>();
147 ret = v8::Number::New( isolate, v2.x);
149 else if(field == "y" || field == "height")
151 Dali::Vector2 v2 = value.Get<Dali::Vector2>();
152 ret = v8::Number::New( isolate, v2.y);
157 case Dali::Property::VECTOR3:
159 objectType = "Vector3";
161 if(field == "x" || field == "width" || field == "r")
163 Dali::Vector3 v3 = value.Get<Dali::Vector3>();
164 ret = v8::Number::New( isolate, v3.x);
166 else if(field == "y" || field == "height" || field == "g")
168 Dali::Vector3 v3 = value.Get<Dali::Vector3>();
169 ret = v8::Number::New( isolate, v3.y);
171 else if(field == "z" || field == "depth" || field == "b")
173 Dali::Vector3 v3 = value.Get<Dali::Vector3>();
174 ret = v8::Number::New( isolate, v3.z);
178 case Dali::Property::VECTOR4:
180 objectType = "vector4";
182 if(field == "x" || field == "s" || field == "r")
184 Dali::Vector4 v4 = value.Get<Dali::Vector4>();
185 ret = v8::Number::New( isolate, v4.x);
187 else if(field == "y" || field == "g" || field == "t")
189 Dali::Vector4 v4 = value.Get<Dali::Vector4>();
190 ret = v8::Number::New( isolate, v4.y);
192 else if(field == "z" || field == "r" || field == "b")
194 Dali::Vector4 v4 = value.Get<Dali::Vector4>();
195 ret = v8::Number::New( isolate, v4.z);
197 else if(field == "w" || field == "a" || field == "q")
199 Dali::Vector4 v4 = value.Get<Dali::Vector4>();
200 ret = v8::Number::New( isolate, v4.w);
205 case Dali::Property::ROTATION:
207 objectType = "rotation";
211 Dali::Vector4 v4 = value.Get<Dali::Quaternion>().EulerAngles();
212 ret = v8::Number::New( isolate, v4.z);
214 else if(field == "pitch")
216 Dali::Vector4 v4 = value.Get<Dali::Quaternion>().EulerAngles();
217 ret = v8::Number::New( isolate, v4.x);
219 else if(field == "yaw")
221 Dali::Vector4 v4 = value.Get<Dali::Quaternion>().EulerAngles();
222 ret = v8::Number::New( isolate, v4.y);
225 else if(field == "axis")
229 value.Get<Dali::Quaternion>().ToAxisAngle(axis, angle);
230 ret = PropertyValueWrapper::WrapDaliProperty( isolate , Dali::Property::Value( axis ) );
232 else if(field == "angle")
236 value.Get<Dali::Quaternion>().ToAxisAngle(axis, angle);
237 ret = PropertyValueWrapper::WrapDaliProperty( isolate , Dali::Property::Value( angle ) );
241 case Dali::Property::RECTANGLE:
243 objectType = "rectangle";
247 Dali::Rect<int> r = value.Get<Dali::Rect<int> >();
248 ret = v8::Number::New( isolate, r.x);
250 else if(field == "y")
252 Dali::Rect<int> r = value.Get<Dali::Rect<int> >();
253 ret = v8::Number::New( isolate, r.y);
255 else if(field == "width")
257 Dali::Rect<int> r = value.Get<Dali::Rect<int> >();
258 ret = v8::Number::New( isolate, r.width);
260 else if(field == "height")
262 Dali::Rect<int> r = value.Get<Dali::Rect<int> >();
263 ret = v8::Number::New( isolate, r.height);
270 // will trigger a type error as ret.IsEmpty() == true
278 DALI_SCRIPT_EXCEPTION( isolate, "Cannot get property with field " + objectType+ ":" + field );
280 return handleScope.Escape(ret);
285 * Setting a field on a property, e.g. Position.x = 5 or Rect.Width = 100
286 * The only property field that supports a struct is rotation.axis
288 void SetFromV8Value(v8::Isolate* isolate,
289 Dali::Property::Value& value,
290 const std::string& field,
291 v8::Local<v8::Value> v8Value )
293 v8::EscapableHandleScope handleScope( isolate );
295 Dali::Property::Type type = value.GetType();
300 // all are numbers at the moment
301 if( v8Value->IsNumber() )
303 asFloat = static_cast<float>(v8Value->NumberValue());
304 asInt = static_cast<int>(asFloat);
308 // if the v8 value isn't a number, then then only Dali object we support is a Vector3 part of a rotation
309 if( ! (type == Dali::Property::ROTATION && field == "axis") )
311 DALI_SCRIPT_EXCEPTION(isolate,std::string("Cannot set property with field (value is not a number):") + field);
316 // simple property values are handled by the actor wrapper so we just handle property values with sub fields
319 case Dali::Property::VECTOR2:
321 if(field == "x" || field == "width")
323 SetX<Dali::Vector2>(value, asFloat);
325 else if(field == "y" || field == "height")
327 SetY<Dali::Vector2>(value, asFloat);
331 DALI_SCRIPT_EXCEPTION(isolate, std::string("Cannot set property with field (unknown type):") + field);
336 case Dali::Property::VECTOR3:
338 if(field == "x" || field == "width" || field == "r")
340 SetX<Dali::Vector3>(value, asFloat);
342 else if(field == "y" || field == "height" || field == "g")
344 SetY<Dali::Vector3>(value, asFloat);
346 else if(field == "z" || field == "depth" || field == "b")
348 SetZ<Dali::Vector3>(value, asFloat);
352 DALI_SCRIPT_EXCEPTION(isolate, std::string("Cannot set property with field (unknown type):") + field);
357 case Dali::Property::VECTOR4:
359 if(field == "x" || field == "s" || field == "r")
361 SetX<Dali::Vector4>(value, asFloat);
363 else if(field == "y" || field == "g" || field == "t")
365 SetY<Dali::Vector4>(value, asFloat);
367 else if(field == "z" || field == "r" || field == "b")
369 SetZ<Dali::Vector4>(value, asFloat);
371 else if(field == "w" || field == "a" || field == "q")
373 SetW<Dali::Vector4>(value, asFloat);
377 DALI_SCRIPT_EXCEPTION( isolate, std::string("Cannot set property with field (unknown type):") + field);
382 case Dali::Property::ROTATION:
386 Dali::Vector4 v4 = value.Get<Dali::Quaternion>().EulerAngles();
388 value = Dali::Quaternion( Radian(Degree(v4.x)), Radian(Degree(v4.y)), Radian(Degree(v4.z)) );
390 else if(field == "pitch")
392 Dali::Vector4 v4 = value.Get<Dali::Quaternion>().EulerAngles();
394 value = Dali::Quaternion( Radian(Degree(v4.x)), Radian(Degree(v4.y)), Radian(Degree(v4.z)) );
396 else if(field == "yaw")
398 Dali::Vector4 v4 = value.Get<Dali::Quaternion>().EulerAngles();
400 value = Dali::Quaternion( Radian(Degree(v4.x)), Radian(Degree(v4.y)), Radian(Degree(v4.z)) );
402 else if(field == "axis")
406 value.Get<Dali::Quaternion>().ToAxisAngle(axis, angle);
408 if( v8Value->IsObject() )
410 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast( v8Value );
412 PropertyValueWrapper* wrapper = PropertyValueWrapper::Unwrap( isolate, object );
413 Dali::Property::Value v3 = wrapper->GetValue();
415 if(v3.GetType() == Dali::Property::VECTOR3)
417 value = Dali::Quaternion(angle, v3.Get<Dali::Vector3>());
421 DALI_SCRIPT_EXCEPTION( isolate, "Axis expects a Vector3:");
427 else if(field == "angle")
431 value.Get<Dali::Quaternion>().ToAxisAngle( axis, angle );
432 value = Dali::Quaternion( Degree( asFloat ), axis );
436 DALI_SCRIPT_EXCEPTION( isolate, std::string("Cannot set property with field (unknown type):") + field);
441 case Dali::Property::RECTANGLE:
445 SetX<Dali::Rect<int> >(value, asInt);
447 else if(field == "y")
449 SetY<Dali::Rect<int> >(value, asInt);
451 else if(field == "width")
453 SetWidth<Dali::Rect<int> >(value, asInt);
455 else if(field == "height")
457 SetHeight<Dali::Rect<int> >(value, asInt);
461 DALI_SCRIPT_EXCEPTION( isolate, std::string("Cannot set property with field (unknown type):") + field);
468 DALI_SCRIPT_EXCEPTION( isolate, std::string("Cannot set property with field (unknown type):") + field);
478 bool IsPrimitive( const Dali::Property::Value &value )
480 switch( value.GetType() )
482 case Dali::Property::BOOLEAN:
483 case Dali::Property::INTEGER:
484 case Dali::Property::STRING:
485 case Dali::Property::FLOAT:
495 v8::Local<v8::Object> CreateJavaScriptPrimitive( v8::Isolate* isolate, const Dali::Property::Value &value )
497 v8::EscapableHandleScope handleScope( isolate );
499 v8::Local<v8::Value> v8Value;
501 switch( value.GetType() )
503 case Dali::Property::FLOAT:
505 v8Value = v8::Number::New( isolate, value.Get<float>() );
508 case Dali::Property::BOOLEAN:
510 v8Value = v8::Boolean::New( isolate, value.Get<bool>());
513 case Dali::Property::INTEGER:
515 v8Value = v8::Integer::New( isolate, value.Get<int>());
518 case Dali::Property::STRING:
520 std::string string = value.Get< std::string >();
521 v8Value = v8::String::NewFromUtf8( isolate, string.c_str());
526 DALI_LOG_ERROR("Primitive mismatch \n");
531 v8::Local<v8::Object> ret;
533 if( v8Value->IsObject() )
535 ret = v8Value->ToObject();
538 return handleScope.Escape( ret );
542 } // un-named namespace
546 Dali::Property::Value PropertyValueWrapper::VectorOrMatrixFromV8Array( v8::Isolate* isolate, const v8::Local<v8::Value>& v8Value)
548 v8::EscapableHandleScope handleScope( isolate );
550 Dali::Property::Value ret;
552 if( !v8Value->IsArray() )
556 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast( v8Value );//v8::Array::Cast( *v8Value);
557 uint32_t len = array->Length();
558 float out[16] = {0.f, 0.f, 0.f, 0.f,0.f, 0.f, 0.f, 0.f,0.f, 0.f, 0.f, 0.f,0.f, 0.f, 0.f, 0.f};
559 const unsigned int size = sizeof(out) / sizeof(float);
560 for( uint32_t i=0; i < (len > size? size:len); ++i)
562 v8::Handle<v8::Value> entry = array->Get( i);// v8::Integer::New( isolate, i));
563 if( V8Utils::IsNumberPrimitiveOrObject( entry ) )
565 out[i] = V8Utils::GetNumberValue( isolate, entry );
566 //printf("entry is a number %d , entry is a int %f \n",(int)i , out[i] );
571 ret = Dali::Matrix( out );
575 ret = Dali::Matrix3( out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7],out[8] );
579 ret = Dali::Vector4(out[0], out[1], out[2], out[3]);
583 ret = Dali::Vector3(out[0], out[1], out[2]);
587 ret = Dali::Vector2(out[0], out[1]);
597 Dali::Property::Value PropertyValueWrapper::ArrayFromV8Array( v8::Isolate* isolate, const v8::Local<v8::Value>& v8Value)
599 v8::EscapableHandleScope handleScope( isolate );
601 if( !v8Value->IsArray() )
603 return Dali::Property::Value();
606 //Cast v8::Value to v8::Array
607 v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast( v8Value );
608 uint32_t elementCount = v8Array->Length();
609 Dali::Property::Array data;
610 data.Reserve( elementCount );
612 for( uint32_t i(0); i<elementCount; ++i )
614 //Get Property::Value for each element in the array
615 data.PushBack( V8Utils::GetPropertyValueFromObject( bFound, isolate, v8Array->Get(i) ) );
618 //return the Property::Value
619 return Dali::Property::Value( data );
622 v8::Persistent<v8::ObjectTemplate> PropertyValueWrapper::mTemplatePrimitive;
625 PropertyValueWrapper::~PropertyValueWrapper()
630 PropertyValueWrapper::PropertyValueWrapper( const Dali::Property::Value& value, GarbageCollectorInterface& gc )
631 : BaseWrappedObject( GetWrappedType( value.GetType() ), gc ),
636 Dali::Property::Value PropertyValueWrapper::ExtractPropertyValue( v8::Isolate* isolate, v8::Local< v8::Value> v8Value, Dali::Property::Type type)
638 v8::HandleScope handleScope( isolate);
640 Dali::Property::Value daliPropertyValue;
642 // check if it's a dali object (vector, rect etc)
643 if( v8Value->IsObject() )
645 v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast(v8Value);
646 if( object->InternalFieldCount() == BaseWrappedObject::FIELD_COUNT )
648 if( BaseWrappedObject::IsWrappedType( isolate, object, GetWrappedType(type) ) )
650 PropertyValueWrapper* propertyWrapper = Unwrap( isolate, object );
651 return propertyWrapper->GetValue();
656 // check if it's a javascript Array
657 Dali::Property::Value array = VectorOrMatrixFromV8Array( isolate, v8Value );
661 case Dali::Property::BOOLEAN:
663 if( V8Utils::IsBooleanPrimitiveOrObject( v8Value ) )
665 daliPropertyValue = Dali::Property::Value( V8Utils::GetBooleanValue( isolate, v8Value));
669 case Dali::Property::FLOAT:
671 if( V8Utils::IsNumberPrimitiveOrObject( v8Value ) )
673 daliPropertyValue = Dali::Property::Value( V8Utils::GetNumberValue( isolate, v8Value) );
678 case Dali::Property::INTEGER: // todo is it wise to distinguish int from float in javascript?!
680 if( v8Value->IsInt32() )
682 daliPropertyValue = Dali::Property::Value( v8Value->Int32Value() ) ;//static_cast<int>( V8Utils::GetNumberValue( isolate, v8Value) ));
684 else if( V8Utils::IsStringPrimitiveOrObject( v8Value) ) // Take string as value for properties that internally convert the string to an enum
686 daliPropertyValue = Dali::Property::Value( V8Utils::GetStringValue( isolate, v8Value) );
690 case Dali::Property::STRING:
692 if( V8Utils::IsStringPrimitiveOrObject( v8Value) )
694 daliPropertyValue = Dali::Property::Value( V8Utils::GetStringValue( isolate, v8Value) );
700 case Dali::Property::VECTOR2:
702 if( array.GetType() == Dali::Property::VECTOR2 )
704 daliPropertyValue = array;
708 case Dali::Property::VECTOR3:
710 if( array.GetType() == Dali::Property::VECTOR3)
712 daliPropertyValue = array;
716 case Dali::Property::VECTOR4:
719 if( array.GetType() == Dali::Property::VECTOR4)
721 daliPropertyValue = array;
725 case Dali::Property::RECTANGLE:
727 if( array.GetType() == Dali::Property::VECTOR4)
729 Vector4 vec4( array.Get<Vector4>());
730 daliPropertyValue = Property::Value(Rect<int>( vec4.x,vec4.y, vec4.z, vec4.w ));
734 case Dali::Property::ROTATION:
736 if( array.GetType() == Dali::Property::VECTOR4)
738 // v4 treated as axis angle
739 Dali::Vector4 v = array.Get<Dali::Vector4>();
740 daliPropertyValue = Dali::AngleAxis(Dali::Degree(v[0]), Dali::Vector3(v[1], v[2], v[3]));
742 else if(array.GetType() == Dali::Property::VECTOR3)
744 // v3 treated as euler in degrees
745 Dali::Vector3 v = array.Get<Dali::Vector3>();
746 daliPropertyValue = Dali::Quaternion( Radian(Degree(v[0])), Radian(Degree(v[1])), Radian(Degree(v[2])) );
750 case Dali::Property::MATRIX:
752 Dali::Matrix mat = array.Get<Dali::Matrix>();
753 daliPropertyValue = mat;
756 case Dali::Property::MATRIX3:
758 Dali::Matrix3 mat = array.Get<Dali::Matrix3>();
759 daliPropertyValue = mat;
762 case Dali::Property::ARRAY:
764 daliPropertyValue = ArrayFromV8Array( isolate, v8Value );
767 case Dali::Property::MAP:
769 if( v8Value->IsObject() )
771 v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast(v8Value);
772 Dali::Property::Map propertyMap = V8Utils::GetPropertyMapFromObject(isolate, object);
773 daliPropertyValue = Dali::Property::Value( propertyMap );
775 else if( V8Utils::IsStringPrimitiveOrObject( v8Value) )
777 // There are special cases where a property with property map type can accept a string value,
778 // so we do the additional check here.
779 daliPropertyValue = Dali::Property::Value( V8Utils::GetStringValue( isolate, v8Value) );
784 case Dali::Property::NONE:
791 return daliPropertyValue;
794 Dali::Property::Value PropertyValueWrapper::ExtractPropertyValue( v8::Isolate* isolate, v8::Local< v8::Value> v8Value)
796 v8::HandleScope handleScope( isolate);
798 Dali::Property::Value daliPropertyValue;
800 // Check if it's a javascript Array
801 Dali::Property::Value array = VectorOrMatrixFromV8Array( isolate, v8Value );
803 if( V8Utils::IsBooleanPrimitiveOrObject( v8Value ) )
805 daliPropertyValue = Dali::Property::Value( V8Utils::GetBooleanValue( isolate, v8Value));
807 else if( V8Utils::IsNumberPrimitiveOrObject( v8Value ) )
809 daliPropertyValue = Dali::Property::Value( V8Utils::GetNumberValue( isolate, v8Value) );
811 else if( v8Value->IsInt32() )
813 daliPropertyValue = Dali::Property::Value( v8Value->Int32Value() ) ;
815 else if( V8Utils::IsStringPrimitiveOrObject( v8Value) )
817 daliPropertyValue = Dali::Property::Value( V8Utils::GetStringValue( isolate, v8Value) );
819 else if( array.GetType() == Dali::Property::VECTOR2
820 || array.GetType() == Dali::Property::VECTOR3
821 || array.GetType() == Dali::Property::VECTOR4 )
823 daliPropertyValue = array;
825 else if( array.GetType() == Dali::Property::MATRIX )
827 Dali::Matrix mat = array.Get<Dali::Matrix>();
828 daliPropertyValue = mat;
830 else if( array.GetType() == Dali::Property::MATRIX3 )
832 Dali::Matrix3 mat = array.Get<Dali::Matrix3>();
833 daliPropertyValue = mat;
835 else if( array.GetType() == Dali::Property::ARRAY )
837 daliPropertyValue = ArrayFromV8Array( isolate, v8Value );
839 else if( v8Value->IsObject() )
841 // Assume this is a property map
842 v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast(v8Value);
843 Dali::Property::Map propertyMap = V8Utils::GetPropertyMapFromObject(isolate, object);
844 daliPropertyValue = Dali::Property::Value( propertyMap );
847 return daliPropertyValue;
850 void PropertyValueWrapper::NewRotation( const v8::FunctionCallbackInfo< v8::Value >& args)
852 v8::Isolate* isolate = args.GetIsolate();
853 v8::HandleScope handleScope( isolate);
855 if(!args.IsConstructCall())
857 DALI_SCRIPT_EXCEPTION( isolate, "Rotation constructor called without 'new'");
860 v8::Local<v8::Object > object;
862 float v[4] = {0.f,0.f,0.f,0.f};
864 bool foundAllArguments(false);
865 V8Utils::ReadFloatArguments( foundAllArguments, v, 4, args, 0.f );
867 int length = args.Length();
869 // if length = 4 create AngleAxis, else create Quaternion
873 const Dali::AngleAxis axis( Degree( v[0] ), Vector3(v[1], v[2], v[3]) );
874 object = WrapDaliProperty( isolate, Dali::Property::Value( axis ) );
876 else if( length > 2 )
878 object = WrapDaliProperty( isolate, Dali::Quaternion( Degree(v[0]), Degree(v[1]), Degree(v[2]) ) );
882 const Dali::Quaternion quaternion( Dali::Quaternion( Dali::ANGLE_0, Dali::Vector3::YAXIS));
883 object = WrapDaliProperty( isolate, quaternion );
886 args.GetReturnValue().Set( object );
890 void PropertyValueWrapper::NewMatrix( const v8::FunctionCallbackInfo< v8::Value >& args )
892 v8::Isolate* isolate = args.GetIsolate();
893 v8::HandleScope handleScope( isolate);
895 if(!args.IsConstructCall())
897 DALI_SCRIPT_EXCEPTION( isolate, "Rotation constructor called without 'new'");
900 v8::Local<v8::Object > object;
902 // we're constructing either a 4x4 Dali::Matrix or a 3x3 Dali::Matrix
903 // we're expecting an array of floats
904 // 4x4 = m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33
905 // 3x3 or m00, m01, m02, m10, m11, m12,m20, m21, m22, m30, m31, m32,
906 bool foundAllArguments( false );
908 if( args.Length() == 16 )
911 V8Utils::ReadFloatArguments( foundAllArguments, v, 16, args, 0.f );
912 if(! foundAllArguments )
914 DALI_SCRIPT_EXCEPTION( isolate, "invalid Matrix parameters");
917 Dali::Matrix matrix( v[0] );
918 object = WrapDaliProperty( isolate , Dali::Property::Value( matrix ) );
920 else if ( args.Length() == 9 )
923 V8Utils::ReadFloatArguments( foundAllArguments, v, 9, args, 0.f );
924 if(! foundAllArguments )
926 DALI_SCRIPT_EXCEPTION( isolate, "invalid Matrix parameters");
929 Dali::Matrix3 matrix( v[0], v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8] );
930 object = WrapDaliProperty( isolate , Dali::Property::Value( matrix ) );
932 args.GetReturnValue().Set( object );
937 v8::Handle<v8::ObjectTemplate> PropertyValueWrapper::MakeDaliPropertyTemplate( v8::Isolate* isolate )
939 v8::EscapableHandleScope handleScope( isolate );
941 v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New();
943 objTemplate->SetInternalFieldCount( BaseWrappedObject::FIELD_COUNT );
945 // property handle intercepts property getters and setters
946 objTemplate->SetNamedPropertyHandler( PropertyGet, PropertySet);
948 return handleScope.Escape( objTemplate );
952 v8::Handle<v8::Object> PropertyValueWrapper::WrapDaliProperty(v8::Isolate* isolate, const Dali::Property::Value &value)
954 v8::EscapableHandleScope handleScope( isolate );
956 // Simple Dali properties (ints, strings, bools etc) are stored as JavaScript primitives (v8::Boolean ...)
957 // more complex properties (Vectors, Rectangles...) are wrapped by a JavaScript object
958 if( IsPrimitive( value ))
960 return handleScope.Escape( CreateJavaScriptPrimitive( isolate, value) );
963 // This will wrap a Dali structure (Vector, Rect, Matrix etc) inside a JavaScript object.
965 v8::Local<v8::ObjectTemplate> objectTemplate;
967 if(PropertyValueWrapper::mTemplatePrimitive.IsEmpty() )
969 objectTemplate = MakeDaliPropertyTemplate( isolate );
970 PropertyValueWrapper::mTemplatePrimitive.Reset( isolate, objectTemplate);
974 // get the object template
975 objectTemplate = v8::Local<v8::ObjectTemplate>::New( isolate, PropertyValueWrapper::mTemplatePrimitive );
978 v8::Local<v8::Object> localObject = objectTemplate->NewInstance();
980 PropertyValueWrapper* pointer = new PropertyValueWrapper( value, Dali::V8Plugin::DaliWrapper::Get().GetDaliGarbageCollector() );
982 // assign the JavaScript object to the wrapper.
983 // This also stores Dali object, in an internal field inside the JavaScript object.
984 pointer->SetJavascriptObject( isolate, localObject );
986 return handleScope.Escape( localObject );
990 // Utility function that extracts the C++ map pointer from a wrapper
993 PropertyValueWrapper* PropertyValueWrapper::Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj)
995 v8::HandleScope handleScope( isolate );
997 v8::Local<v8::External> field = v8::Local<v8::External>::Cast( obj->GetInternalField(0) );
998 void* ptr = field->Value();
999 return static_cast< PropertyValueWrapper *>(ptr);
1002 void PropertyValueWrapper::PropertyGet( v8::Local<v8::String> propertyName,
1003 const v8::PropertyCallbackInfo<v8::Value>& info)
1005 v8::Isolate* isolate = info.GetIsolate();
1006 v8::HandleScope handleScope( isolate );
1008 std::string name = V8Utils::v8StringToStdString( propertyName );
1010 // unwrap the object
1011 PropertyValueWrapper* propWrapper = Unwrap( isolate, info.This() );
1013 v8::Local<v8::Value> value = GetV8ValueFrom( isolate, propWrapper->mValue, name );
1015 info.GetReturnValue().Set( value );
1018 void PropertyValueWrapper::PropertySet( v8::Local<v8::String> propertyName,
1019 v8::Local<v8::Value> javaScriptValue,
1020 const v8::PropertyCallbackInfo<v8::Value>& info)
1022 v8::Isolate* isolate = info.GetIsolate();
1023 v8::HandleScope handleScope( isolate );
1025 std::string name = V8Utils::v8StringToStdString( propertyName );
1027 PropertyValueWrapper* propWrapper = Unwrap( isolate, info.This() );
1029 SetFromV8Value( isolate, propWrapper->mValue, name, javaScriptValue );
1034 } // namespace V8Plugin