void EJBindingImage::endLoad(EJTexture * tex) { loading = false; tex->retain(); texture = tex; if( tex->textureId ) { EJBindingEventedBase::triggerEvent(NSStringMake("load") ,0 ,NULL); } else { EJBindingEventedBase::triggerEvent(NSStringMake("error") ,0 ,NULL); } }
EJCanvasContext::EJCanvasContext(short widthp, short heightp) : viewFrameBuffer(0), viewRenderBuffer(0), msaaFrameBuffer(0), msaaRenderBuffer(0), stencilBuffer(0),vertexBufferIndex(0) { memset(stateStack, 0, sizeof(stateStack)); stateIndex = 0; state = &stateStack[stateIndex]; state->globalAlpha = 1; state->globalCompositeOperation = kEJCompositeOperationSourceOver; state->transform = CGAffineTransformIdentity; state->lineWidth = 1; state->lineCap = kEJLineCapButt; state->lineJoin = kEJLineJoinMiter; state->miterLimit = 10; state->textBaseline = kEJTextBaselineAlphabetic; state->textAlign = kEJTextAlignStart; //state->font = [[UIFont fontWithName:@"Helvetica" size:10] retain]; state->font = new UIFont(NSStringMake("simsun.ttc"),32); state->clipPath = NULL; setScreenSize(widthp, heightp); path = new EJPath(); backingStoreRatio = 1; fontCache = new NSCache(); fontCache->setCountLimit(8); imageSmoothingEnabled = true; msaaEnabled = false; msaaSamples = 2; }
JSValueRef EJApp::loadModuleWithId(NSString * moduleId, JSValueRef module, JSValueRef exports) { NSString * path = NSStringMake(moduleId->getCString() + string(".js")); NSString * script = NSString::createWithContentsOfFile(pathForResource(path)->getCString()); if( !script ) { NSLog("Error: Can't Find Module %s", moduleId->getCString() ); return NULL; } NSLog("Loading Module: %s", moduleId->getCString() ); JSStringRef scriptJS = JSStringCreateWithUTF8CString(script->getCString()); JSStringRef pathJS = JSStringCreateWithUTF8CString(path->getCString()); JSStringRef parameterNames[] = { JSStringCreateWithUTF8CString("module"), JSStringCreateWithUTF8CString("exports"), }; JSValueRef exception = NULL; JSObjectRef func = JSObjectMakeFunction( jsGlobalContext, NULL, 2, parameterNames, scriptJS, pathJS, 0, &exception ); JSStringRelease( scriptJS ); JSStringRelease( pathJS ); JSStringRelease(parameterNames[0]); JSStringRelease(parameterNames[1]); if( exception ) { logException(exception, jsGlobalContext); return NULL; } JSValueRef params[] = { module, exports }; return invokeCallback(func, NULL, 2, params); }
EJ_BIND_FUNCTION(EJBindingHttpRequest, abort, ctx, argc, argv) { if (connection) { clearConnection(); EJBindingEventedBase::triggerEvent(NSStringMake("abort"), 0, NULL); } return NULL; }
EJ_BIND_FUNCTION( EJBindingCanvas, getContext, ctx, argc, argv) { NSLOG("Canvas.getContext('2d'), firstCanvasInstance %d, isScreenCanvas : %d", firstCanvasInstance, isScreenCanvas); if( argc < 1 || !JSValueToNSString(ctx, argv[0])->isEqual(NSStringMake("2d")) ) { return NULL; }; if( renderingContext ) { return jsObject; } ejectaInstance->currentRenderingContext = NULL; if( isScreenCanvas ) { NSLOG("get Screen Canvas Context"); EJCanvasContextScreen * sc = new EJCanvasContextScreen(width, height); sc->useRetinaResolution = useRetinaResolution; sc->scalingMode = scalingMode; ejectaInstance->screenRenderingContext = sc; renderingContext = (EJCanvasContext*)sc; } else { NSLOG("get Texture Canvas Context"); renderingContext = (EJCanvasContext*)(new EJCanvasContextTexture(width, height)); } renderingContext->msaaEnabled = msaaEnabled; renderingContext->msaaSamples = msaaSamples; renderingContext->create(); ejectaInstance->currentRenderingContext = renderingContext; // Context and canvas are one and the same object, so getContext just // returns itself return jsObject; }
EJ_BIND_FUNCTION(EJBindingHttpRequest, getAllResponseHeaders, ctx, argc, argv) { if (!response) { return NULL; } NSString *headers = NSStringMake(""); return NSStringToJSValue(ctx, headers); }
EJTexture::EJTexture(int widthp, int heightp, GLenum formatp) : textureId(0), width(0), height(0), realWidth(0), realHeight(0) { // Create an empty texture contentScale = 1; NSString* empty = NSStringMake("[Empty]"); empty->retain(); fullPath = empty; setWidthAndHeight(widthp, heightp); createTextureWithPixels(NULL, formatp); }
void EJBindingHttpRequest::onHttpRequestCompleted(NSObject *sender, void *data) { response = (EJHttpResponse *)data; if (!response) { return; } state = kEJHttpRequestStateDone; // You can get original request type from: response->request->reqType if (0 != strlen(response->getHttpRequest()->getTag())) { NSLOG("%s completed", response->getHttpRequest()->getTag()); } int statusCode = response->getResponseCode(); char statusString[64] = {}; sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag()); NSLOG("response code: %d", statusCode); if (!response->isSucceed()) { NSLOG("response failed"); NSLOG("error buffer: %s", response->getErrorBuffer()); response->retain(); responseBody = NULL; EJBindingEventedBase::triggerEvent(NSStringMake("loadend"), 0, NULL); EJBindingEventedBase::triggerEvent(NSStringMake("readystatechange"), 0, NULL); return; } std::vector<char> *buffer = response->getResponseData(); response->retain(); requestSource = kEJHttpRequestSourceHttp; responseBodySize = buffer->size(); responseBody = (char *)malloc(sizeof(char) * responseBodySize); memcpy(responseBody, &((*buffer)[0]), sizeof(char) * responseBodySize); EJBindingEventedBase::triggerEvent(NSStringMake("loadend"), 0, NULL); EJBindingEventedBase::triggerEvent(NSStringMake("readystatechange"), 0, NULL); }
NSString * EJBindingHttpRequest::getResponseText() { if( !response || !responseBody ) { return NULL; } // NSStringEncoding encoding = NSASCIIStringEncoding; // if ( response.textEncodingName ) { // CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef) [response textEncodingName]); // if( cfEncoding != kCFStringEncodingInvalidId ) { // encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding); // } // } return NSStringMake(responseBody); }
void EJApp::init(const char* path, int w, int h) { if(mainBundle) free(mainBundle); int len = (strlen(path) + 1); mainBundle = (char *)malloc(len * sizeof(char)); memset(mainBundle, 0, len); snprintf(mainBundle, len, "%s", path); height = h; width = w; // Load the initial JavaScript source files // loadScriptAtPath(NSStringMake(EJECTA_BOOT_JS)); loadScriptAtPath(NSStringMake(EJECTA_MAIN_JS)); }
EJ_BIND_SET( EJBindingCanvas,font, ctx, value) { char string[64]; // Long font names are long JSStringRef jsString = JSValueToStringCopy( ctx, value, NULL ); JSStringGetUTF8CString(jsString, string, 64); // Yeah, oldschool! float size = 0; char name[64]; sscanf( string, "%fp%*[tx] %63s", &size, name); // matches: 10.5p[tx] helvetica UIFont * newFont = new UIFont(NSStringMake("droidsans.ttf"),size); if( newFont ) { renderingContext->state->font->release(); renderingContext->state->font = newFont; } JSStringRelease(jsString); }
EJTexture::EJTexture(int widthp, int heightp, GLubyte * pixels) : textureId(0), width(0), height(0), realWidth(0), realHeight(0) { // Creates a texture with the given pixels contentScale = 1; NSString* empty = NSStringMake("[From Pixels]"); empty->retain(); fullPath = empty; setWidthAndHeight(widthp, heightp); if( width != realWidth || height != realHeight ) { GLubyte * pixelsPow2 = (GLubyte *)calloc( realWidth * realHeight * 4, sizeof(GLubyte) ); for( int y = 0; y < height; y++ ) { memcpy( &pixelsPow2[y*realWidth*4], &pixels[y*width*4], width * 4 ); } createTextureWithPixels(pixelsPow2, GL_RGBA); free(pixelsPow2); } else { createTextureWithPixels(pixels, GL_RGBA); } }
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++; }
EJ_BIND_FUNCTION(EJBindingHttpRequest, send, ctx, argc, argv) { if (!method || !url) { return NULL; } clearConnection(); NSLOG("XHR: URL %s ", url->getCString()); Uri u0 = Uri::Parse(string(url->getCString())); std::string host = u0.Host; EJHttpRequest* request = new EJHttpRequest(); request->setUrl(url->getCString()); // if( !requestUrl.host ) { // No host? Assume we have a local file // requestUrl = [NSURL fileURLWithPath:[[EJApp instance] pathForResource:url]]; // } if (host.empty()) { NSLOG("no host"); EJBindingHttpRequest::loadLocalhost(); return NULL; } // NSURL * requestUrl = [NSURL URLWithString:url]; // NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:requestUrl]; // [request setHTTPMethod:method]; // for( NSString * header in requestHeaders ) { // [request setValue:[requestHeaders objectForKey:header] forHTTPHeaderField:header]; // } // if( argc > 0 ) { // NSString * requestBody = JSValueToNSString( ctx, argv[0] ); // NSData * requestData = [NSData dataWithBytes:[requestBody UTF8String] length:[requestBody length]]; // [request setHTTPBody:requestData]; // } // if( timeout ) { // NSTimeInterval timeoutSeconds = (float)timeout/1000.0f; // [request setTimeoutInterval:timeoutSeconds]; // } if (method->isEqual(NSStringMake("GET"))) { request->setRequestType(EJHttpRequest::kHttpGet); } else if (method->isEqual(NSStringMake("POST"))) { request->setRequestType(EJHttpRequest::kHttpPost); } else if (method->isEqual(NSStringMake("PUT"))) { request->setRequestType(EJHttpRequest::kHttpPut); } else if (method->isEqual(NSStringMake("DELETE"))) { request->setRequestType(EJHttpRequest::kHttpDelete); } else { request->setRequestType(EJHttpRequest::kHttpUnkown); } request->setResponseCallback(this, callfuncND_selector(EJBindingHttpRequest::onHttpRequestCompleted)); connection = EJHttpClient::getInstance(); connection->setTimeoutForConnect(timeout/1000); NSLOG("XHR: %s %s", method->getCString(), url->getCString()); EJBindingEventedBase::triggerEvent(NSStringMake("loadstart"), 0, NULL); // if( async ) { // state = kEJHttpRequestStateLoading; // connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; // } // else { // NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; // responseBody = [[NSMutableData alloc] initWithData:data]; // [response retain]; // state = kEJHttpRequestStateDone; // if( [response isKindOfClass:[NSHTTPURLResponse class]] ) { // NSHTTPURLResponse * urlResponse = (NSHTTPURLResponse *)response; // if( urlResponse.statusCode == 200 ) { // [self triggerEvent:@"load" argc:0 argv:NULL]; // } // } // else { // [self triggerEvent:@"load" argc:0 argv:NULL]; // } // [self triggerEvent:@"loadend" argc:0 argv:NULL]; // [self triggerEvent:@"readystatechange" argc:0 argv:NULL]; // } // [request release]; state = kEJHttpRequestStateLoading; connection->send(request); request->release(); EJBindingEventedBase::triggerEvent(NSStringMake("load"), 0, NULL); return NULL; }
void EJBindingHttpRequest::loadLocalhost() { state = kEJHttpRequestStateLoading; // No host? Assume we have a local file EJBindingEventedBase::triggerEvent(NSStringMake("loadstart"), 0, NULL); EJBindingEventedBase::triggerEvent(NSStringMake("load"), 0, NULL); // Check file from cache - /data/data/ NSString *urlPath = EJApp::instance()->pathForResource(url); unsigned long size = 0; unsigned char *pData = 0; NSLOG("Search data: %s", urlPath->getCString()); pData = NSString::createFileData(urlPath->getCString(), "rb", &size); if (pData) { // Data was found NSLOG("Data found in data/data"); requestSource = kEJHttpRequestSourceData; responseBodySize = size; responseBody = (char *)pData; } else { NSLOG("Checking in bundle"); // Check file from main bundle - /assets/EJECTA_APP_FOLDER/ if (EJApp::instance()->aassetManager == NULL) { NSLOG("Error loading asset manager"); return; } const char *filename = urlPath->getCString(); // "dirname/filename.ext"; // Open file AAsset *asset = AAssetManager_open(EJApp::instance()->aassetManager, filename, AASSET_MODE_UNKNOWN); if (NULL == asset) { NSLOG("Error: Cannot find script %s", filename); return; } long size = AAsset_getLength(asset); unsigned char *buffer = (unsigned char *)malloc(sizeof(char) * size); int result = AAsset_read(asset, buffer, size); if (result < 0) { NSLOG("Error reading file %s", filename); AAsset_close(asset); free(buffer); return; } requestSource = kEJHttpRequestSourceAssets; responseBodySize = result; responseBody = (char *)buffer; AAsset_close(asset); } state = kEJHttpRequestStateDone; // A response Object was never added to the response queue so we do not have // anything to clean on the network thread, but we must create a fake response // to hold the response code etc. // Set a response code and emit events response = new EJHttpResponse(NULL); response->setResponseCode(200); // Emit events EJBindingEventedBase::triggerEvent(NSStringMake("loadend"), 0, NULL); EJBindingEventedBase::triggerEvent(NSStringMake("readystatechange"), 0, NULL); }
NSString * EJApp::pathForResource(NSString * resourcePath) { string full_path = string(mainBundle) + string("/") + string(EJECTA_APP_FOLDER) + resourcePath->getCString(); return NSStringMake(full_path); }