Changed all property & signal names to lowerCamelCase
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / object / handle-wrapper.cpp
1 /*
2  * Copyright (c) 2015 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 "handle-wrapper.h"
20
21 // EXTERNAL INCLUDES
22 #include <sstream>
23
24 // INTERNAL INCLUDES
25 #include <v8-utils.h>
26 #include <shared/base-wrapped-object.h>
27 #include <shared/object-template-helper.h>
28 #include <object/property-value-wrapper.h>
29
30 namespace Dali
31 {
32
33 namespace V8Plugin
34 {
35
36 namespace // un-named name space
37 {
38
39 /**
40  * Contains a list of all functions that can be called
41  */
42 const ApiFunction HandleFunctionTable[]=
43 {
44   { "RegisterAnimatableProperty",            HandleWrapper::RegisterAnimatableProperty },
45 };
46
47 const unsigned int HandleFunctionTableCount = sizeof(HandleFunctionTable)/sizeof(HandleFunctionTable[0]);
48 } //un-named space
49
50 /**
51  * @class Handle
52  */
53
54 HandleWrapper::HandleWrapper( BaseWrappedObject::Type type,
55     Handle handle,
56     GarbageCollectorInterface& gc ) :
57  BaseWrappedObject( type, gc ),
58  mHandle( handle )
59 {
60 }
61
62 HandleWrapper::~HandleWrapper()
63 {
64
65 }
66 HandleWrapper*  HandleWrapper::Unwrap( v8::Isolate* isolate, v8::Handle< v8::Object> obj)
67 {
68   v8::HandleScope handleScope( isolate );
69
70   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( obj->GetInternalField(0) );
71   void* ptr = field->Value();
72   return static_cast< HandleWrapper *>(ptr);
73 }
74
75 // may have to do this IsUpper to intercept function calls or as function?
76 void HandleWrapper::PropertyGet( v8::Local<v8::String> propertyName,
77                                         const v8::PropertyCallbackInfo<v8::Value>& info)
78 {
79   v8::Isolate* isolate = info.GetIsolate();
80   v8::HandleScope handleScope( isolate );
81
82   // get the property name
83   std::string name = V8Utils::v8StringToStdString( propertyName );
84
85   if( std::isupper( name[0] ))
86   {
87     return;
88   }
89
90   // unwrap the object
91   HandleWrapper* handleWrapper = Unwrap( isolate, info.This() );
92   Handle handle =  handleWrapper->mHandle;
93
94   // get the property index
95   Dali::Property::Index index = handle.GetPropertyIndex( name );
96
97   if(index != Dali::Property::INVALID_INDEX)
98   {
99     Dali::Property::Value value = handle.GetProperty(index);
100
101     // Simple Dali properties (ints, strings, bools etc) are stored as JavaScript primitives (v8::Boolean ...)
102     // more complex properties (Vectors, Rectangles...) are wrapped by a JavaScript object
103     v8::Local<v8::Object> ret = PropertyValueWrapper::WrapDaliProperty( isolate, value );
104
105     info.GetReturnValue().Set( ret );
106   }
107   else
108   {
109     //  std::string error="Invalid property Get for "+name + "\n";
110     // DALI_SCRIPT_EXCEPTION( isolate, error );
111   }
112
113 }
114 void HandleWrapper::PropertySet( v8::Local<v8::String> propertyName,
115                   v8::Local<v8::Value> javaScriptValue,
116                   const v8::PropertyCallbackInfo<v8::Value>& info)
117 {
118
119   v8::Isolate* isolate = info.GetIsolate();
120   v8::HandleScope handleScope( isolate );
121
122   // get the property name
123   std::string name = V8Utils::v8StringToStdString( propertyName );
124
125   // try to filter out function calls before going to the property system
126   // @todo use installed functions to generate a map
127   if( ( name.compare(0,2,"is") == 0 )  ||
128       ( name.compare(0,3,"get") == 0 ) ||
129       ( name.compare(0,3,"add") == 0 ) ||
130       ( name.compare(0,3,"set") == 0 ) ||
131       ( name.compare(0,3,"get") == 0 ) ||
132       ( name.compare(0,4,"find") == 0 ) ||
133       ( name.compare(0,6,"remove") == 0 )
134      )
135   {
136     //
137     return;
138   }
139   // unwrap the object
140   HandleWrapper* handleWrapper = Unwrap( isolate, info.This() );
141   if( !handleWrapper )
142   {
143     // printf("setting property name %s \n", name.c_str());
144     return;
145   }
146
147  // DALI_ASSERT_DEBUG( handleWrapper && "not a dali object");
148   Handle handle =  handleWrapper->mHandle;
149
150   Dali::Property::Index index = handle.GetPropertyIndex( name );
151
152   if(index != Dali::Property::INVALID_INDEX)
153   {
154     Dali::Property::Type type = handle.GetPropertyType(index);
155
156     // we know the type we want to set ( int, vector, etc..)
157     // try and convert the javascript value in to the type we want.
158     Dali::Property::Value value = PropertyValueWrapper::ExtractPropertyValue( isolate, javaScriptValue, type);
159
160     if( Dali::Property::NONE == value.GetType() )
161       {
162         std::stringstream msg;
163         msg << "Invalid property Set: '";
164         msg << name;
165         msg << "(Index = ";
166         msg << index;
167         msg << ")";
168         msg << "' Cannot convert value to correct type: (";
169         msg << type;
170         msg << ")";
171         msg << Dali::PropertyTypes::GetName(type);
172         DALI_SCRIPT_EXCEPTION( isolate, msg.str().c_str());
173       }
174       else
175       {
176         handle.SetProperty( index, value );
177       }
178   }
179   else
180   {
181     std::string error="Invalid property Set for "+name + "\n";
182     DALI_SCRIPT_EXCEPTION( isolate, error );
183   }
184 }
185
186 void HandleWrapper::AddInterceptsToTemplate( v8::Isolate* isolate, v8::Local<v8::ObjectTemplate>& objTemplate )
187 {
188   v8::HandleScope handleScope( isolate );
189
190   objTemplate->SetNamedPropertyHandler( HandleWrapper::PropertyGet, HandleWrapper::PropertySet);
191
192   // add function properties
193   ObjectTemplateHelper::InstallFunctions( isolate, objTemplate, HandleFunctionTable, HandleFunctionTableCount );
194
195   ObjectTemplateHelper::AddSignalConnectAndDisconnect( isolate, objTemplate );
196
197 }
198
199 /**
200  * Register a new animatable property.
201  *
202  * The object should support dynamic properties.
203  * Property names are expected to be unique, but this is not enforced.
204  * Property indices are unique to each registered custom property in a given object.
205  * returns dali.PROPERTY_INVALID_INDEX if registration failed. This can happen if you try
206  * to register animatable property on an object that does not have scene graph object.
207  *
208  * @method registerAnimatableProperty
209  * @for Handle
210  * @param {string} name The name of the property.
211  * @param {Object} propertyValue The new value of the property.
212  * @return {integer} The index of the property or dali.PROPERTY_INVALID_INDEX if registration failed
213  * @example
214  *
215  *     var morphPropertyIdex = actor.registerAnimatableProperty("uMorphAmount", 0.0f);
216  *     var fadeColorPropertyIdex = handle.registerAnimatableProperty("uFadeColor", [1.0, 0.0, 0.0, 1.0]);
217  *
218  */
219 void HandleWrapper::RegisterAnimatableProperty( const v8::FunctionCallbackInfo< v8::Value >& args )
220 {
221   v8::Isolate* isolate = args.GetIsolate();
222   v8::HandleScope handleScope( isolate );
223
224   // unwrap the object
225   HandleWrapper* handleWrapper = Unwrap( isolate, args.This() );
226   if( !handleWrapper )
227   {
228     return;
229   }
230
231   Handle handle =  handleWrapper->mHandle;
232
233   bool found( false );
234   std::string propertyName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
235   if( !found )
236   {
237     DALI_SCRIPT_EXCEPTION( isolate, "bad property name parameter" );
238     return;
239   }
240
241   found = false;
242   Dali::Property::Value daliPropertyValue = V8Utils::GetPropertyValueParameter(PARAMETER_1, found, isolate, args );
243   if( !found || Dali::Property::NONE == daliPropertyValue.GetType() )
244   {
245     DALI_SCRIPT_EXCEPTION( isolate, "bad property value parameter" );
246     return;
247   }
248   else
249   {
250     args.GetReturnValue().Set( v8::Integer::New( isolate, handle.RegisterProperty(propertyName, daliPropertyValue) ) );
251   }
252 }
253
254 } // namespace V8Plugin
255
256 } // namespace Dali