Example #1
0
Library::~Library()
{
    // Decrease instance count
    instance_count--;

    // If no instances remaining, free resources.
    if (instance_count == 0)
        for (auto r : resources)
            unload_resource(r.second);
}
Example #2
0
/*!
*/
uint32_t Library::Unload(const wcl::string& file)
{
//         static std::unordered_map<wcl::string, resource_entry_t> resources;
    if (resources.count(file) == 0)
        return WHEEL_UNINITIALISED_RESOURCE;

    unload_resource(resources[file]);
    resources.erase(file);

    return WHEEL_OK;
}
Example #3
0
FBD_API __bool ICBlk_del_pin(struct blk_pin_t * p)
{
    struct cblk_pin_t *cp;
    struct cblk_link_t *lk;

    assert(p->blk->h.magic == CBLK_MAGIC);

    // remove all connections on this pin
    lk = ICBlk_first_connection(p);
    while(lk) {
        ICBlk_unlink(lk);
        lk = ICBlk_first_connection(p);
    }

    /* propagate this delete operation upwards */
    if(p->ulink) {
        ICBlk_del_pin(p->ulink);
        /*
        	p->ulink is not accessible here because it's already
        	been freed
        */
        p->ulink = NULL;
    }

    /* propagate delete operation downloads */
    p->u1.x.id.llink->ulink = 0;

    p->blk->h.n_pins--;

    /* i'm dying, mother! */
    cp = SAFE_CONTAINING_RECORD(p, struct cblk_pin_t, p);
    RtkRemoveEntryList(&cp->sibling);

#ifdef F8_CONFIGURATOR
    unload_resource(&cp->uuid);
#endif

    mm_free(g_hBlkHeap, cp);

    return __true;
}
Example #4
0
/*
	remove a connection
*/
FBD_API __bool ICBlk_unlink(struct cblk_link_t * lk)
{
    IBlk * me;

    me = parent_blk(lk->t.pin->blk);
    assert(me->h.magic == CBLK_MAGIC);
    assert(me == __ucast__(ICBlk, IBlk, lk->blk));

    IBlk_disconnect(lk->t.pin);
    RtkRemoveEntryList(&lk->sibling);
    me->h.u2.n_links--;
    // assert(me->h.u2.n_links >= 0);

#ifdef F8_CONFIGURATOR
    unload_resource(&lk->uuid);
#endif

    mm_free(g_hBlkHeap, lk);

    return __true;
}
Example #5
0
/*
	move_resource
	will decrement usage count of the source resource,
	note this will not necessary cause the source resource
	to be deleted, only if its usage count reaches zero.
*/
F8RES_API int move_resource(
	const f8_uuid * s, 
	const f8_uuid * t
	)
{
	int r;
	F8_RESOURCE *tr, *sr;

	if(query_resource(t) >= 0){
		return F8_NAME_DUPLICATE;
	}
	sr = _get_res(s);
	if(!sr){
		return F8_OBJECT_NOT_FOUND;
	}
	if(!create_resource(t)){
		return F8_LOW_MEMORY;
	}
	if(sr->refcount == 1){
		/*
			a little optimization, if the reference count of source
			is 1, then no actual copy is made, instead, we move
			the contents of s to t, and detach s from its contents.
		*/
		tr = _get_res(t);
		delete tr->pItems;
		tr->pItems = _get_res(s)->pItems;
		sr->pItems = 0;
		_free_resource(sr);
		r = F8_SUCCESS;
	}else{
		r = copy_resource(s, t);
	}
	/*
	this will decrement the reference count, and remove the
	resource entry if necessary
	*/
	unload_resource(s);
	return r;
}
Example #6
0
/*
	import a resource from disk, and if the resource has
	already been loaded, increment its reference count.

	2005/6/24
	the load_from_disk branch is obsolete.
*/
F8RES_API __bool load_resource(
	const f8_uuid * id
	)
{
	RESMAP::iterator it;
	it = g_Resources.find(*id);
	if(it != g_Resources.end()){
		it->second.refcount++;
		return __true;
	}
	return __false;
#if 0
	IFileStream *fs;
	IF8Stream * str;
	char buf[43];
	
	f8_uuid_to_string(id, buf, sizeof(buf));
	strcat(buf, ".res");
	fs = IFileStream_from_file(buf, "rb");
	if(!fs){
		return __false;
	}
	str = __ucast__(IFileStream, IF8Stream, fs);
	h = _load_res_stream(str);
	if(h){
		if(*id != h->id){
			/* error in library */
			unload_resource(&h->id);
			h = 0;
		}		
	}

	__delete__(fs);
	return h? __true : __false;
#endif
}
Example #7
0
/*
	construct a resource object in memory from a stream
	the stream is composed of:
	1) a magic
	2) uuid
	3) item count
	4) array of items

	NOTE!! 
	1) On success, the resource item is not reference counted. 
	If the client won't addref on the loaded resource, then the 
	item is exposed to the garbage collector.
	More exactly, this proc won't addref on the resource when
	the resource already exists.
*/
static F8_RESOURCE * _load_res_stream(IF8Stream * str)
{
	__u16	magic;
	RESMAP::iterator it;
	__u32 itemcount;
	c_bstr_t cbstr;
	f8_uuid id;
	__int	length;
	void	* buffer;
	F8_RESOURCE * res;
	__bool ret;

	// DEBUG_PRINTF(("stream %08x\n", __vcall__(str, tell, (str))));
	
	if(!__vcall__(str, get, (str, &magic, sizeof(magic)))){
		return 0;
	}

	if(magic != F8_RES_MAGIC && magic != F8_RES_MAGIC_2){
		__vcall__(str, seek, (str, -sizeof(magic), SEEK_CUR));
		return 0;
	}

	if(!__vcall__(str, get, (str, &id, sizeof(id)))){
		return 0;
	}

	res = create_resource_bibibobo(&id, __false);
	if(!res){
		return 0;
	}
	
	/* the resource has not been loaded yet */
	if(!__vcall__(str, get, (str, &itemcount, sizeof(itemcount)))){
		return 0;
	}

	if(res->refcount){
		/* note if the resource is already present we silently
		eat the stream without modifing the in-memory version
		*/
		for(; itemcount; itemcount--){
			if(!__vcall__(str, get, (str, &cbstr.count, sizeof(cbstr.count)))){
				goto __failed;
			}
			__vcall__(str, seek, (str, cbstr.count, SEEK_CUR));
			if(!__vcall__(str, get, (str, &length, sizeof(length)))){
				goto __failed;
			}
			__vcall__(str, seek, (str, length, SEEK_CUR));
		}	
	}else{
		for(; itemcount; itemcount--){	
			if(!bstr_from_stream(&cbstr, str)){
				goto __failed;
			}

			if(!__vcall__(str, get, (str, &length, sizeof(length)))){
				goto __failed;
			}
			if(length){
				buffer = __malloc__(length);
				if(!buffer){
					goto __failed;
				}
				if(!__vcall__(str, get, (str, buffer, length))){
					goto __failed;
				}
			}else{
				buffer = 0;
			}
			
			ret = set_res_buf(&id, buffer, length, cbstr.buffer);
			__free__(buffer);
			c_free_bstr(&cbstr);
			if(!ret){
				goto __failed;
			}
		}
	}
	return res;	

__failed:
	/* the unload_resource will decrease the refcount */
	res->refcount++;
	unload_resource(&id);
	
	return 0;
}