view dstep/objc/objc.d @ 20:6255d355d752

Made it compile with dmd 1.056
author Jacob Carlborg <doob@me.com>
date Wed, 03 Feb 2010 18:28:01 +0100
parents 19885b43130e
children 420969b22201
line wrap: on
line source

/**
 * Copyright: Copyright (c) 2009 Jacob Carlborg.
 * Authors: Jacob Carlborg
 * Version: Initial created: Feb 1, 2009
 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
 */
module dstep.objc.objc;

import dstep.internal.String;
import dstep.internal.Types;
import bindings = dstep.objc.bindings;
import dstep.objc.message;
import dstep.objc.runtime;

import mambo.io;

alias objc_object* id;
alias objc_class* Class;
alias objc_selector* SEL;
alias extern (C) id function(id self, SEL op, ...) IMP;
alias bool BOOL;
alias char* STR;

alias typeof(null) Nil;
alias typeof(null) nil;

alias c_long arith_t;
alias c_ulong uarith_t;

const bool YES = true;
const bool NO = false;

struct objc_object
{
	Class isa;
	
	// D Extensions:
	
	string getClassName ()
	{
		return fromStringz(bindings.object_getClassName(this));
	}
	
	Ivar setInstanceVariable (T, string name) (T value)
	{
		return bindings.object_setInstanceVariable(this, name.ptr, value);
	}
	
	Ivar getInstanceVariable (T, string name) (out T outValue)
	{
		return bindings.object_getInstanceVariable(this, name.ptr, &outValue);
	}
	
	objc_property_t* getProperty (string name, bool isRequiredProperty, bool isInstanceProperty)
	{
		return bindings.protocol_getProperty(this, name.toStringz(), isRequiredProperty, isInstanceProperty);
	}

	objc_property_t* copyPropertyList (out uint outCount)
	{
		return bindings.protocol_copyPropertyList(this, &outCount);
	}

	Protocol** copyProtocolList (out uint outCount)
	{
		return bindings.protocol_copyProtocolList(this, &outCount);
	}
	
	string getName ()
	{
		return fromStringz(bindings.protocol_getName(this));
	}
	
	objc_method_description* copyMethodDescriptionList (bool isRequiredMethod, bool isInstanceMethod, out uint outCount)
	{
		return bindings.protocol_copyMethodDescriptionList(this, isRequiredMethod, isInstanceMethod, &outCount);
	}
	
	id copy (size_t size)
	{
		return bindings.object_copy(this, size);
	}
	
	id dispose ()
	{
		return bindings.object_dispose(this);
	}
	
	Class getClass ()
	{
		return bindings.object_getClass(this);
	}
	
	Class setClass (Class cls)
	{
		return bindings.object_setClass(this, cls);
	}
	
	void* getIndexedIvars ()
	{
		return bindings.object_getIndexedIvars(this);
	}
	
	id getIvar (Ivar ivar)
	{
		return bindings.object_getIvar(this, ivar);
	}
	
	void setIvar (Ivar ivar, Protocol* value)
	{
		return bindings.object_setIvar(this, ivar, value);
	}
	
	bool conformsToProtocol (Protocol* other)
	{
		return bindings.protocol_conformsToProtocol(this, other);
	}
	
	bool isEqual (id other)
	{
		return bindings.protocol_isEqual(this, other);
	}
	
	objc_method_description getMethodDescription (SEL aSel, bool isRequiredMethod, bool isInstanceMethod)
	{
		return bindings.protocol_getMethodDescription(this, aSel, isRequiredMethod, isInstanceMethod);
	}
	
	
	
	// message.h

	R msgSend (R = id, ARGS...) (SEL op, ARGS args)
	{
		alias extern (C) R function (id, SEL, ARGS) fp;
		return (cast(fp)&bindings.objc_msgSend)(this, op, args);
	}

	void msgSend_stret (T, ARGS...) (out T stretAddr, SEL op, ARGS args)
	{
		if (T.sizeof > STRUCT_SIZE_LIMIT)
		{
			alias extern (C) void function (T*, id, SEL, ARGS...) fp;
			(cast(fp)&bindings.objc_msgSend_stret)(&stretAddr, this, op, args);
		}			
		    
		else
		{
			alias extern (C) T function (id, SEL, ARGS) fp;
			stretAddr = (*cast(fp)&bindings.objc_msgSend)(this, op, args);
		}  
	}

	static if (dstep.internal.Version.X86 || dstep.internal.Version.X86_64)
	{
		R msgSend_fpret (R, ARGS...) (SEL op, ARGS args)
		{
			version (X86_64)
				static assert(is(R == real), "dstep.objc.objc.objc_object.msgSend_fpret: Only real are legal return value for objc_msgSend_fpret");
			
			else
				static assert(is(R == double) || is(R == float), "dstep.objc.objc.objc_object.msgSend_fpret: Only double and float are legal return values for objc_msgSend_fpret");
				
			alias extern (C) R function (id, SEL, ARGS) fp;
			return (cast(fp)&bindings.objc_msgSend_fpret)(this, op, args);
		}
	}

	R invoke (R = id, ARGS...) (Method m, ARGS args)
	{
		alias extern (C) R function (id, SEL, ARGS) fp;
		return (cast(fp)&bindings.method_invoke)(this, m, args);
	}

	void invoke_stret (ARGS...) (Method m, ARGS args)
	{
		alias extern (C) R function (id, SEL, ARGS) fp;
		return (cast(fp)&bindings.method_invoke_stret)(this, m, args);
	}

	R msgSendv (R = id, T) (SEL op, size_t arg_size, T arg_frame)
	{
		alias extern (C) R function (id, SEL, size_t, T) fp;
		(cast(fp)&bindings.objc_msgSendv)(this, op, arg_size, arg_frame);
	}

	void msgSendv_stret (R = id, T) (out T stretAddr, SEL op, size_t arg_size, T arg_frame)
	{
	    if (R.sizeof > STRUCT_SIZE_LIMIT)
	    {
	    	alias extern (C) void function (R*, id, SEL, size_t, T) fp;
	    	(cast(fp)&bindings.objc_msgSendv_stret)(&stretAddr, this, op, arg_size, arg_frame);
	    }
	    
	    else
	    {
	    	alias extern (C) R function (id, SEL, size_t, T) fp;
	    	stretAddr = (*cast(fp)&bindings.objc_msgSendv)(this, op, arg_size, arg_frame);
	    }
	}

	version (X86)
	{
		R msgSendv_fpret (R = id, T) (SEL op, uint arg_size, T arg_frame)
		{
			static assert(!is(R == double) && !is(R == float), "dstep.objc.objc.objc_object.msgSend_fpret: Only double and float are legal return values for objc_msgSendv_fpret");
			alias extern (C) R function (id, SEL, uint, T) fp;
			return (cast(fp)&bindings.objc_msgSendv_fpret)(this, op, arg_size, arg_frame);
		}
	}
}

struct objc_selector
{
	void* sel_id;
	char* sel_types;
	
	
	
	// D Extensions:
	
	string getName ()
	{
		return fromStringz(bindings.sel_getName(this));
	}
	
	bool isEqual (SEL rhs)
	{
		return bindings.sel_isEqual(this, rhs);
	}
	
	bool isMapped ()
	{
		return bindings.sel_isMapped(this);
	}
}


//D Extensions:

struct objc
{	
	static string[] copyImageNames (out uint outCount)
	{
		string[] ret;
		
		char** result = bindings.objc_copyImageNames(&outCount);
		ret.length = outCount;
		
		for (size_t i = 0; i < outCount; i++)
			ret[i] = fromStringz(result[i]);
		
		return ret;
	}
	
	alias bindings.objc_enumerationMutation objc_enumerationMutation;
	alias bindings.objc_setForwardHandler objc_setForwardHandler;
	alias bindings.objc_setMultithreaded objc_setMultithreaded;
	
	static id getClass (string name) ()
	{
		return bindings.objc_getClass(name.ptr);
	}
	
	static id getMetaClass (string name) ()
	{
		return bindings.objc_getMetaClass(name.ptr);
	}
	
	static id lookUpClass (string name) ()
	{
		return bindings.objc_lookUpClass(name.ptr);
	}
	
	static id getRequiredClass (string name) ()
	{
		return bindings.objc_getRequiredClass(name.ptr);
	}	
	
	static Class getFutureClass (string name) ()
	{
		return bindings.objc_getFutureClass(name.ptr);
	}
	
	static string[] objc_copyClassNamesForImage (string image) (out uint outCount)
	{
		string[] ret;
		
		char** result = bindings.objc_copyClassNamesForImage(image.ptr, &outCount);
		ret.length = outCount;
		
		for (size_t i = 0; i < outCount; i++)
			ret[i] = fromStringz(result[i]);
		
		return ret;
	}
	
	static Class objc_getOrigClass (string name) ()
	{
		return bindings.objc_getOrigClass(name.ptr);
	}
	
	static Class allocateClassPair (string name) (Class superclass, size_t extraBytes)
	{
		return bindings.objc_allocateClassPair(superclass, name.ptr, extraBytes);
	}
	
	alias bindings.objc_registerClassPair registerClassPair;
	alias bindings.objc_disposeClassPair disposeClassPair;
	alias bindings.objc_getClasses getClasses;
	alias bindings.objc_addClass addClass;
	alias bindings.class_createInstance createInstance;
}

struct property
{
	static string getName (objc_property_t* property)
	{
		return fromStringz(bindings.property_getName(property));
	}

	static string getAttributes (objc_property_t* property)
	{
		return fromStringz(bindings.property_getAttributes(property));
	}
}

struct sel
{	
	static SEL getUid (string str) ()
	{
		return bindings.sel_getUid(str.ptr);
	}
	
	static SEL registerName (string str) ()
	{
		return bindings.sel_registerName(str.ptr);
	}
}