Sirikata
|
00001 /* Sirikata 00002 * JSInvokableUtil.cpp 00003 * 00004 * Copyright (c) 2011, Ewen Cheslack-Postava 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #ifndef _SIRIKATA_JS_INVOKABLE_UTIL_HPP_ 00034 #define _SIRIKATA_JS_INVOKABLE_UTIL_HPP_ 00035 00036 #include "JSFunctionInvokable.hpp" 00037 #include "JSInvokableObject.hpp" 00038 #include <sirikata/proxyobject/Invokable.hpp> 00039 #include "JSVisible.hpp" 00040 #include "../EmersonScript.hpp" 00041 #include "../JSObjectStructs/JSVisibleStruct.hpp" 00042 #include "JSPresence.hpp" 00043 #include "../JSObjectStructs/JSPresenceStruct.hpp" 00044 00045 namespace Sirikata { 00046 namespace JS { 00047 namespace InvokableUtil { 00048 00052 inline boost::any V8ToAny(EmersonScript* parent, v8::Handle<v8::Value> val) 00053 { 00054 /* Pushing only string params for now */ 00055 if(val->IsString()) 00056 { 00057 v8::String::Utf8Value str(val); 00058 std::string s = FromV8String(str); 00059 return Invokable::asAny(s); 00060 } 00061 else if(val->IsFunction()) 00062 { 00063 v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(val); 00064 v8::Persistent<v8::Function> function_persist = v8::Persistent<v8::Function>::New(function); 00065 00066 JSFunctionInvokable* invokable = new JSFunctionInvokable(function_persist, parent); 00067 Sirikata::Invokable* in = invokable; 00068 return Invokable::asAny(in); 00069 } 00070 else if (val->IsBoolean()) { 00071 return Invokable::asAny(val->BooleanValue()); 00072 } 00073 else if (val->IsNumber()) { 00074 return Invokable::asAny((float64)val->NumberValue()); 00075 } 00076 else if (val->IsObject()) { 00077 // Handle special types 00078 if ( JSVisible::isVisibleObject(val) ) { 00079 std::string errmsg; 00080 JSVisibleStruct* jsvis = JSVisibleStruct::decodeVisible(val,errmsg); 00081 return Invokable::asAny((jsvis->getSporef())); 00082 } 00083 else if ( JSPresence::isPresence(val) ) { 00084 std::string errmsg; 00085 JSPresenceStruct* jspres = JSPresenceStruct::decodePresenceStruct(val,errmsg); 00086 return Invokable::asAny(jspres->getSporef()); 00087 } 00088 00089 // Otherwise do normal translation 00090 return boost::any(); // FIXME 00091 } 00092 return boost::any(); 00093 } 00094 00095 00099 inline v8::Handle<v8::Value> AnyToV8( 00100 EmersonScript* parent, const boost::any& val) 00101 { 00102 if(Invokable::anyIsString(val)) { 00103 std::string s = Invokable::anyAsString(val); 00104 return v8::String::New(s.c_str(), s.length()); 00105 } 00106 else if(Invokable::anyIsFloat(val)) { 00107 double s = Invokable::anyAsFloat(val); 00108 return v8::Number::New(s); 00109 } 00110 else if(Invokable::anyIsDouble(val)) { 00111 double s = Invokable::anyAsDouble(val); 00112 return v8::Number::New(s); 00113 } 00114 else if (val.type() == typeid(uint8)) { 00115 uint32 d = boost::any_cast<uint8>(val); 00116 return v8::Uint32::New(d); 00117 } 00118 else if (val.type() == typeid(uint16)) { 00119 uint32 d = boost::any_cast<uint16>(val); 00120 return v8::Uint32::New(d); 00121 } 00122 else if (val.type() == typeid(uint32)) { 00123 uint32 d = boost::any_cast<uint32>(val); 00124 return v8::Uint32::New(d); 00125 } 00126 else if (val.type() == typeid(uint64)) { 00127 uint32 d = boost::any_cast<uint64>(val); 00128 return v8::Uint32::New(d); 00129 } 00130 else if (val.type() == typeid(int8)) { 00131 int32 d = boost::any_cast<int8>(val); 00132 return v8::Int32::New(d); 00133 } 00134 else if (val.type() == typeid(int16)) { 00135 int32 d = boost::any_cast<int16>(val); 00136 return v8::Int32::New(d); 00137 } 00138 else if (val.type() == typeid(int32)) { 00139 int32 d = boost::any_cast<int32>(val); 00140 return v8::Int32::New(d); 00141 } 00142 else if (val.type() == typeid(int64)) { 00143 int32 d = boost::any_cast<int64>(val); 00144 return v8::Int32::New(d); 00145 } 00146 else if(Invokable::anyIsBoolean(val)) { 00147 bool s = Invokable::anyAsBoolean(val); 00148 return v8::Boolean::New(s); 00149 } 00150 else if(Invokable::anyIsArray(val)) { 00151 Sirikata::Invokable::Array native_arr = Invokable::anyAsArray(val); 00152 v8::Local<v8::Array> arr = v8::Array::New(); 00153 for(uint32 ii = 0; ii < native_arr.size(); ii++) { 00154 v8::Handle<v8::Value> rhs = AnyToV8(parent, native_arr[ii]); 00155 if (!rhs.IsEmpty()) 00156 arr->Set(ii, rhs); 00157 } 00158 return arr; 00159 } 00160 else if(Invokable::anyIsDict(val)) { 00161 Sirikata::Invokable::Dict native_dict = Invokable::anyAsDict(val); 00162 v8::Local<v8::Object> dict = v8::Object::New(); 00163 for(Sirikata::Invokable::Dict::const_iterator di = native_dict.begin(); di != native_dict.end(); di++) { 00164 v8::Handle<v8::Value> rhs = AnyToV8(parent, di->second); 00165 if (!rhs.IsEmpty()) 00166 dict->Set(v8::String::New(di->first.c_str(), di->first.size()), rhs); 00167 } 00168 return dict; 00169 } 00170 else if(Invokable::anyIsInvokable(val)) { 00171 if (!parent) return v8::Handle<v8::Value>(); 00172 Invokable* newInvokableObj = Invokable::anyAsInvokable(val); 00173 Local<Object> tmpObj = parent->JSObjectScript::mCtx->mInvokableObjectTemplate->NewInstance(); 00174 Persistent<Object>tmpObjP = Persistent<Object>::New(tmpObj); 00175 tmpObjP->SetInternalField(JSINVOKABLE_OBJECT_JSOBJSCRIPT_FIELD,External::New(parent)); 00176 tmpObjP->SetInternalField(JSINVOKABLE_OBJECT_SIMULATION_FIELD,External::New( new JSInvokableObject::JSInvokableObjectInt(newInvokableObj) )); 00177 tmpObjP->SetInternalField(TYPEID_FIELD,External::New( new String (JSINVOKABLE_TYPEID_STRING))); 00178 return tmpObjP; 00179 } 00180 else if(Invokable::anyIsObject(val)) { 00181 SpaceObjectReference obj = Invokable::anyAsObject(val); 00182 if (obj == SpaceObjectReference::null()) return v8::Handle<v8::Value>(); 00183 return parent->findVisible(obj); 00184 } 00185 00186 return v8::Handle<v8::Value>(); 00187 } 00188 00189 } // namespace InvokableUtil 00190 } // namespace JS 00191 } // namespace Sirikata 00192 00193 #endif //_SIRIKATA_JS_INVOKABLE_UTIL_HPP_