JavaScript binding for new mesh APIs
[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 std::string JavaScriptNameToPropertyName(const std::string& camelCase)
272 {
273   std::string ret;
274
275   int countUpper = 0;
276   for(unsigned int i = 0; i < camelCase.size(); ++i)
277   {
278     if(std::isupper(camelCase[i]))
279     {
280       countUpper++;
281     }
282   }
283
284   if(countUpper)
285   {
286     ret.reserve(camelCase.size() + countUpper);
287
288     for(unsigned int i = 0; i < camelCase.size(); ++i)
289     {
290       char c = camelCase[i];
291       if(std::isupper(c))
292       {
293         ret.push_back('-');
294       }
295
296       ret.push_back(std::tolower(c));
297     }
298   }
299   else
300   {
301     return camelCase ;
302   }
303
304   return ret;
305 }
306
307 void ScriptError( const char* function, v8::Isolate* isolate, std::string errorString )
308 {
309   v8::EscapableHandleScope scope( isolate);
310   std::string errorMsg = std::string(function) + std::string("(), ") + errorString;
311
312   // log out to DALI_LOG_ERROR first, so we know something has gone wrong
313   DALI_LOG_ERROR("%s \n", errorMsg.c_str() );
314
315   // throw a V8 exception, DALi will keep running but we will get a print out
316   // of where the error occured in the JavaScript source
317   isolate->ThrowException( v8::String::NewFromUtf8( isolate, errorMsg.c_str()) );
318 }
319
320 bool IsBooleanPrimitiveOrObject( const v8::Local<v8::Value>& value )
321 {
322   return ( value->IsBoolean() || value->IsBooleanObject());
323 }
324
325 bool GetBooleanValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
326 {
327   v8::EscapableHandleScope scope( isolate); // may not be required.
328
329   if( value->IsBoolean() )
330   {
331     return value->ToBoolean()->Value();
332   }
333   else if (value->IsBooleanObject() )
334   {
335     const v8::Local<v8::BooleanObject> object = v8::Local<v8::BooleanObject>::Cast(value);
336     return object->BooleanValue();
337   }
338   DALI_SCRIPT_EXCEPTION(isolate, "no bool found");
339   return false;
340 }
341
342 bool IsNumberPrimitiveOrObject( const v8::Local<v8::Value>& value )
343 {
344   return ( value->IsNumber() || value->IsNumberObject());
345 }
346
347 float GetNumberValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
348 {
349   v8::EscapableHandleScope scope( isolate); // may not be required.
350
351   if( value->IsNumber() )
352   {
353     return value->ToNumber()->Value();
354   }
355   else if (value->IsNumberObject() )
356   {
357     const v8::Local<v8::NumberObject> object = v8::Local<v8::NumberObject>::Cast(value);
358     return object->ValueOf();
359   }
360
361   DALI_SCRIPT_EXCEPTION(isolate, "no number found?");
362   return 0.f;
363 }
364
365 bool IsStringPrimitiveOrObject( const v8::Local<v8::Value>& value )
366 {
367   return ( value->IsString() || value->IsStringObject());
368 }
369
370 std::string GetStringValue( v8::Isolate* isolate, const v8::Local<v8::Value>& value )
371 {
372   v8::EscapableHandleScope scope( isolate); // may not be required.
373
374   if( value->IsString() )
375   {
376     return V8Utils::v8StringToStdString(value);
377   }
378   else if (value->IsStringObject() )
379   {
380     const v8::Local<v8::StringObject> object = v8::Local<v8::StringObject>::Cast(value);
381     return V8Utils::v8StringToStdString( object->ValueOf() );
382   }
383
384   DALI_SCRIPT_EXCEPTION(isolate, "no string found?");
385   return "";
386 }
387
388
389 Property::Value GetPropertyValueFromObject( bool& found, v8::Isolate* isolate, const   v8::Local<v8::Value >& value  )
390 {
391   v8::HandleScope handleScope( isolate);
392
393   Property::Value  daliPropertyValue;// creates a property with Property::NONE
394
395   found = false;
396
397   if( value->IsObject() )
398   {
399     v8::Local<v8::Object> object = v8::Handle<v8::Object>::Cast( value );
400
401     if( BaseWrappedObject::IsWrappedTypeAPropertyValue( object ) )
402     {
403       found = true;
404       PropertyValueWrapper* propertyWrapper = PropertyValueWrapper::Unwrap( isolate, object );
405       return propertyWrapper->GetValue();
406     }
407     else if( value->IsArray() )
408     {
409       found = true;
410       return PropertyValueWrapper::VectorOrMatrixFromV8Array( isolate, object);//todo check for V8 array / map?
411     }
412   }
413   else if( value->IsBoolean() )
414   {
415     found = true;
416     v8::Local<v8::Boolean> v = value->ToBoolean();
417     return Dali::Property::Value(v->Value());
418   }
419   else if( value->IsNumber() )
420   {
421     found = true;
422     v8::Local<v8::Number> v = value->ToNumber();
423     return Dali::Property::Value(static_cast<float>(v->Value()));
424   }
425   else if( value->IsInt32() || value->IsUint32() )
426   {
427     found = true;
428     v8::Local<v8::Int32> v = value->ToInt32();
429     return Dali::Property::Value(static_cast<int>(v->Value()));
430   }
431   return daliPropertyValue;
432
433 }
434
435 Property::Map GetPropertyMapFromObject( v8::Isolate* isolate, const v8::Local<v8::Object>& object)
436 {
437   v8::Local<v8::Array> properties = object->GetPropertyNames();
438   Property::Map propertyMap;    // empty map
439
440   for(  unsigned int i = 0; i <  properties->Length(); ++i)
441   {
442     // Get the key
443     v8::Local<v8::Value> key = properties->Get( i );
444     std::string keyString = v8StringToStdString( key );
445
446     // Get the value
447     v8::Local<v8::Value> value = object->Get( key );
448
449     if( value->IsBoolean() )
450     {
451       v8::Local<v8::Boolean> v = value->ToBoolean();
452       propertyMap[ keyString ] = v->Value();
453     }
454     else if( value->IsNumber() )
455     {
456       v8::Local<v8::Number> v = value->ToNumber();
457       propertyMap[ keyString ] = static_cast<float>(v->Value());
458     }
459     else if( value->IsInt32() || value->IsUint32() )
460     {
461       v8::Local<v8::Int32> v = value->ToInt32();
462       propertyMap[ keyString ] = static_cast<int>(v->Value());
463     }
464     else if( value->IsString() )
465     {
466       std::string valueString = V8Utils::v8StringToStdString( value );
467       propertyMap[ keyString ] = valueString.c_str();
468     }
469     else if( value->IsArray() )
470     {
471       propertyMap[ keyString ] = PropertyValueWrapper::VectorOrMatrixFromV8Array( isolate, value);
472     }
473   }
474
475   return propertyMap;
476 }
477
478 Actor GetActorFromObject( v8::Isolate* isolate, bool& found, v8::Local<v8::Object>& object)
479 {
480   v8::HandleScope handleScope( isolate);
481   found = false;
482
483   if( BaseWrappedObject::IsWrappedType ( isolate, object, BaseWrappedObject::ACTOR ))
484   {
485     HandleWrapper* handleWrapper = HandleWrapper::Unwrap( isolate, object );
486     return Actor::DownCast( handleWrapper->mHandle );
487   }
488   return Actor();
489 }
490
491
492 int GetIntegerParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args, int defaultValue  )
493 {
494   found = false;
495   unsigned int length = args.Length();
496   if( index >= length )
497   {
498     return defaultValue;
499   }
500   if( args[ index ]->IsInt32() )
501   {
502     found = true;
503     return args[ index ]->Int32Value();
504   }
505   else
506   {
507     return defaultValue;
508   }
509 }
510
511 float GetFloatParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args, float defaultValue  )
512 {
513   found = false;
514   unsigned int length = args.Length();
515   if( index >= length )
516   {
517     return defaultValue;
518   }
519   if( args[ index ]->IsNumber() )
520   {
521     found = true;
522     return args[ index ]->NumberValue();
523   }
524   else
525   {
526     return defaultValue;
527   }
528 }
529
530 std::string GetStringParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
531 {
532   found = false;
533   unsigned int length = args.Length();
534
535   if( index >= length )
536   {
537     return std::string();
538   }
539   if( args[ index ]->IsString() )
540   {
541     found = true;
542     return v8StringToStdString( args[ index ]);
543   }
544   else
545   {
546     return std::string();
547   }
548 }
549
550 bool GetBooleanParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
551 {
552   v8::HandleScope handleScope( isolate);
553
554   found = false;
555   unsigned int length = args.Length();
556   if( index >= length )
557   {
558     return false;
559   }
560   if( args[ index ]->IsBoolean() )
561   {
562     found = true;
563     v8::Local<v8::Boolean> v = args[ index ]->ToBoolean();
564     return v->Value();
565   }
566   else
567   {
568     return false;
569   }
570 }
571
572 void* GetArrayBufferViewParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args  )
573 {
574   found = false;
575   unsigned int length = args.Length();
576   if( index < length && args[index]->IsArrayBufferView() )
577   {
578     found = true;
579     v8::ArrayBufferView* bufferView = v8::ArrayBufferView::Cast(*(args[index]));
580     v8::Handle<v8::ArrayBuffer> buffer = bufferView->Buffer();
581     v8::ArrayBuffer::Contents contents = buffer->Externalize();
582     return contents.Data();
583   }
584   else
585   {
586     return NULL;
587   }
588 }
589
590 Handle GetHandleParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
591 {
592   v8::HandleScope handleScope( isolate);
593
594   found = false;
595   unsigned int length = args.Length();
596   if( index >= length )
597   {
598     return Handle();
599   }
600
601   if( args[ index ]->IsObject() )
602   {
603     v8::Local<v8::Object> object = args[ index ]->ToObject();
604     v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
605     void* ptr = field->Value();
606     if( ptr )
607     {
608         found = true;
609         HandleWrapper* wrapper = static_cast< HandleWrapper *>(ptr);
610         return wrapper->GetHandle();
611     }
612   }
613   return Handle();
614 }
615
616 Vector2 GetVector2Parameter( unsigned int index,  bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
617 {
618   v8::HandleScope handleScope( isolate);
619   unsigned int length =  args.Length();
620   Vector2 ret;
621   found = false;
622
623   if( index < length )
624   {
625     if( args[ index ]->IsObject() )
626     {
627       Dali::Property::Value value;
628       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR2 );
629       if( value.GetType() == Dali::Property::VECTOR2)
630       {
631         found = true;
632         value.Get(ret);
633       }
634       else
635       {
636         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector2 parameter");
637       }
638     }
639   }
640   else
641   {
642     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector2 parameter");
643   }
644
645   return ret;
646 }
647
648 Vector2 GetVector2ParameterFrom2Float( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
649 {
650   Vector2 ret(0.0f,0.0f);
651   bool bFound(false);
652   unsigned int argCount( args.Length() );
653
654   if( index+2 >= argCount )
655   {
656     DALI_SCRIPT_EXCEPTION(isolate, "Missing parameter");
657   }
658
659   found = true;
660   ret.x = V8Utils::GetFloatParameter( index, bFound, isolate, args, 0.0f );
661   found = found && bFound;
662   ret.y = V8Utils::GetFloatParameter( index+1, bFound, isolate, args, 0.0f );
663   found = found && bFound;
664
665   return ret;
666 }
667
668 Vector3 GetVector3Parameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args)
669 {
670   v8::HandleScope handleScope( isolate);
671   unsigned int argCount( args.Length() );
672   Vector3 ret;
673   found = false;
674   if( index < argCount )
675   {
676     if( args[ index ]->IsObject() )
677     {
678       Dali::Property::Value value;
679       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR3 );
680       if( value.GetType() == Dali::Property::VECTOR3)
681       {
682         found = true;
683         value.Get(ret);
684       }
685       else
686       {
687         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector3 parameter");
688       }
689     }
690   }
691   else
692   {
693     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector3 parameter");
694
695   }
696
697   return ret;
698 }
699
700 Vector4 GetVector4Parameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args)
701 {
702   v8::HandleScope handleScope( isolate);
703   unsigned int argCount( args.Length() );
704   Vector4 ret;
705   found = false;
706
707   if( index < argCount )
708   {
709     if( args[ index ]->IsObject() )
710     {
711       Dali::Property::Value value;
712       value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::VECTOR4 );
713       if( value.GetType() == Dali::Property::VECTOR4)
714       {
715         found = true;
716         value.Get(ret);
717       }
718       else
719       {
720         DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector4 parameter");
721       }
722     }
723   }
724   else
725   {
726     DALI_SCRIPT_EXCEPTION(isolate, "Missing Vector4 parameter");
727   }
728
729   return ret;
730 }
731
732
733 Rect<int> GetRectIntParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
734 {
735   v8::HandleScope handleScope( isolate);
736
737    found = false;
738    int length = args.Length() - index;
739
740    // if it's an array read the 2 numbers into a vector2
741    if( length == 4 )
742    {
743      if( args[ 0 + index ]->IsInt32() &&
744          args[ 1 + index ]->IsInt32() &&
745          args[ 2 + index ]->IsInt32() &&
746          args[ 3 + index ]->IsInt32() )
747      {
748        found = true;
749        Rect<int> rect( args[ 0 + index ]->Int32Value(),
750                        args[ 1 + index ]->Int32Value(),
751                        args[ 2 + index ]->Int32Value(),
752                        args[ 3 + index ]->Int32Value() );
753        return rect;
754      }
755    }
756    // this will extract a Vector4, if it is a Vector4 or a Javascript array object
757    if( args[ index ]->IsObject() )
758    {
759      Dali::Property::Value value;
760      value = PropertyValueWrapper::ExtractPropertyValue( isolate, args[index], Dali::Property::RECTANGLE );
761      if( value.GetType() == Dali::Property::RECTANGLE)
762      {
763        found = true;
764        Rect<int> rect;
765        value.Get(rect);
766        return rect;
767      }
768
769      // @todo support vector4 as well?
770    }
771    return Rect<int>();
772 }
773
774 Actor GetActorParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
775 {
776   BaseWrappedObject* wrapper = GetWrappedDaliObjectParameter( index, BaseWrappedObject::ACTOR, isolate, args);
777   ActorWrapper* actorWrapper = static_cast< ActorWrapper*>( wrapper );
778   if( actorWrapper )
779   {
780     found = true;
781     return actorWrapper->GetActor();
782   }
783   else
784   {
785     return Actor();
786   }
787 }
788
789 Layer GetLayerParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
790 {
791   Actor actor = GetActorParameter( index, found, isolate, args );
792   return Layer::DownCast( actor );
793 }
794
795 Image GetImageParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
796 {
797   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( index, BaseWrappedObject::IMAGE, isolate, args );
798   if( wrappedObject )
799   {
800     found = true;
801     ImageWrapper* wrapper = static_cast< ImageWrapper *>(wrappedObject);
802     return wrapper->GetImage();
803   }
804   else
805   {
806     return Image();
807   }
808
809 }
810
811 RenderTask GetRenderTaskParameter( unsigned int paramIndex, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
812 {
813   found = false;
814   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::RENDER_TASK, isolate, args );
815   if( wrappedObject )
816   {
817     found = true;
818     RenderTaskWrapper* wrapper = static_cast< RenderTaskWrapper *>(wrappedObject);
819     return wrapper->GetRenderTask();
820   }
821   else
822   {
823     return RenderTask(); // empty handle
824   }
825 }
826
827 BaseWrappedObject* GetWrappedDaliObjectParameter( unsigned int index,  BaseWrappedObject::Type type,  v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
828 {
829   v8::HandleScope handleScope( isolate);
830   unsigned int length = args.Length();
831
832   if( index >= length )
833   {
834     return NULL;
835   }
836
837   if( !args[ index ]->IsObject() )
838   {
839     return NULL;
840   }
841
842   v8::Local<v8::Object> object = args[ index ]->ToObject();
843
844   if( BaseWrappedObject::IsWrappedType ( isolate, object, type ))
845   {
846     v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
847     void* ptr = field->Value();
848     BaseWrappedObject* wrapper = static_cast< BaseWrappedObject *>(ptr);
849     return wrapper;
850   }
851   return NULL;
852 }
853
854
855 Property::Value GetPropertyValueParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
856 {
857   v8::HandleScope handleScope( isolate);
858
859   Property::Value  daliPropertyValue;// creates a property with Property::INVALID
860
861   found = false;
862   unsigned int length = args.Length();
863
864   if( index >= length )
865   {
866     return daliPropertyValue;
867   }
868   v8::Local<v8::Value > value = args[ index ];
869
870   return GetPropertyValueFromObject( found, isolate, value);
871 }
872
873 Property::Map GetPropertyMapParameter( unsigned int index, bool& found, v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
874 {
875   v8::HandleScope handleScope( isolate);
876
877   Property::Map propertyMap;    // empty map
878
879   found = false;
880   unsigned int length = args.Length();
881
882   if( index >= length )
883   {
884     return propertyMap;
885   }
886
887   if( !args[ index ]->IsObject() )
888   {
889     return propertyMap;
890   }
891   found = true;
892
893   // go through each key value pair
894   v8::Local<v8::Object> obj = args[ index ]->ToObject();
895
896   return GetPropertyMapFromObject( isolate, obj );
897
898 }
899
900 void CreatePropertyMap( v8::Isolate* isolate, const Property::Map& map, v8::Local<v8::Object>& object )
901 {
902   v8::HandleScope handleScope( isolate);
903
904   // we're converting a dali property map in to a JavaScript property map
905   if( map.Count() == 0 )
906   {
907     return;
908   }
909
910   for( unsigned int index = 0; index < map.Count() - 1; ++index )
911   {
912     const std::string& key = map.GetKey( index );
913     Property::Value& value = map.GetValue( index );
914     v8::Local<v8::Value> v8Value;
915
916     switch( value.GetType() )
917     {
918       case Dali::Property::FLOAT:
919       {
920         v8Value = v8::Number::New( isolate, value.Get<float>()  );
921         break;
922       }
923       case Dali::Property::BOOLEAN:
924       {
925         v8Value = v8::Boolean::New(  isolate, value.Get<bool>());
926         break;
927       }
928       case Dali::Property::INTEGER:
929       {
930         v8Value = v8::Integer::New( isolate, value.Get<int>());
931         break;
932       }
933       case Dali::Property::STRING:
934       {
935         std::string string = value.Get< std::string >();
936         v8Value = v8::String::NewFromUtf8( isolate,  string.c_str());
937         break;
938       }
939       case Dali::Property::VECTOR2:
940       {
941         // create a vector2
942         Vector2 vec = value.Get<Vector2>();
943         v8::Local<v8::Array> array= v8::Array::New( isolate, 2 );
944         array->Set( 0 , v8::Number::New(isolate, vec.x));
945         array->Set( 1 , v8::Number::New(isolate, vec.y));
946         v8Value = array;
947         break;
948       }
949       case Dali::Property::VECTOR3:
950       {
951         // create a vector 3
952         Vector3 vec = value.Get<Vector3>();
953         v8::Local<v8::Array> array= v8::Array::New( isolate, 3 );
954         array->Set( 0 , v8::Number::New(isolate, vec.x));
955         array->Set( 1 , v8::Number::New(isolate, vec.y));
956         array->Set( 2 , v8::Number::New(isolate, vec.z));
957         v8Value = array;
958         break;
959       }
960       case Dali::Property::VECTOR4:
961       {
962         // create a vector 4
963         Vector4 vec = value.Get<Vector4>();
964         v8::Local<v8::Array> array= v8::Array::New( isolate, 4 );
965         array->Set( 0 , v8::Number::New(isolate, vec.x));
966         array->Set( 1 , v8::Number::New(isolate, vec.y));
967         array->Set( 2 , v8::Number::New(isolate, vec.z));
968         array->Set( 3 , v8::Number::New(isolate, vec.w));
969         v8Value = array;
970         break;
971       }
972
973       default:
974       {
975         DALI_SCRIPT_EXCEPTION( isolate, "Primitive mismatch \n");
976         return;
977       }
978     }
979     object->Set( v8::String::NewFromUtf8( isolate, key.c_str() ), v8Value );
980   }
981 }
982
983 void ReadFloatArguments( bool& foundAllArguments, float* data, unsigned int dataSize, const v8::FunctionCallbackInfo< v8::Value >& args, float defaultValue )
984 {
985   foundAllArguments = true;
986   unsigned int length = args.Length();
987
988   if( length < dataSize )
989   {
990     foundAllArguments = false;
991   }
992
993   for( unsigned int i = 0; i< dataSize ;i++ )
994   {
995     if( i < length )
996     {
997       if( args[ i ]->IsNumber()  )
998       {
999         data[i] = args[i]->NumberValue();
1000       }
1001       else
1002       {
1003         data[i] = defaultValue;
1004         foundAllArguments = false;   // bad argument
1005       }
1006     }
1007     else
1008     {
1009       data[i] = defaultValue; // not enough arguments
1010     }
1011   }
1012
1013 }
1014
1015 void ReadIntegerArguments( bool& foundAllArguments, int* data, int dataSize, const v8::FunctionCallbackInfo< v8::Value >& args, int defaultValue )
1016 {
1017   foundAllArguments = true;
1018   int length = args.Length();
1019   if( length < dataSize )
1020   {
1021     foundAllArguments = false;
1022   }
1023
1024   for( int i = 0; i< dataSize ;i++ )
1025   {
1026     if( i < length )
1027     {
1028       if( args[ i ]->IsInt32()  )
1029       {
1030         data[i] = args[i]->Int32Value();
1031       }
1032       else
1033       {
1034         data[i] = defaultValue;
1035         foundAllArguments = false;   // bad argument
1036       }
1037     }
1038     else
1039     {
1040       data[i] = defaultValue; // not enough arguments
1041     }
1042   }
1043
1044 }
1045 } // namespace V8Utils
1046
1047 } // namespace V8Plugin
1048
1049 } // namespace Dali