Пример #1
0
void log_printline(enum LogMessageLevel lev, const std::string &text)
{
	log_threadnamemutex.Lock();
	std::string threadname = "(unknown thread)";
	std::map<threadid_t, std::string>::const_iterator i;
	i = log_threadnames.find(get_current_thread_id());
	if(i != log_threadnames.end())
		threadname = i->second;
	std::string levelname = get_lev_string(lev);
	std::ostringstream os(std::ios_base::binary);
	os<<getTimestamp()<<": "<<levelname<<"["<<threadname<<"]: "<<text;
	for(std::list<ILogOutput*>::iterator i = log_outputs[lev].begin();
			i != log_outputs[lev].end(); i++){
		ILogOutput *out = *i;
		if (out->silence)
			continue;

		out->printLog(os.str());
		out->printLog(os.str(), lev);
		out->printLog(lev, text);
	}
	log_threadnamemutex.Unlock();
}
Пример #2
0
	ClientCached* getClientCached(const std::string &name,
			IGameDef *gamedef) const
	{
		ClientCached *cc = NULL;
		m_clientcached.get(name, &cc);
		if(cc)
			return cc;

		if(get_current_thread_id() == m_main_thread)
		{
			return createClientCachedDirect(name, gamedef);
		}
		else
		{
			// We're gonna ask the result to be put into here
			static ResultQueue<std::string, ClientCached*, u8, u8> result_queue;

			// Throw a request in
			m_get_clientcached_queue.add(name, 0, 0, &result_queue);
			try{
				while(true) {
					// Wait result for a second
					GetResult<std::string, ClientCached*, u8, u8>
						result = result_queue.pop_front(1000);

					if (result.key == name) {
						return result.item;
					}
				}
			}
			catch(ItemNotFoundException &e)
			{
				errorstream<<"Waiting for clientcached " << name << " timed out."<<std::endl;
				return &m_dummy_clientcached;
			}
		}
	}
//systemwide thread
inline OS_systemwide_thread_id_t get_current_systemwide_thread_id()
{
   return get_current_thread_id();
}
Пример #4
0
int *__errno_ptr(void)
{
    return &__errno_array[get_current_thread_id()];
}
Пример #5
0
void log_deregister_thread()
{
    threadid_t id = get_current_thread_id();
    log_threadnames.erase(id);
}
Пример #6
0
void log_register_thread(const std::string &name)
{
    threadid_t id = get_current_thread_id();
    log_threadnames[id] = name;
}
Пример #7
0
	ClientCached* createClientCachedDirect(const std::string &name,
			IGameDef *gamedef) const
	{
		infostream<<"Lazily creating item texture and mesh for \""
				<<name<<"\""<<std::endl;

		// This is not thread-safe
		sanity_check(get_current_thread_id() == m_main_thread);

		// Skip if already in cache
		ClientCached *cc = NULL;
		m_clientcached.get(name, &cc);
		if(cc)
			return cc;

		ITextureSource *tsrc = gamedef->getTextureSource();
		INodeDefManager *nodedef = gamedef->getNodeDefManager();
		const ItemDefinition &def = get(name);

		// Create new ClientCached
		cc = new ClientCached();

		// Create an inventory texture
		cc->inventory_texture = NULL;
		if(def.inventory_image != "")
			cc->inventory_texture = tsrc->getTexture(def.inventory_image);

		// Additional processing for nodes:
		// - Create a wield mesh if WieldMeshSceneNode can't render
		//   the node on its own.
		// - If inventory_texture isn't set yet, create one using
		//   render-to-texture.
		if (def.type == ITEM_NODE) {
			// Get node properties
			content_t id = nodedef->getId(name);
			const ContentFeatures &f = nodedef->get(id);

			bool need_rtt_mesh = cc->inventory_texture == NULL;

			// Keep this in sync with WieldMeshSceneNode::setItem()
			bool need_wield_mesh =
				!(f.mesh_ptr[0] ||
				  f.drawtype == NDT_NORMAL ||
				  f.drawtype == NDT_ALLFACES ||
				  f.drawtype == NDT_AIRLIKE);

			scene::IMesh *node_mesh = NULL;

			if (need_rtt_mesh || need_wield_mesh) {
				u8 param1 = 0;
				if (f.param_type == CPT_LIGHT)
					param1 = 0xee;

				/*
					Make a mesh from the node
				*/
				MeshMakeData mesh_make_data(gamedef, false);
				u8 param2 = 0;
				if (f.param_type_2 == CPT2_WALLMOUNTED)
					param2 = 1;
				MapNode mesh_make_node(id, param1, param2);
				mesh_make_data.fillSingleNode(&mesh_make_node);
				MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
				node_mesh = mapblock_mesh.getMesh();
				node_mesh->grab();
				video::SColor c(255, 255, 255, 255);
				setMeshColor(node_mesh, c);

				// scale and translate the mesh so it's a
				// unit cube centered on the origin
				scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS));
				translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0));
			}

			/*
				Draw node mesh into a render target texture
			*/
			if (need_rtt_mesh) {
				TextureFromMeshParams params;
				params.mesh = node_mesh;
				params.dim.set(64, 64);
				params.rtt_texture_name = "INVENTORY_"
					+ def.name + "_RTT";
				params.delete_texture_on_shutdown = true;
				params.camera_position.set(0, 1.0, -1.5);
				params.camera_position.rotateXZBy(45);
				params.camera_lookat.set(0, 0, 0);
				// Set orthogonal projection
				params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
						1.65, 1.65, 0, 100);
				params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
				params.light_position.set(10, 100, -50);
				params.light_color.set(1.0, 0.5, 0.5, 0.5);
				params.light_radius = 1000;

#ifdef __ANDROID__
				params.camera_position.set(0, -1.0, -1.5);
				params.camera_position.rotateXZBy(45);
				params.light_position.set(10, -100, -50);
#endif
				cc->inventory_texture =
					tsrc->generateTextureFromMesh(params);

				// render-to-target didn't work
				if (cc->inventory_texture == NULL) {
					cc->inventory_texture =
						tsrc->getTexture(f.tiledef[0].name);
				}
			}

			/*
				Use the node mesh as the wield mesh
			*/
			if (need_wield_mesh) {
				cc->wield_mesh = node_mesh;
				cc->wield_mesh->grab();

				// no way reference count can be smaller than 2 in this place!
				assert(cc->wield_mesh->getReferenceCount() >= 2);
			}

			if (node_mesh)
				node_mesh->drop();
		}

		// Put in cache
		m_clientcached.set(name, cc);

		return cc;
	}
Пример #8
0
/*
	This method generates all the textures
*/
u32 TextureSource::getTextureIdDirect(const std::string &name)
{
	//infostream<<"getTextureIdDirect(): name=\""<<name<<"\""<<std::endl;

	// Empty name means texture 0
	if(name == "")
	{
		infostream<<"getTextureIdDirect(): name is empty"<<std::endl;
		return 0;
	}

	/*
		Calling only allowed from main thread
	*/
	if(get_current_thread_id() != m_main_thread)
	{
		errorstream<<"TextureSource::getTextureIdDirect() "
				"called not from main thread"<<std::endl;
		return 0;
	}

	/*
		See if texture already exists
	*/
	{
		JMutexAutoLock lock(m_textureinfo_cache_mutex);

		std::map<std::string, u32>::iterator n;
		n = m_name_to_id.find(name);
		if(n != m_name_to_id.end())
		{
			/*infostream<<"getTextureIdDirect(): \""<<name
					<<"\" found in cache"<<std::endl;*/
			return n->second;
		}
	}

	/*infostream<<"getTextureIdDirect(): \""<<name
			<<"\" NOT found in cache. Creating it."<<std::endl;*/

	/*
		Get the base image
	*/

	char separator = '^';

	/*
		This is set to the id of the base image.
		If left 0, there is no base image and a completely new image
		is made.
	*/
	u32 base_image_id = 0;

	// Find last meta separator in name
	s32 last_separator_position = -1;
	for(s32 i=name.size()-1; i>=0; i--)
	{
		if(name[i] == separator)
		{
			last_separator_position = i;
			break;
		}
	}
	/*
		If separator was found, construct the base name and make the
		base image using a recursive call
	*/
	std::string base_image_name;
	if(last_separator_position != -1)
	{
		// Construct base name
		base_image_name = name.substr(0, last_separator_position);
		/*infostream<<"getTextureIdDirect(): Calling itself recursively"
				" to get base image of \""<<name<<"\" = \""
                <<base_image_name<<"\""<<std::endl;*/
		base_image_id = getTextureIdDirect(base_image_name);
	}

	//infostream<<"base_image_id="<<base_image_id<<std::endl;

	video::IVideoDriver* driver = m_device->getVideoDriver();
	assert(driver);

	video::ITexture *t = NULL;

	/*
		An image will be built from files and then converted into a texture.
	*/
	video::IImage *baseimg = NULL;

	// If a base image was found, copy it to baseimg
	if(base_image_id != 0)
	{
		JMutexAutoLock lock(m_textureinfo_cache_mutex);

		TextureInfo *ti = &m_textureinfo_cache[base_image_id];

		if(ti->img == NULL)
		{
			infostream<<"getTextureIdDirect(): WARNING: NULL image in "
					<<"cache: \""<<base_image_name<<"\""
					<<std::endl;
		}
		else
		{
			core::dimension2d<u32> dim = ti->img->getDimension();

			baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);

			ti->img->copyTo(
					baseimg, // target
					v2s32(0,0), // position in target
					core::rect<s32>(v2s32(0,0), dim) // from
			);

			/*infostream<<"getTextureIdDirect(): Loaded \""
					<<base_image_name<<"\" from image cache"
					<<std::endl;*/
		}
	}

	/*
		Parse out the last part of the name of the image and act
		according to it
	*/

	std::string last_part_of_name = name.substr(last_separator_position+1);
	//infostream<<"last_part_of_name=\""<<last_part_of_name<<"\""<<std::endl;

	// Generate image according to part of name
	if(!generateImage(last_part_of_name, baseimg))
	{
		errorstream<<"getTextureIdDirect(): "
				"failed to generate \""<<last_part_of_name<<"\""
				<<std::endl;
	}

	// If no resulting image, print a warning
	if(baseimg == NULL)
	{
		errorstream<<"getTextureIdDirect(): baseimg is NULL (attempted to"
				" create texture \""<<name<<"\""<<std::endl;
	}

	if(baseimg != NULL)
	{
		// Create texture from resulting image
		t = driver->addTexture(name.c_str(), baseimg);
	}

	/*
		Add texture to caches (add NULL textures too)
	*/

	JMutexAutoLock lock(m_textureinfo_cache_mutex);

	u32 id = m_textureinfo_cache.size();
	TextureInfo ti(name, t, baseimg);
	m_textureinfo_cache.push_back(ti);
	m_name_to_id[name] = id;

	/*infostream<<"getTextureIdDirect(): "
			<<"Returning id="<<id<<" for name \""<<name<<"\""<<std::endl;*/

	return id;
}
Пример #9
0
    ClientCached* createClientCachedDirect(const std::string &name,
                                           IGameDef *gamedef) const
    {
        infostream<<"Lazily creating item texture and mesh for \""
                  <<name<<"\""<<std::endl;

        // This is not thread-safe
        assert(get_current_thread_id() == m_main_thread);

        // Skip if already in cache
        ClientCached *cc = NULL;
        m_clientcached.get(name, &cc);
        if(cc)
            return cc;

        ITextureSource *tsrc = gamedef->getTextureSource();
        INodeDefManager *nodedef = gamedef->getNodeDefManager();
        IrrlichtDevice *device = tsrc->getDevice();
        video::IVideoDriver *driver = device->getVideoDriver();
        const ItemDefinition *def = &get(name);

        // Create new ClientCached
        cc = new ClientCached();

        bool need_node_mesh = false;

        // Create an inventory texture
        cc->inventory_texture = NULL;
        if(def->inventory_image != "")
        {
            cc->inventory_texture = tsrc->getTextureRaw(def->inventory_image);
        }
        else if(def->type == ITEM_NODE)
        {
            need_node_mesh = true;
        }

        // Create a wield mesh
        assert(cc->wield_mesh == NULL);
        if(def->type == ITEM_NODE && def->wield_image == "")
        {
            need_node_mesh = true;
        }
        else if(def->wield_image != "" || def->inventory_image != "")
        {
            // Extrude the wield image into a mesh

            std::string imagename;
            if(def->wield_image != "")
                imagename = def->wield_image;
            else
                imagename = def->inventory_image;

            cc->wield_mesh = createExtrudedMesh(
                                 tsrc->getTextureRaw(imagename),
                                 driver,
                                 def->wield_scale * v3f(40.0, 40.0, 4.0));
            if(cc->wield_mesh == NULL)
            {
                infostream<<"ItemDefManager: WARNING: "
                          <<"updateTexturesAndMeshes(): "
                          <<"Unable to create extruded mesh for item "
                          <<def->name<<std::endl;
            }
        }

        if(need_node_mesh)
        {
            /*
            	Get node properties
            */
            content_t id = nodedef->getId(def->name);
            const ContentFeatures &f = nodedef->get(id);

            u8 param1 = 0;
            if(f.param_type == CPT_LIGHT)
                param1 = 0xee;

            /*
            	Make a mesh from the node
            */
            MeshMakeData mesh_make_data(gamedef);
            MapNode mesh_make_node(id, param1, 0);
            mesh_make_data.fillSingleNode(&mesh_make_node);
            MapBlockMesh mapblock_mesh(&mesh_make_data);

            scene::IMesh *node_mesh = mapblock_mesh.getMesh();
            assert(node_mesh);
            video::SColor c(255, 255, 255, 255);
            if(g_settings->getS32("enable_shaders") != 0)
                c = MapBlock_LightColor(255, 0xffff, decode_light(f.light_source));
            setMeshColor(node_mesh, c);

            /*
            	Scale and translate the mesh so it's a unit cube
            	centered on the origin
            */
            scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS));
            translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0));

            /*
            	Draw node mesh into a render target texture
            */
            if(cc->inventory_texture == NULL)
            {
                core::dimension2d<u32> dim(64,64);
                std::string rtt_texture_name = "INVENTORY_"
                                               + def->name + "_RTT";
                v3f camera_position(0, 1.0, -1.5);
                camera_position.rotateXZBy(45);
                v3f camera_lookat(0, 0, 0);
                core::CMatrix4<f32> camera_projection_matrix;
                // Set orthogonal projection
                camera_projection_matrix.buildProjectionMatrixOrthoLH(
                    1.65, 1.65, 0, 100);

                video::SColorf ambient_light(0.2,0.2,0.2);
                v3f light_position(10, 100, -50);
                video::SColorf light_color(0.5,0.5,0.5);
                f32 light_radius = 1000;

                cc->inventory_texture = generateTextureFromMesh(
                                            node_mesh, device, dim, rtt_texture_name,
                                            camera_position,
                                            camera_lookat,
                                            camera_projection_matrix,
                                            ambient_light,
                                            light_position,
                                            light_color,
                                            light_radius);

                // render-to-target didn't work
                if(cc->inventory_texture == NULL)
                {
                    cc->inventory_texture =
                        tsrc->getTextureRaw(f.tiledef[0].name);
                }
            }
            else
            {
                if (m_driver == 0)
                    m_driver = driver;

                m_extruded_textures.push_back(cc->inventory_texture);
            }

            /*
            	Use the node mesh as the wield mesh
            */

            // Scale to proper wield mesh proportions
            scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0)
                      * def->wield_scale);

            cc->wield_mesh = node_mesh;
            cc->wield_mesh->grab();

            //no way reference count can be smaller than 2 in this place!
            assert(cc->wield_mesh->getReferenceCount() >= 2);
        }

        // Put in cache
        m_clientcached.set(name, cc);

        return cc;
    }
Пример #10
0
void log_api(uint32_t index, int is_success, uintptr_t return_value,
    uint64_t hash, last_error_t *lasterr, ...)
{
    va_list args; char idx[4];

    // We haven't started logging yet.
    if(index >= sig_index_firsthookidx() && g_monitor_logging == 0) {
        return;
    }

    va_start(args, lasterr);

    EnterCriticalSection(&g_mutex);

    if(g_api_init[index] == 0) {
        log_explain(index);
        g_api_init[index] = 1;
    }

    LeaveCriticalSection(&g_mutex);

    bson b;

    bson_init_size(&b, mem_suggested_size(1024));
    bson_append_int(&b, "I", index);
    bson_append_int(&b, "T", get_current_thread_id());
    bson_append_int(&b, "t", get_tick_count() - g_starttick);
    bson_append_long(&b, "h", hash);

    // If failure has been determined, then log the last error as well.
    if(is_success == 0) {
        bson_append_int(&b, "e", lasterr->lasterror);
        bson_append_int(&b, "E", lasterr->nt_status);
    }

#if DEBUG
    if(index != sig_index_exception()) {
        _log_stacktrace(&b);
    }
#endif

    bson_append_start_array(&b, "args");
    bson_append_int(&b, "0", is_success);
    bson_append_long(&b, "1", return_value);

    int argnum = 2, override = 0;

    for (const char *fmt = sig_paramtypes(index); *fmt != 0; fmt++) {
        ultostr(argnum++, idx, 10);

        // Limitation override. Instead of displaying this right away in the
        // report we turn it into a buffer (much like the dropped files).
        if(*fmt == '!') {
            override = 1;
            argnum--;
            fmt++;
        }

        if(*fmt == 's') {
            const char *s = va_arg(args, const char *);
            log_string(&b, idx, s, s != NULL ? copy_strlen(s) : 0);
        }
        else if(*fmt == 'S') {