JSValueRef ej_getNativeClass(JSContextRef ctx, JSObjectRef object, JSStringRef propertyNameJS, JSValueRef* exception) { size_t classNameSize = JSStringGetMaximumUTF8CStringSize(propertyNameJS); char* className = (char*)malloc(classNameSize); JSStringGetUTF8CString(propertyNameJS, className, classNameSize); JSObjectRef obj = NULL; NSString * fullClassName = new NSString(); NSLOG("ej_getNativeClass : EJBinding%s", className); fullClassName->initWithFormat("EJBinding%s",className); EJBindingBase* pClass = (EJBindingBase*)NSClassFromString(fullClassName->getCString()); if( pClass ) { obj = JSObjectMake( ctx, ej_constructorClass, (void *)pClass ); } else { NSLOG("%s is NULL ... ", fullClassName->getCString()); } if (obj) { NSLOG("constructor js-obj for %s", className); } free(className); fullClassName->autorelease(); return obj ? obj : ej_global_undefined; }
JSObjectRef ej_callAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argc, const JSValueRef argv[], JSValueRef* exception) { EJBindingBase* pClass = (EJBindingBase*)(JSObjectGetPrivate( constructor )); NSLOG("ej_callAsConstructor constructor: %s()", pClass->toString().c_str()); JSClassRef jsClass = EJApp::instance()->getJSClassForClass(pClass); JSObjectRef obj = JSObjectMake( ctx, jsClass, NULL ); EJBindingBase* instance = (EJBindingBase*)NSClassFromString(pClass->toString().c_str()); instance->init(ctx, obj, argc, argv); NSLOG("binding constructor: %s", instance->toString().c_str()); JSObjectSetPrivate( obj, (void *)instance ); return obj; }
JSClassRef EJBindingBase::getJSClass (EJBindingBase* ej_obj){ // Gather all class methods that return C callbacks for this class or it's parents NSDictionary * methods = new NSDictionary(); NSDictionary * properties = new NSDictionary(); string base_obj = ej_obj->toString(); NSObjectFactory::fuc_map_type* base = NSObjectFactory::getFunctionMap(); for(NSObjectFactory::fuc_map_type::iterator it = base->begin(); it != base->end(); it++) { string name = it->first; string base_obj_tmp = base_obj; if( name.find("_func_") != string::npos ) { int pos = name.find("_func_"); int is_member_func = name.find(base_obj_tmp); bool n_pos = (is_member_func == string::npos); while(n_pos) { EJBindingBase* pClass = (EJBindingBase*)NSClassFromString(base_obj_tmp); base_obj_tmp = pClass->superclass(); is_member_func = name.find(base_obj_tmp); if ((is_member_func != string::npos) || (base_obj_tmp.find("EJBindingBase") != string::npos)) { n_pos = false; } } if (is_member_func != string::npos) { methods->setObject(NSStringMake(name.substr(pos + strlen("_func_"))), name); } } else if( name.find("_get_") != string::npos ) { int pos = name.find("_get_"); int is_member_func = name.find(base_obj_tmp); bool n_pos = (is_member_func == string::npos); while(n_pos) { EJBindingBase* pClass = (EJBindingBase*)NSClassFromString(base_obj_tmp); base_obj_tmp = pClass->superclass(); is_member_func = name.find(base_obj_tmp); if ((is_member_func != string::npos) || (base_obj_tmp.find("EJBindingBase") != string::npos)) { n_pos = false; } } if (is_member_func != string::npos) { // We only look for getters - a property that has a setter, but no getter will be ignored properties->setObject(NSStringMake(name.substr(pos + strlen("_get_"))), name); } } } // Set up the JSStaticValue struct array JSStaticValue * values = (JSStaticValue *)calloc( properties->count() + 1, sizeof(JSStaticValue) ); int i = 0; NSDictElement* pElement = NULL; NSObject* pObject = NULL; NSDICT_FOREACH(properties, pElement) { pObject = pElement->getObject()->copy(); string key_name = pElement->getStrKey(); NSString* name = (NSString*)pObject; char * nameData = NSDataFromString( name ); char** p_name = const_cast<char**>(&values[i].name); *p_name = nameData; values[i].attributes = kJSPropertyAttributeDontDelete; SEL get = NSSelectorFromString(key_name); values[i].getProperty = (JSObjectGetPropertyCallback)get; // Property has a setter? Otherwise mark as read only int pos = key_name.find("_get_"); key_name = key_name.replace(pos, strlen("_get_"), "_set_"); SEL set = NSSelectorFromString(key_name); if( set ) { values[i].setProperty = (JSObjectSetPropertyCallback)set; } else { values[i].attributes |= kJSPropertyAttributeReadOnly; } i++; }