4d09da99bd8566168959baacae09dfd2601d46d9
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / utils / v8-utils.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 // HEADER
19 #include "v8-utils.h"
20
21 // EXTERNAL INCLUDES
22 #include <iostream>
23 #include <fstream>
24 #include <sstream>
25 #include <dali/integration-api/debug.h>
26
27 // INTERNAL INCLUDES
28 #include <object/property-value-wrapper.h>
29 #include <actors/actor-wrapper.h>
30 #include <object/handle-wrapper.h>
31 #include <image/image-wrapper.h>
32 #include <render-tasks/render-task-wrapper.h>
33 #include <object/property-value-wrapper.h>
34
35
36 /**
37  * Similar to DALI_LOG_ERROR except the PRETTY_FUNCTION
38  * is removed because it makes no sense for scripting errors.
39  */
40 #define DALI_LOG_SCRIPT_ERROR(format, args...) Dali::Integration::Log::LogMessage(Dali::Integration::Log::DebugError, format, ## args)
41
42 namespace Dali
43 {
44
45 namespace V8Plugin
46 {
47
48 namespace V8Utils
49 {
50
51 void Log(const v8::FunctionCallbackInfo< v8::Value >& args)
52 {
53   v8::HandleScope handleScope( args.GetIsolate());
54
55   bool first = true;
56   for (int i = 0; i < args.Length(); i++)
57   {
58     if (first)
59     {
60       first = false;
61     }
62     else
63     {
64       std::cout << " ";
65     }
66     v8::String::Utf8Value utf8_value( args[i] );
67     std::cout << *utf8_value << "\n";
68   }
69 }
70
71 void LogError(const v8::FunctionCallbackInfo< v8::Value >& args)
72 {
73   v8::HandleScope handleScope( args.GetIsolate());
74   std::string output;
75   bool first = true;
76   for (int i = 0; i < args.Length(); i++)
77   {
78     if (first)
79     {
80       first = false;
81     }
82     else
83     {
84       output +=" ";
85     }
86     v8::String::Utf8Value utf8_value( args[i] );
87     output += *utf8_value;
88     output +="\n";
89   }
90   DALI_LOG_ERROR_NOFN( "JavaScript: %s",output.c_str() );
91 }
92
93 void GetFileContents(const std::string &fileName, std::string& contents)
94 {
95    std::ifstream t(fileName.c_str());
96    contents = std::string((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
97 };
98
99 void GetFileDirectory( const std::string& fileName, std::string& directory )
100 {
101   directory = "";
102
103   // get the position of the last slash
104   size_t pos = fileName.find_last_of("\\/");
105
106   // if it doesn't exist, return nothing
107   if( (std::string::npos == pos ) )
108   {
109     return;
110   }
111   else
112   {
113     // check an edge case where the string ends in a forward slash "mydir/"
114     if( (pos+1) < fileName.length() )
115     {
116       directory = fileName.substr(0, pos+1);
117       return;
118     }
119   }
120 }
121
122 void GetFileName( const std::string& fullPathName, std::string& fileName )
123 {
124   // look for last slash
125   size_t pos = fullPathName.find_last_of("\\/");
126
127   if( std::string::npos == pos )
128   {
129     fileName = fullPathName;
130   }
131   else
132   {
133     fileName = fullPathName.substr(pos,fileName.length());
134   }
135 }
136
137 void GetModuleName( const std::string& fileName, std::string& moduleName )
138 {
139   std::string fileNameNoPath;
140    GetFileName( fileName , fileNameNoPath );
141   size_t pos = fileNameNoPath.find_last_of(".");
142   if( std::string::npos == pos )
143   {
144     moduleName = fileNameNoPath;
145   }
146   else
147   {
148     moduleName = fileName.substr(0, pos );
149   }
150 }
151
152 void ReportException(  v8::Isolate* isolate, v8::TryCatch* tryCatch)
153 {
154   v8::HandleScope handleScope( isolate );
155
156   v8::String::Utf8Value exception(tryCatch->Exception());
157   v8::Handle<v8::Message> message   = tryCatch->Message();
158
159   if (message.IsEmpty())
160   {
161     // V8 didn't provide any extra information about this error; just
162     // print the exception.
163     DALI_LOG_SCRIPT_ERROR("%s\n", *exception);
164   }
165   else
166   {
167
168     // Print (filename):(line number): (message).
169     v8::String::Utf8Value filename(message->GetScriptResourceName());
170
171     DALI_LOG_SCRIPT_ERROR("\n\n====== Error found in JavaScript: ========= \n");
172
173
174     int linenum = message->GetLineNumber();
175     DALI_LOG_SCRIPT_ERROR("File: %s\n", *filename, linenum, *exception);
176
177      DALI_LOG_SCRIPT_ERROR("Error: :%s\n", *exception );
178      DALI_LOG_SCRIPT_ERROR("Line: :%i\n",  linenum );
179
180     // Print line of source code.
181     v8::String::Utf8Value sourceline(message->GetSourceLine());
182
183     DALI_LOG_SCRIPT_ERROR("Source: %s\n", *sourceline);
184
185     // Print wavy underline (GetUnderline is deprecated).
186
187     std::stringstream msg;
188
189     int start = message->GetStartColumn();
190     for (int i = 0; i < start; i++)
191     {
192       msg << " ";
193     }
194     int end = message->GetEndColumn();
195     for (int i = start; i < end; i++)
196     {
197       msg << "↑";
198     }
199
200     DALI_LOG_SCRIPT_ERROR("        %s\n", msg.str().c_str());
201
202     v8::String::Utf8Value stack_trace(tryCatch->StackTrace());
203     if (stack_trace.length() > 0)
204     {
205       DALI_LOG_SCRIPT_ERROR("%s\n", *stack_trace);
206     }
207     DALI_LOG_SCRIPT_ERROR("\n=========================================== \n");
208
209   }
210 }
211
212 std::string GetJavaScriptFunctionName( const char* functionName  )
213 {
214   // @todo if we are 100% decided on lower case, go through
215   // every api and manually change the function names to lower case first character
216   std::string name( functionName );
217   name[0]=tolower( functionName[0] );
218   return name;
219 }
220
221 void Version(const v8::FunctionCallbackInfo< v8::Value >& args)
222 {
223   v8::HandleScope handleScope( args.GetIsolate());
224
225   v8::Handle<v8::String>  ver = v8::String::NewFromUtf8(args.GetIsolate(), v8::V8::GetVersion());
226
227   args.GetReturnValue().Set(ver);
228 }
229
230
231 std::string v8StringToStdString( const v8::Handle<v8::Value>& value )
232 {
233   v8::String::Utf8Value utf8(value);
234   return std::string(*utf8);
235 }
236
237
238 std::string PropertyNameToJavaScriptName(const std::string& hyphenatedName)
239 {
240   std::string ret;
241
242   ret.reserve(hyphenatedName.size());
243
244   bool capitlizeNext = false ;
245   for(unsigned int i = 0; i < hyphenatedName.size(); ++i)
246   {
247     char c = hyphenatedName[i];
248     if(c == '-')
249     {
250       capitlizeNext = true;
251     }
252     else
253     {
254       if(capitlizeNext)
255       {
256         ret.push_back(std::toupper(c));
257         capitlizeNext = false;
258       }
259       else
260       {
261         ret.push_back(c);
262       }
263     }
264   }
265
266   return ret;
267 }
268
269
270
271 void ScriptError( const char* function, v8::Isolate* isolate, std::string errorString )
272 {
273   v8::EscapableHandleScope scope( isolate);
274   std::string errorMsg = std::string(function) + std::string("(), ") + errorString;
275
276   // log out to DALI_LOG_ERROR first, so we know something has gone wrong
277   DALI_LOG_ERROR("%s \n", errorMsg.c_str() );
278
279   // throw a V8 exception, DALi will keep running but we will get a print out
280   // of where the error occured in the JavaScript source
281   isolate->ThrowException( v8::String::NewFromUtf8( isolate, errorMsg.c_str()) );
282 }
283
284 bool IsBooleanPrimitiveOrObject( const v8::Local<v8::Value>& value )
285 {
286   return ( value->IsBoolean() || value->IsBooleanObject());
287 }
288
289 bool GetBooleanValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
290 {
291   v8::EscapableHandleScope scope( isolate); // may not be required.
292
293   if( value->IsBoolean() )
294   {
295     return value->ToBoolean()->Value();
296   }
297   else if (value->IsBooleanObject() )
298   {
299     const v8::Local<v8::BooleanObject> object = v8::Local<v8::BooleanObject>::Cast(value);
300     return object->BooleanValue();
301   }
302   DALI_SCRIPT_EXCEPTION(isolate, "no bool found");
303   return false;
304 }
305
306 bool IsNumberPrimitiveOrObject( const v8::Local<v8::Value>& value )
307 {
308   return ( value->IsNumber() || value->IsNumberObject());
309 }
310
311 float GetNumberValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
312 {
313   v8::EscapableHandleScope scope( isolate); // may not be required.
314
315   if( value->IsNumber() )
316   {
317     return value->ToNumber()->Value();
318   }
319   else if (value->IsNumberObject() )
320   {
321     const v8::Local<v8::NumberObject> object = v8::Local<v8::NumberObject>::Cast(value);
322     return object->ValueOf();
323   }
324
325   DALI_SCRIPT_EXCEPTION(isolate, "no number found?");
326   return 0.f;
327 }
328
329 bool IsStringPrimitiveOrObject( const v8::Local<v8::Value>& value )
330 {
331   return ( value->IsString() || value->IsStringObject());
332 }
333
334 std::string GetStringValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
335 {
336   v8::EscapableHandleScope scope( isolate); // may not be required.
337
338   if( value->IsString() )
339   {
340     return V8Utils::v8StringToStdString(value);
341   }
342   else if (value->IsStringObject() )
343   {
344     const v8::Local<v8::StringObject> object = v8::Local<v8::StringObject>::Cast(value);
345     return V8Utils::v8StringToStdString( object->ValueOf() );
346   }
347
348   DALI_SCRIPT_EXCEPTION(isolate, "no string found?");
349   return "";
350 }
351
352
353 Property::Value GetPropertyValueFromObject( bool& found, v8::Isolate* isolate, const   v8::Local<v8::Value >& value  )
354 {
355   v8::HandleScope handleScope( isolate);
356
357   Property::Value  daliPropertyValue;// creates a property with Property::NONE
358
359   found = false;
360
361   if( value->IsObject() )
362   {
363     v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast( value );
364
365     if( BaseWrappedObject::IsWrappedTypeAPropertyValue( object ) )
366     {
367       found = true;
368       PropertyValueWrapper* propertyWrapper = PropertyValueWrapper::Unwrap( isolate, object );
369       return propertyWrapper->GetValue();
370     }
371     else if( value->IsArray() )
372     {
373       found = true;
374       return PropertyValueWrapper::VectorOrMatrixFromV8Array( isolate, object);//todo check for V8 array / map?
375     }
376   }
377   else if( value->IsBoolean() )
378   {
379     found = true;
380     v8::Local<v8::Boolean> v = value->ToBoolean();
381     return Dali::Property::Value(v->Value());
382   }
383   else if( value->IsNumber() )
384   {
385     found = true;
386     v8::Local<v8::Number> v = value->ToNumber();
387     return Dali::Property::Value(static_cast<float>(v->Value()));
388   }
389   else if( value->IsInt32() || value->IsUint32() )
390   {
391     found = true;
392     v8::Local<v8::Int32> v = value->ToInt32();
393     return Dali::Property::Value(static_cast<int>(v->Value()));
394   }
395   return daliPropertyValue;
396
397 }
398
399 Property::Map GetPropertyMapFromObject( v8::Isolate* isolate, const v8::Local<v8::Object>& object)
400 {
401   v8::Local<v8::Array> properties = object->GetPropertyNames();
402   Property::Map propertyMap;    // empty map
403
404   for(  unsigned int i = 0; i <  properties->Length(); ++i)
405   {
406     // Get the key
407     v8::Local<v8::Value> key = properties->Get( i );
408     std::string keyString = v8StringToStdString( key );
409
410     // Get the value
411     v8::Local<v8::Value> value = object->Get( key );
412
413     if( value->IsBoolean() )
414     {
415       v8::Local<v8::Boolean> v = value->ToBoolean();
416       propertyMap[ keyString ] = v->Value();
417     }
418     else if( value->IsNumber() )
419     {
420       v8::Local<v8::Number> v = value->ToNumber();
421       propertyMap[ keyString ] = static_cast<float>(v->Value());
422     }
423     else if( value->IsInt32() || value->IsUint32() )
424     {
425       v8::Local<v8::Int32> v = value->ToInt32();
426       propertyMap[ keyString ] = static_cast<int>(v->Value());
427     }
428     else if( value->IsString() )
429     {
430       std::string valueString = V8Utils::v8StringToStdString( value );
431       propertyMap[ keyString ] = valueString.c_str();
432     }
433     else if( value->IsArray() )
434     {
435       propertyMap[ keyString ] = PropertyValueWrapper::VectorOrMatrixFromV8Array( isolate, value);
436     }
437     else if( value->IsObject() )
438     {
439       Dali::Property::Map map = V8Utils::GetPropertyMapFromObject(isolate, value->ToObject());
440       if( !map.Empty() )
441       {
442         propertyMap[ keyString ] = Dali::Property::Value( map );
443       }
444     }
445   }
446
447   return propertyMap;
448 }
449
450 Actor GetActorFromObject( v8::Isolate* isolate, bool& found, v8::Local<v8::Object>& object)
451 {
452   v8::HandleScope handleScope( isolate);
453   found = false;
454
455   if( BaseWrappedObject::IsWrappedType ( isolate, object, BaseWrappedObject::ACTOR ))
456   {
457     HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, object );
458     return Actor::DownCast( handleWrapper->mHandle );
459   }
460   return Actor();
461 }
462
463
464 int GetIntegerParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args, int defaultValue  )
465 {
466   found = false;
467   unsigned int length = args.Length();
468   if( index >= length )
469   {
470     return defaultValue;
471   }
472   if( args[ index ]->IsInt32() )
473   {
474     found = true;
475     return args[ index ]->Int32Value();
476   }
477   else
478   {
479     return defaultValue;
480   }
481 }
482
483 float GetFloatParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args, float defaultValue  )
484 {
485   found = false;
486   unsigned int length = args.Length();
487   if( index >= length )
488   {
489     return defaultValue;
490   }
491   if( args[ index ]->IsNumber() )
492   {
493     found = true;
494     return args[ index ]->NumberValue();
495   }
496   else
497   {
498     return defaultValue;
499   }
500 }
501
502 std::string GetStringParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
503 {
504   found = false;
505   unsigned int length = args.Length();
506
507   if( index >= length )
508   {
509     return std::string();
510   }
511   if( args[ index ]->IsString() )
512   {
513     found = true;
514     return v8StringToStdString( args[ index ]);
515   }
516   else
517   {
518     return std::string();
519   }
520 }
521
522 bool GetBooleanParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
523 {
524   v8::HandleScope handleScope( isolate);
525
526   found = false;
527   unsigned int length = args.Length();
528   if( index >= length )
529   {
530     return false;
531   }
532   if( args[ index ]->IsBoolean() )
533   {
534     found = true;
535     v8::Local<v8::Boolean> v = args[ index ]->ToBoolean();
536     return v->Value();
537   }
538   else
539   {
540     return false;
541   }
542 }
543
544 void* GetArrayBufferViewParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args  )
545 {
546   found = false;
547   unsigned int length = args.Length();
548   if( index < length && args[index]->IsArrayBufferView() )
549   {
550     found = true;
551     v8::ArrayBufferView* bufferView = v8::ArrayBufferView::Cast(*(args[index]));
552     v8::Handle<v8::ArrayBuffer> buffer = bufferView->Buffer();
553     v8::ArrayBuffer::Contents contents = buffer->Externalize();
554     return contents.Data();
555   }
556   else
557   {
558     return NULL;
559   }
560 }
561
562 Handle GetHandleParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
563 {
564   v8::HandleScope handleScope( isolate);
565
566   found = false;
567   unsigned int length = args.Length();
568   if( index >= length )
569   {
570     return Handle();
571   }
572
573   if( args[ index ]->IsObject() )
574   {
575     v8::Local<v8::Object> object = args[ index ]->ToObject();
576     v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
577     void* ptr = field->Value();
578     if( ptr )
579     {
580         found = true;
581         HandleWrapper* wrapper = static_cast< HandleWrapper *>(ptr);
582         return wrapper->GetHandle();
583     }
584   }
585   return Handle();
586 }
587
588 Vector2 GetVector2Parameter( unsigned int index,  bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
589 {
590   v8::HandleScope handleScope( isolate);
591   unsigned int length =  args.Length();
592   Vector2 ret;
593   found = false;
594
595   if( index < length )
596   {
597     if( args[ index ]->IsObject() )
598     {
599       Dali::Property::Value value;
600       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR2 );
601       if( value.GetType() == Dali::Property::VECTOR2)
602       {
603         found = true;
604         value.Get(ret);
605       }
606       else
607       {
608         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector2 parameter");
609       }
610     }
611   }
612   else
613   {
614     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector2 parameter");
615   }
616
617   return ret;
618 }
619
620 Vector2 GetVector2ParameterFrom2Float( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
621 {
622   Vector2 ret(0.0f,0.0f);
623   bool bFound(false);
624   unsigned int argCount( args.Length() );
625
626   if( index+2 >= argCount )
627   {
628     DALI_SCRIPT_EXCEPTION(isolate, "Missing parameter");
629   }
630
631   found = true;
632   ret.x = V8Utils::GetFloatParameter( index, bFound, isolate, args, 0.0f );
633   found = found && bFound;
634   ret.y = V8Utils::GetFloatParameter( index+1, bFound, isolate, args, 0.0f );
635   found = found && bFound;
636
637   return ret;
638 }
639
640 Vector3 GetVector3Parameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args)
641 {
642   v8::HandleScope handleScope( isolate);
643   unsigned int argCount( args.Length() );
644   Vector3 ret;
645   found = false;
646   if( index < argCount )
647   {
648     if( args[ index ]->IsObject() )
649     {
650       Dali::Property::Value value;
651       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR3 );
652       if( value.GetType() == Dali::Property::VECTOR3)
653       {
654         found = true;
655         value.Get(ret);
656       }
657       else
658       {
659         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector3 parameter");
660       }
661     }
662   }
663   else
664   {
665     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector3 parameter");
666
667   }
668
669   return ret;
670 }
671
672 Vector4 GetVector4Parameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args)
673 {
674   v8::HandleScope handleScope( isolate);
675   unsigned int argCount( args.Length() );
676   Vector4 ret;
677   found = false;
678
679   if( index < argCount )
680   {
681     if( args[ index ]->IsObject() )
682     {
683       Dali::Property::Value value;
684       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR4 );
685       if( value.GetType() == Dali::Property::VECTOR4)
686       {
687         found = true;
688         value.Get(ret);
689       }
690       else
691       {
692         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector4 parameter");
693       }
694     }
695   }
696   else
697   {
698     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector4 parameter");
699   }
700
701   return ret;
702 }
703
704
705 Rect<int> GetRectIntParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
706 {
707   v8::HandleScope handleScope( isolate);
708
709    found = false;
710    int length = args.Length() - index;
711
712    // if it's an array read the 2 numbers into a vector2
713    if( length == 4 )
714    {
715      if( args[ 0 + index ]->IsInt32() &&
716          args[ 1 + index ]->IsInt32() &&
717          args[ 2 + index ]->IsInt32() &&
718          args[ 3 + index ]->IsInt32() )
719      {
720        found = true;
721        Rect<int> rect( args[ 0 + index ]->Int32Value(),
722                        args[ 1 + index ]->Int32Value(),
723                        args[ 2 + index ]->Int32Value(),
724                        args[ 3 + index ]->Int32Value() );
725        return rect;
726      }
727    }
728    // this will extract a Vector4, if it is a Vector4 or a Javascript array object
729    if( args[ index ]->IsObject() )
730    {
731      Dali::Property::Value value;
732      value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::RECTANGLE );
733      if( value.GetType() == Dali::Property::RECTANGLE)
734      {
735        found = true;
736        Rect<int> rect;
737        value.Get(rect);
738        return rect;
739      }
740
741      // @todo support vector4 as well?
742    }
743    return Rect<int>();
744 }
745
746 Actor GetActorParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
747 {
748   BaseWrappedObject* wrapper = GetWrappedDaliObjectParameter( index, BaseWrappedObject::ACTOR, isolate, args);
749   ActorWrapper* actorWrapper = static_cast< ActorWrapper*>( wrapper );
750   if( actorWrapper )
751   {
752     found = true;
753     return actorWrapper->GetActor();
754   }
755   else
756   {
757     return Actor();
758   }
759 }
760
761 Layer GetLayerParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
762 {
763   Actor actor = GetActorParameter( index, found, isolate, args );
764   return Layer::DownCast( actor );
765 }
766
767 Image GetImageParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
768 {
769   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( index, BaseWrappedObject::IMAGE, isolate, args );
770   if( wrappedObject )
771   {
772     found = true;
773     ImageWrapper* wrapper = static_cast< ImageWrapper *>(wrappedObject);
774     return wrapper->GetImage();
775   }
776   else
777   {
778     return Image();
779   }
780
781 }
782
783 RenderTask GetRenderTaskParameter( unsigned int paramIndex, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
784 {
785   found = false;
786   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::RENDER_TASK, isolate, args );
787   if( wrappedObject )
788   {
789     found = true;
790     RenderTaskWrapper* wrapper = static_cast< RenderTaskWrapper *>(wrappedObject);
791     return wrapper->GetRenderTask();
792   }
793   else
794   {
795     return RenderTask(); // empty handle
796   }
797 }
798
799 BaseWrappedObject* GetWrappedDaliObjectParameter( unsigned int index,  BaseWrappedObject::Type type,  v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
800 {
801   v8::HandleScope handleScope( isolate);
802   unsigned int length = args.Length();
803
804   if( index >= length )
805   {
806     return NULL;
807   }
808
809   if( !args[ index ]->IsObject() )
810   {
811     return NULL;
812   }
813
814   v8::Local<v8::Object> object = args[ index ]->ToObject();
815
816   if( BaseWrappedObject::IsWrappedType ( isolate, object, type ))
817   {
818     v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
819     void* ptr = field->Value();
820     BaseWrappedObject* wrapper = static_cast< BaseWrappedObject *>(ptr);
821     return wrapper;
822   }
823   return NULL;
824 }
825
826
827 Property::Value GetPropertyValueParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
828 {
829   v8::HandleScope handleScope( isolate);
830
831   Property::Value  daliPropertyValue;// creates a property with Property::INVALID
832
833   found = false;
834   unsigned int length = args.Length();
835
836   if( index >= length )
837   {
838     return daliPropertyValue;
839   }
840   v8::Local<v8::Value > value = args[ index ];
841
842   return GetPropertyValueFromObject( found, isolate, value);
843 }
844
845 Property::Map GetPropertyMapParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
846 {
847   v8::HandleScope handleScope( isolate);
848
849   Property::Map propertyMap;    // empty map
850
851   found = false;
852   unsigned int length = args.Length();
853
854   if( index >= length )
855   {
856     return propertyMap;
857   }
858
859   if( !args[ index ]->IsObject() )
860   {
861     return propertyMap;
862   }
863   found = true;
864
865   // go through each key value pair
866   v8::Local<v8::Object> obj = args[ index ]->ToObject();
867
868   return GetPropertyMapFromObject( isolate, obj );
869
870 }
871
872 void CreatePropertyMap( v8::Isolate* isolate, const Property::Map& map, v8::Local<v8::Object>& object )
873 {
874   v8::HandleScope handleScope( isolate);
875
876   // we're converting a dali property map in to a JavaScript property map
877   if( map.Count() == 0 )
878   {
879     return;
880   }
881
882   for( unsigned int index = 0; index < map.Count() - 1; ++index )
883   {
884     const std::string& key = map.GetKey( index );
885     Property::Value& value = map.GetValue( index );
886     v8::Local<v8::Value> v8Value;
887
888     switch( value.GetType() )
889     {
890       case Dali::Property::FLOAT:
891       {
892         v8Value = v8::Number::New( isolate, value.Get<float>()  );
893         break;
894       }
895       case Dali::Property::BOOLEAN:
896       {
897         v8Value = v8::Boolean::New(  isolate, value.Get<bool>());
898         break;
899       }
900       case Dali::Property::INTEGER:
901       {
902         v8Value = v8::Integer::New( isolate, value.Get<int>());
903         break;
904       }
905       case Dali::Property::STRING:
906       {
907         std::string string = value.Get< std::string >();
908         v8Value = v8::String::NewFromUtf8( isolate,  string.c_str());
909         break;
910       }
911       case Dali::Property::VECTOR2:
912       {
913         // create a vector2
914         Vector2 vec = value.Get<Vector2>();
915         v8::Local<v8::Array> array= v8::Array::New( isolate, 2 );
916         array->Set( 0 , v8::Number::New(isolate, vec.x));
917         array->Set( 1 , v8::Number::New(isolate, vec.y));
918         v8Value = array;
919         break;
920       }
921       case Dali::Property::VECTOR3:
922       {
923         // create a vector 3
924         Vector3 vec = value.Get<Vector3>();
925         v8::Local<v8::Array> array= v8::Array::New( isolate, 3 );
926         array->Set( 0 , v8::Number::New(isolate, vec.x));
927         array->Set( 1 , v8::Number::New(isolate, vec.y));
928         array->Set( 2 , v8::Number::New(isolate, vec.z));
929         v8Value = array;
930         break;
931       }
932       case Dali::Property::VECTOR4:
933       {
934         // create a vector 4
935         Vector4 vec = value.Get<Vector4>();
936         v8::Local<v8::Array> array= v8::Array::New( isolate, 4 );
937         array->Set( 0 , v8::Number::New(isolate, vec.x));
938         array->Set( 1 , v8::Number::New(isolate, vec.y));
939         array->Set( 2 , v8::Number::New(isolate, vec.z));
940         array->Set( 3 , v8::Number::New(isolate, vec.w));
941         v8Value = array;
942         break;
943       }
944
945       default:
946       {
947         DALI_SCRIPT_EXCEPTION( isolate, "Primitive mismatch \n");
948         return;
949       }
950     }
951     object->Set( v8::String::NewFromUtf8( isolate, key.c_str() ), v8Value );
952   }
953 }
954
955 void ReadFloatArguments( bool& foundAllArguments, float* data, unsigned int dataSize, const v8::FunctionCallbackInfo< v8::Value >& args, float defaultValue )
956 {
957   foundAllArguments = true;
958   unsigned int length = args.Length();
959
960   if( length < dataSize )
961   {
962     foundAllArguments = false;
963   }
964
965   for( unsigned int i = 0; i< dataSize ;i++ )
966   {
967     if( i < length )
968     {
969       if( args[ i ]->IsNumber()  )
970       {
971         data[i] = args[i]->NumberValue();
972       }
973       else
974       {
975         data[i] = defaultValue;
976         foundAllArguments = false;   // bad argument
977       }
978     }
979     else
980     {
981       data[i] = defaultValue; // not enough arguments
982     }
983   }
984
985 }
986
987 void ReadIntegerArguments( bool& foundAllArguments, int* data, int dataSize, const v8::FunctionCallbackInfo< v8::Value >& args, int defaultValue )
988 {
989   foundAllArguments = true;
990   int length = args.Length();
991   if( length < dataSize )
992   {
993     foundAllArguments = false;
994   }
995
996   for( int i = 0; i< dataSize ;i++ )
997   {
998     if( i < length )
999     {
1000       if( args[ i ]->IsInt32()  )
1001       {
1002         data[i] = args[i]->Int32Value();
1003       }
1004       else
1005       {
1006         data[i] = defaultValue;
1007         foundAllArguments = false;   // bad argument
1008       }
1009     }
1010     else
1011     {
1012       data[i] = defaultValue; // not enough arguments
1013     }
1014   }
1015
1016 }
1017 } // namespace V8Utils
1018
1019 } // namespace V8Plugin
1020
1021 } // namespace Dali