Sirikata
liboh/plugins/js/JSObjects/JSInvokableUtil.hpp
Go to the documentation of this file.
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_