view dstep/objc/objc.d @ 2:9fd439a28ce3

Adapted the scripts for the new bridge + a lot more
author Jacob Carlborg <doob@me.com>
date Sun, 05 Jul 2009 17:16:19 +0200
parents 033d260cfc9b
children c0cfd40362ee
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)
	{
		return (cast(R function (id, SEL, ARGS))&bindings.objc_msgSend)(this, op, args);
	}

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

	static if (dstep.internal.Version.X86 || X86_64)
	{
		R msgSend_fpret (R = id, 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");
				
			return (cast(R function (id, SEL, ARGS...))&bindings.objc_msgSend_fpret)(this, op, args);
		}
	}

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

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

	R msgSendv (R = id, T) (SEL op, size_t arg_size, T arg_frame)
	{
		(cast(R function (id, SEL, size_t, T))&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)
			(cast(void function (R*, id, SEL, size_t, T))&bindings.objc_msgSendv_stret)(&stretAddr, this, op, arg_size, arg_frame);
	    
	    else
	        stretAddr = (*cast(R function (id, SEL, size_t, T))&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");
			return (cast(R function (id, SEL, uint, T))&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);
	}
}