Home modules.gotpike.org
Username: Password: [Create Account]
[Forgot Password?]
Return to module

File Contents

Contents of /wx-0.5/handcoded.cc:

// wxhello.cpp
// Version using dynamic event routing
// Robert Roebling, Martin Bernreuther

#include <wx/wx.h>


/*
   wxPike - (c) 2005 Julio César Gázquez
   
   handcoded.cc: 
   Wrapper functions implemented by hand for main functionality

*/
#include "wx.h"
#include <iostream>
/*
    Functions that interface with Pike needs C interfaces
*/
extern "C" {
void f_wxEvent__m_callbackUserData(INT32 args);
void f_wxEvent__GetEventObject(INT32 args);
void f_wxEvtHandler__Connect(INT32 args);
void f_wxGetApp(INT32 args);
void f_implement_app(INT32 args);
}

extern struct program* wxEvent_program;
extern struct program* wxApp_program;

struct svalue app_program;
struct object *app_object=NULL;

/*
    Event handling
*/
// used to be public wxObject for wx 2.4, but 2.5.4 changed 
// the class for function callbacks to wxEvtHandler
class WXDLLEXPORT ThunkObject : public wxEvtHandler
{
private:
	struct svalue method;
	struct object* eventObject;
	struct object* data;
public:
	ThunkObject(struct svalue* method, struct object* eventObject, struct object* data);
	~ThunkObject();
	void eventThunker(wxEvent& event);
	void run(wxEvent& event);
	struct object* getObject() { return eventObject; };
	struct object* getData() { return data; };
};

ThunkObject::ThunkObject(struct svalue* method, struct object* eventObject, struct object* data)
{
	assign_svalue_no_free(&(this->method),method);

	// eventObject != NULL!!!
 	this->eventObject=eventObject;
	add_ref(eventObject);

	if (data) {
 		this->data=data;
		add_ref(data);
	}
}

ThunkObject::~ThunkObject()
{
	free_svalue(&(this->method));
	free_object(eventObject);
	if (data)
		free_object(data);
}

void ThunkObject::eventThunker(wxEvent& event)
{
	ThunkObject* thunk=static_cast<ThunkObject*>(event.m_callbackUserData);
	thunk->run(event);
}

void ThunkObject::run(wxEvent& event)
{
	// The next block allows to return a different wrappers
	// according the exact wxEvent subclass
	const char *pn=event.GetClassInfo()->GetClassName();
	push_constant_text("wx.");
	push_text(pn+2);
	f_add(2);
	push_constant_text("-");
	APPLY_MASTER("resolv", 2);
	if (Pike_sp[-1].type == PIKE_T_PROGRAM) {
		struct program *p = Pike_sp[-1].u.program;
		struct object *o = low_clone( p );
		call_c_initializers( o );
		static_cast<wxEvent*>(STORAGE(o,wxEvent)->cppobject)=&event;
		STORAGE(o,wxEvent)->foreign=true;
		push_object( o );
		apply_svalue(&(this->method),1);
	} else {
		std::cout << "Event casting failed!\n"; 
		struct object *o = low_clone( wxEvent_program );
		call_c_initializers( o );
		static_cast<wxEvent*>(STORAGE(o,wxEvent)->cppobject)=&event;
		STORAGE(o,wxEvent)->foreign=true;
		push_object( o );
		apply_svalue(&(this->method),1);
		
	}
	
}

// Do not expose C++ thunk but Pike object as data to the Pike side
void f_wxEvent__m_callbackUserData(INT32 args)
{
	pop_n_elems(args);
	struct object *o = static_cast<ThunkObject*>(static_cast<wxEvent*>(THIS->cppobject)->m_callbackUserData)->getData();
	if (o)
		ref_push_object( o );
	else
		push_undefined();
}

// For returning always the same wrapper. Maybe redundant with proper generator code, though.
void f_wxEvent__GetEventObject(INT32 args)
{
	pop_n_elems(args);
	struct object *o = static_cast<ThunkObject*>(static_cast<wxEvent*>(THIS->cppobject)->m_callbackUserData)->getObject();
	ref_push_object( o );
}


void f_wxEvtHandler__Connect(INT32 args)
{
	/*
	int id;
	wxEventType eventType;
	get_all_args("Connect", args, "%d.%d", &id, &eventType);
	*/
	if (args<3)
		SIMPLE_TOO_FEW_ARGS_ERROR("Connect",3);
	if (Pike_sp[0-args].type!=T_INT)
		SIMPLE_BAD_ARG_ERROR("Connect",0,"int");
	INT_TYPE id = Pike_sp[0-args].u.integer;
	if (Pike_sp[1-args].type!=T_INT)
		SIMPLE_BAD_ARG_ERROR("Connect",1,"int");
	wxEventType eventType = Pike_sp[1-args].u.integer;
	
	if (Pike_sp[2-args].type!=T_FUNCTION)
		SIMPLE_BAD_ARG_ERROR("Connect",2,"function");
	struct svalue* method=&Pike_sp[2-args];
	
	object* data;
	if (args<4)
		data=NULL;
	else {
		if (Pike_sp[3-args].type!=T_OBJECT)
			SIMPLE_BAD_ARG_ERROR("Connect",3,"object");
		data=Pike_sp[3-args].u.object;
	}

	ThunkObject* thunk = new ThunkObject(method,Pike_fp->current_object,data);

	static_cast<wxEvtHandler*>(THIS->cppobject)
		->Connect(id, eventType, static_cast<wxObjectEventFunction>(&ThunkObject::eventThunker), thunk );
	pop_n_elems(args);
}

/*
    wxWidgets startup
*/
#if wxMINOR_VERSION == 4
wxApp *wxCreateApp() 
{
	wxApp::CheckBuildOptions(wxBuildOptions());
	
	apply_svalue( &app_program, 0 );
	app_object = Pike_sp[-1].u.object;
	add_ref(app_object);
	pop_stack();
	return (wxApp*)
	( (struct wrapper_storage*)get_storage(app_object,app_object->prog)) ->cppobject;
}
#else
wxAppConsole *wxCreateApp() 
{
	wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,
		"your program");
	apply_svalue( &app_program, 0 );
	app_object = Pike_sp[-1].u.object;
	add_ref(app_object);
	pop_stack();
	return (wxApp*)
	( (struct wrapper_storage*)get_storage(app_object,app_object->prog)) ->cppobject;
}
#endif

wxAppInitializer wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp); 

wxApp__pv& wxGetApp() 
{
#if wxMINOR_VERSION == 4
	return *(wxApp__pv *)wxTheApp;
#else
	return *(wxApp__pv *)((wxApp *)wxApp::GetInstance());
#endif
}

void f_wxGetApp(INT32 args)
{
	if (args!=0)
		SIMPLE_TOO_FEW_ARGS_ERROR("wxGetApp",1);
	if (app_object)
		ref_push_object( app_object );
	else
		push_undefined();
}

void f_implement_app(INT32 args)
{
	if (args<1)
		SIMPLE_TOO_FEW_ARGS_ERROR("implement_app",1);
	if (Pike_sp[0-args].type!=T_FUNCTION)
		SIMPLE_BAD_ARG_ERROR("implement_app",0,"program");
	assign_svalue_no_free(&app_program,&Pike_sp[0-args]);
	pop_n_elems(args);
	// Allocar aqui el argv (o bien ver de tomarlo directamente del
	// argv de Pike y no pedir parámetros	
	static int argc=1;
	char *argv[] ={ "wxPike" };
	int r=wxEntry(argc, argv);
	if (r<0) r=0;
	push_int(r);
}

gotpike.org | Copyright © 2004 - 2011 | Pike is a trademark of Department of Computer and Information Science, Linköping University