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.
19 #include "handle-wrapper.h"
26 #include <shared/base-wrapped-object.h>
27 #include <shared/object-template-helper.h>
28 #include <object/property-value-wrapper.h>
36 namespace // un-named name space
40 * Contains a list of all functions that can be called
42 const ApiFunction HandleFunctionTable[]=
44 { "RegisterAnimatableProperty", HandleWrapper::RegisterAnimatableProperty },
45 { "RegisterCustomProperty", HandleWrapper::RegisterCustomProperty },
48 const unsigned int HandleFunctionTableCount = sizeof(HandleFunctionTable)/sizeof(HandleFunctionTable[0]);
55 HandleWrapper::HandleWrapper( BaseWrappedObject::Type type,
57 GarbageCollectorInterface& gc ) :
58 BaseWrappedObject( type, gc ),
63 HandleWrapper::~HandleWrapper()
67 HandleWrapper* HandleWrapper::Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj)
69 v8::HandleScope handleScope( isolate );
71 v8::Local<v8::External> field = v8::Local<v8::External>::Cast( obj->GetInternalField(0) );
72 void* ptr = field->Value();
73 return static_cast< HandleWrapper *>(ptr);
76 // may have to do this IsUpper to intercept function calls or as function?
77 void HandleWrapper::PropertyGet( v8::Local<v8::String> propertyName,
78 const v8::PropertyCallbackInfo<v8::Value>& info)
80 v8::Isolate* isolate = info.GetIsolate();
81 v8::HandleScope handleScope( isolate );
83 // get the property name
84 std::string name = V8Utils::v8StringToStdString( propertyName );
86 if( std::isupper( name[0] ))
92 HandleWrapper* handleWrapper = Unwrap( isolate, info.This() );
93 Handle handle = handleWrapper->mHandle;
95 // get the property index
96 Dali::Property::Index index = handle.GetPropertyIndex( name );
98 if(index != Dali::Property::INVALID_INDEX)
100 Dali::Property::Value value = handle.GetProperty(index);
102 // Simple Dali properties (ints, strings, bools etc) are stored as JavaScript primitives (v8::Boolean ...)
103 // more complex properties (Vectors, Rectangles...) are wrapped by a JavaScript object
104 v8::Local<v8::Object> ret = PropertyValueWrapper::WrapDaliProperty( isolate, value );
106 info.GetReturnValue().Set( ret );
110 // std::string error="Invalid property Get for "+name + "\n";
111 // DALI_SCRIPT_EXCEPTION( isolate, error );
115 void HandleWrapper::PropertySet( v8::Local<v8::String> propertyName,
116 v8::Local<v8::Value> javaScriptValue,
117 const v8::PropertyCallbackInfo<v8::Value>& info)
120 v8::Isolate* isolate = info.GetIsolate();
121 v8::HandleScope handleScope( isolate );
123 // get the property name
124 std::string name = V8Utils::v8StringToStdString( propertyName );
126 // try to filter out function calls before going to the property system
127 // @todo use installed functions to generate a map
128 if( ( name.compare(0,2,"is") == 0 ) ||
129 ( name.compare(0,3,"get") == 0 ) ||
130 ( name.compare(0,3,"add") == 0 ) ||
131 ( name.compare(0,3,"set") == 0 ) ||
132 ( name.compare(0,3,"get") == 0 ) ||
133 ( name.compare(0,4,"find") == 0 ) ||
134 ( name.compare(0,6,"remove") == 0 )
141 HandleWrapper* handleWrapper = Unwrap( isolate, info.This() );
144 // printf("setting property name %s \n", name.c_str());
148 // DALI_ASSERT_DEBUG( handleWrapper && "not a dali object");
149 Handle handle = handleWrapper->mHandle;
151 Dali::Property::Index index = handle.GetPropertyIndex( name );
153 if(index != Dali::Property::INVALID_INDEX)
155 Dali::Property::Type type = handle.GetPropertyType(index);
157 // we know the type we want to set ( int, vector, etc..)
158 // try and convert the javascript value in to the type we want.
159 Dali::Property::Value value = PropertyValueWrapper::ExtractPropertyValue( isolate, javaScriptValue, type);
161 if( Dali::Property::NONE == value.GetType() )
163 std::stringstream msg;
164 msg << "Invalid property Set: '";
169 msg << "' Cannot convert value to correct type: (";
172 msg << Dali::PropertyTypes::GetName(type);
173 DALI_SCRIPT_EXCEPTION( isolate, msg.str().c_str());
177 handle.SetProperty( index, value );
182 std::string error="Invalid property Set for "+name + "\n";
183 DALI_SCRIPT_EXCEPTION( isolate, error );
187 void HandleWrapper::AddInterceptsToTemplate( v8::Isolate* isolate, v8::Local<v8::ObjectTemplate>& objTemplate )
189 v8::HandleScope handleScope( isolate );
191 objTemplate->SetNamedPropertyHandler( HandleWrapper::PropertyGet, HandleWrapper::PropertySet);
193 // add function properties
194 ObjectTemplateHelper::InstallFunctions( isolate, objTemplate, HandleFunctionTable, HandleFunctionTableCount );
196 ObjectTemplateHelper::AddSignalConnectAndDisconnect( isolate, objTemplate );
201 * Register a new animatable property.
203 * The object should support dynamic properties.
204 * Property names are expected to be unique, but this is not enforced.
205 * Property indices are unique to each registered custom property in a given object.
206 * returns dali.PROPERTY_INVALID_INDEX if registration failed. This can happen if you try
207 * to register animatable property on an object that does not have scene graph object.
209 * @method registerAnimatableProperty
211 * @param {string} name The name of the property.
212 * @param {Object} propertyValue The new value of the property.
213 * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
216 * var morphPropertyIndex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
217 * var fadeColorPropertyIndex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
220 void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
222 v8::Isolate* isolate = args.GetIsolate();
223 v8::HandleScope handleScope( isolate );
226 HandleWrapper* handleWrapper = Unwrap( isolate, args.This() );
232 Handle handle = handleWrapper->mHandle;
235 std::string propertyName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
238 DALI_SCRIPT_EXCEPTION( isolate, "bad property name parameter" );
243 Dali::Property::Value daliPropertyValue = V8Utils::GetPropertyValueParameter(PARAMETER_1, found, isolate, args );
244 if( !found || Dali::Property::NONE == daliPropertyValue.GetType() )
246 DALI_SCRIPT_EXCEPTION( isolate, "bad property value parameter" );
251 args.GetReturnValue().Set( v8::Integer::New( isolate, handle.RegisterProperty(propertyName, daliPropertyValue) ) );
256 * Register a new custom property.
258 * The object should support dynamic properties.
259 * Property names must be unused.
260 * Property indices are unique to each registered custom property in a given object.
261 * Properties can be set as non animatable using property attributes.
262 * returns dali.PROPERTY_INVALID_INDEX if registration failed.
264 * @method registerCustomProperty
266 * @param {string} name The name of the property.
267 * @param {Object} propertyValue The new value of the property.
268 * @param {integer} accessMode The property access mode (writable, animatable etc).
269 * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
272 * // access mode is one of the following
273 * dali.PROPERTY_READ_ONLY
274 * dali.PROPERTY_READ_WRITE
275 * dali.PROPERTY_ANIMATABLE
277 * var cellIndexPropertyIndex = actor.registerCustomProperty("cellIndex", 2, dali.PROPERTY_READ_WRITE);
278 * var myCustomPropertyIndex = handle.registerCustomProperty("myCustomProperty", [10.0, 25.0, 0.0], dali.PROPERTY_READ_ONLY);
281 void HandleWrapper::RegisterCustomProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
283 v8::Isolate* isolate = args.GetIsolate();
284 v8::HandleScope handleScope( isolate );
287 HandleWrapper* handleWrapper = Unwrap( isolate, args.This() );
293 Handle handle = handleWrapper->mHandle;
296 std::string propertyName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
299 DALI_SCRIPT_EXCEPTION( isolate, "bad property name parameter" );
304 Dali::Property::Value daliPropertyValue = V8Utils::GetPropertyValueParameter(PARAMETER_1, found, isolate, args );
305 if( !found || Dali::Property::NONE == daliPropertyValue.GetType() )
307 DALI_SCRIPT_EXCEPTION( isolate, "bad property value parameter" );
312 int accessMode = V8Utils::GetIntegerParameter( PARAMETER_2, found, isolate, args, 0 /* default */);
315 DALI_SCRIPT_EXCEPTION( isolate, "invalid access mode parameter" );
320 args.GetReturnValue().Set( v8::Integer::New( isolate, handle.RegisterProperty( propertyName, daliPropertyValue, static_cast<Property::AccessMode>(accessMode) ) ) );
324 } // namespace V8Plugin