Пример #1
0
bool frame::safe_for_sender(JavaThread *thread) {

  address _SP = (address) sp();
  address _FP = (address) fp();
  address _UNEXTENDED_SP = (address) unextended_sp();
  // sp must be within the stack
  bool sp_safe = (_SP <= thread->stack_base()) &&
                 (_SP >= thread->stack_base() - thread->stack_size());

  if (!sp_safe) {
    return false;
  }

  // unextended sp must be within the stack and above or equal sp
  bool unextended_sp_safe = (_UNEXTENDED_SP <= thread->stack_base()) &&
                            (_UNEXTENDED_SP >= _SP);

  if (!unextended_sp_safe) return false;

  // an fp must be within the stack and above (but not equal) sp
  bool fp_safe = (_FP <= thread->stack_base()) &&
                 (_FP > _SP);

  // We know sp/unextended_sp are safe only fp is questionable here

  // If the current frame is known to the code cache then we can attempt to
  // to construct the sender and do some validation of it. This goes a long way
  // toward eliminating issues when we get in frame construction code

  if (_cb != NULL ) {

    // First check if frame is complete and tester is reliable
    // Unfortunately we can only check frame complete for runtime stubs and nmethod
    // other generic buffer blobs are more problematic so we just assume they are
    // ok. adapter blobs never have a frame complete and are never ok.

    if (!_cb->is_frame_complete_at(_pc)) {
      if (_cb->is_compiled() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {
        return false;
      }
    }

    // Could just be some random pointer within the codeBlob
    if (!_cb->code_contains(_pc)) {
      return false;
    }

    // Entry frame checks
    if (is_entry_frame()) {
      // an entry frame must have a valid fp.

      if (!fp_safe) {
        return false;
      }

      // Validate the JavaCallWrapper an entry frame must have

      address jcw = (address)entry_frame_call_wrapper();

      bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > _FP);

      return jcw_safe;

    }

    intptr_t* younger_sp = sp();
    intptr_t* _SENDER_SP = sender_sp(); // sender is actually just _FP
    bool adjusted_stack = is_interpreted_frame();

    address   sender_pc = (address)younger_sp[I7->sp_offset_in_saved_window()] + pc_return_offset;


    // We must always be able to find a recognizable pc
    CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
    if (sender_pc == NULL ||  sender_blob == NULL) {
      return false;
    }

    // Could be a zombie method
    if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
      return false;
    }

    // It should be safe to construct the sender though it might not be valid

    frame sender(_SENDER_SP, younger_sp, adjusted_stack);

    // Do we have a valid fp?
    address sender_fp = (address) sender.fp();

    // an fp must be within the stack and above (but not equal) current frame's _FP

    bool sender_fp_safe = (sender_fp <= thread->stack_base()) &&
                   (sender_fp > _FP);

    if (!sender_fp_safe) {
      return false;
    }


    // If the potential sender is the interpreter then we can do some more checking
    if (Interpreter::contains(sender_pc)) {
      return sender.is_interpreted_frame_valid(thread);
    }

    // Could just be some random pointer within the codeBlob
    if (!sender.cb()->code_contains(sender_pc)) {
      return false;
    }

    // We should never be able to see an adapter if the current frame is something from code cache
    if (sender_blob->is_adapter_blob()) {
      return false;
    }

    if( sender.is_entry_frame()) {
      // Validate the JavaCallWrapper an entry frame must have

      address jcw = (address)sender.entry_frame_call_wrapper();

      bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > sender_fp);

      return jcw_safe;
    }

    // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
    // because you must allocate window space

    if (sender_blob->frame_size() <= 0) {
      assert(!sender_blob->is_compiled(), "should count return address at least");
      return false;
    }

    // The sender should positively be an nmethod or call_stub. On sparc we might in fact see something else.
    // The cause of this is because at a save instruction the O7 we get is a leftover from an earlier
    // window use. So if a runtime stub creates two frames (common in fastdebug/debug) then we see the
    // stale pc. So if the sender blob is not something we'd expect we have little choice but to declare
    // the stack unwalkable. pd_get_top_frame_for_signal_handler tries to recover from this by unwinding
    // that initial frame and retrying.

    if (!sender_blob->is_compiled()) {
      return false;
    }

    // Could put some more validation for the potential non-interpreted sender
    // frame we'd create by calling sender if I could think of any. Wait for next crash in forte...

    // One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb

    // We've validated the potential sender that would be created

    return true;

  }

  // Must be native-compiled frame. Since sender will try and use fp to find
  // linkages it must be safe

  if (!fp_safe) return false;

  // could try and do some more potential verification of native frame if we could think of some...

  return true;
}
Пример #2
0
void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
{
	INodeDefManager *nodemgr = m_gamedef->ndef();

	//m_dout<<DTIME<<"Rendering map..."<<std::endl;
	DSTACK(__FUNCTION_NAME);

	bool is_transparent_pass = pass == scene::ESNRP_TRANSPARENT;
	
	std::string prefix;
	if(pass == scene::ESNRP_SOLID)
		prefix = "CM: solid: ";
	else
		prefix = "CM: transparent: ";

	/*
		This is called two times per frame, reset on the non-transparent one
	*/
	if(pass == scene::ESNRP_SOLID)
	{
		m_last_drawn_sectors.clear();
	}

	/*
		Get time for measuring timeout.
		
		Measuring time is very useful for long delays when the
		machine is swapping a lot.
	*/
	int time1 = time(0);

	/*
		Get animation parameters
	*/
	float animation_time = m_client->getAnimationTime();
	int crack = m_client->getCrackLevel();
	u32 daynight_ratio = m_client->getEnv().getDayNightRatio();

	m_camera_mutex.Lock();
	v3f camera_position = m_camera_position;
	v3f camera_direction = m_camera_direction;
	f32 camera_fov = m_camera_fov;
	m_camera_mutex.Unlock();

	/*
		Get all blocks and draw all visible ones
	*/

	v3s16 cam_pos_nodes = floatToInt(camera_position, BS);
	
	v3s16 box_nodes_d = m_control.wanted_range * v3s16(1,1,1);

	v3s16 p_nodes_min = cam_pos_nodes - box_nodes_d;
	v3s16 p_nodes_max = cam_pos_nodes + box_nodes_d;

	// Take a fair amount as we will be dropping more out later
	// Umm... these additions are a bit strange but they are needed.
	v3s16 p_blocks_min(
			p_nodes_min.X / MAP_BLOCKSIZE - 3,
			p_nodes_min.Y / MAP_BLOCKSIZE - 3,
			p_nodes_min.Z / MAP_BLOCKSIZE - 3);
	v3s16 p_blocks_max(
			p_nodes_max.X / MAP_BLOCKSIZE + 1,
			p_nodes_max.Y / MAP_BLOCKSIZE + 1,
			p_nodes_max.Z / MAP_BLOCKSIZE + 1);
	
	u32 vertex_count = 0;
	u32 meshbuffer_count = 0;
	
	// For limiting number of mesh animations per frame
	u32 mesh_animate_count = 0;
	u32 mesh_animate_count_far = 0;
	
	// Number of blocks in rendering range
	u32 blocks_in_range = 0;
	// Number of blocks occlusion culled
	u32 blocks_occlusion_culled = 0;
	// Number of blocks in rendering range but don't have a mesh
	u32 blocks_in_range_without_mesh = 0;
	// Blocks that had mesh that would have been drawn according to
	// rendering range (if max blocks limit didn't kick in)
	u32 blocks_would_have_drawn = 0;
	// Blocks that were drawn and had a mesh
	u32 blocks_drawn = 0;
	// Blocks which had a corresponding meshbuffer for this pass
	u32 blocks_had_pass_meshbuf = 0;
	// Blocks from which stuff was actually drawn
	u32 blocks_without_stuff = 0;

	/*
		Collect a set of blocks for drawing
	*/
	
	core::map<v3s16, MapBlock*> drawset;

	{
	ScopeProfiler sp(g_profiler, prefix+"collecting blocks for drawing", SPT_AVG);

	for(core::map<v2s16, MapSector*>::Iterator
			si = m_sectors.getIterator();
			si.atEnd() == false; si++)
	{
		MapSector *sector = si.getNode()->getValue();
		v2s16 sp = sector->getPos();
		
		if(m_control.range_all == false)
		{
			if(sp.X < p_blocks_min.X
			|| sp.X > p_blocks_max.X
			|| sp.Y < p_blocks_min.Z
			|| sp.Y > p_blocks_max.Z)
				continue;
		}

		core::list< MapBlock * > sectorblocks;
		sector->getBlocks(sectorblocks);
		
		/*
			Loop through blocks in sector
		*/

		u32 sector_blocks_drawn = 0;
		
		core::list< MapBlock * >::Iterator i;
		for(i=sectorblocks.begin(); i!=sectorblocks.end(); i++)
		{
			MapBlock *block = *i;

			/*
				Compare block position to camera position, skip
				if not seen on display
			*/
			
			float range = 100000 * BS;
			if(m_control.range_all == false)
				range = m_control.wanted_range * BS;

			float d = 0.0;
			if(isBlockInSight(block->getPos(), camera_position,
					camera_direction, camera_fov,
					range, &d) == false)
			{
				continue;
			}

			// This is ugly (spherical distance limit?)
			/*if(m_control.range_all == false &&
					d - 0.5*BS*MAP_BLOCKSIZE > range)
				continue;*/

			blocks_in_range++;
			
			/*
				Ignore if mesh doesn't exist
			*/
			{
				//JMutexAutoLock lock(block->mesh_mutex);

				if(block->mesh == NULL){
					blocks_in_range_without_mesh++;
					continue;
				}
			}

			/*
				Occlusion culling
			*/

			// No occlusion culling when free_move is on and camera is
			// inside ground
			bool occlusion_culling_enabled = true;
			if(g_settings->getBool("free_move")){
				MapNode n = getNodeNoEx(cam_pos_nodes);
				if(n.getContent() == CONTENT_IGNORE ||
						nodemgr->get(n).solidness == 2)
					occlusion_culling_enabled = false;
			}

			v3s16 cpn = block->getPos() * MAP_BLOCKSIZE;
			cpn += v3s16(MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2);
			float step = BS*1;
			float stepfac = 1.1;
			float startoff = BS*1;
			float endoff = -BS*MAP_BLOCKSIZE*1.42*1.42;
			v3s16 spn = cam_pos_nodes + v3s16(0,0,0);
			s16 bs2 = MAP_BLOCKSIZE/2 + 1;
			u32 needed_count = 1;
			if(
				occlusion_culling_enabled &&
				isOccluded(this, spn, cpn + v3s16(0,0,0),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(bs2,bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(bs2,bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(bs2,-bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(bs2,-bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(-bs2,bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(-bs2,bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr) &&
				isOccluded(this, spn, cpn + v3s16(-bs2,-bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr)
			)
			{
				blocks_occlusion_culled++;
				continue;
			}
			
			// This block is in range. Reset usage timer.
			block->resetUsageTimer();

			// Limit block count in case of a sudden increase
			blocks_would_have_drawn++;
			if(blocks_drawn >= m_control.wanted_max_blocks
					&& m_control.range_all == false
					&& d > m_control.wanted_min_range * BS)
				continue;

			// Mesh animation
			{
				//JMutexAutoLock lock(block->mesh_mutex);
				MapBlockMesh *mapBlockMesh = block->mesh;
				// Pretty random but this should work somewhat nicely
				bool faraway = d >= BS*50;
				//bool faraway = d >= m_control.wanted_range * BS;
				if(mapBlockMesh->isAnimationForced() ||
						!faraway ||
						mesh_animate_count_far < (m_control.range_all ? 200 : 50))
				{
					bool animated = mapBlockMesh->animate(
							faraway,
							animation_time,
							crack,
							daynight_ratio);
					if(animated)
						mesh_animate_count++;
					if(animated && faraway)
						mesh_animate_count_far++;
				}
				else
				{
					mapBlockMesh->decreaseAnimationForceTimer();
				}
			}

			// Add to set
			drawset[block->getPos()] = block;
			
			sector_blocks_drawn++;
			blocks_drawn++;

		} // foreach sectorblocks

		if(sector_blocks_drawn != 0)
			m_last_drawn_sectors[sp] = true;
	}
	} // ScopeProfiler
	
	/*
		Draw the selected MapBlocks
	*/

	{
	ScopeProfiler sp(g_profiler, prefix+"drawing blocks", SPT_AVG);

	int timecheck_counter = 0;
	for(core::map<v3s16, MapBlock*>::Iterator
			i = drawset.getIterator();
			i.atEnd() == false; i++)
	{
		{
			timecheck_counter++;
			if(timecheck_counter > 50)
			{
				timecheck_counter = 0;
				int time2 = time(0);
				if(time2 > time1 + 4)
				{
					infostream<<"ClientMap::renderMap(): "
						"Rendering takes ages, returning."
						<<std::endl;
					return;
				}
			}
		}
		
		MapBlock *block = i.getNode()->getValue();

		/*
			Draw the faces of the block
		*/
		{
			//JMutexAutoLock lock(block->mesh_mutex);

			MapBlockMesh *mapBlockMesh = block->mesh;
			assert(mapBlockMesh);

			scene::SMesh *mesh = mapBlockMesh->getMesh();
			assert(mesh);

			u32 c = mesh->getMeshBufferCount();
			bool stuff_actually_drawn = false;
			for(u32 i=0; i<c; i++)
			{
				scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
				const video::SMaterial& material = buf->getMaterial();
				video::IMaterialRenderer* rnd =
						driver->getMaterialRenderer(material.MaterialType);
				bool transparent = (rnd && rnd->isTransparent());
				// Render transparent on transparent pass and likewise.
				if(transparent == is_transparent_pass)
				{
					if(buf->getVertexCount() == 0)
						errorstream<<"Block ["<<analyze_block(block)
								<<"] contains an empty meshbuf"<<std::endl;
					/*
						This *shouldn't* hurt too much because Irrlicht
						doesn't change opengl textures if the old
						material has the same texture.
					*/
					driver->setMaterial(buf->getMaterial());
					driver->drawMeshBuffer(buf);
					vertex_count += buf->getVertexCount();
					meshbuffer_count++;
					stuff_actually_drawn = true;
				}
			}
			if(stuff_actually_drawn)
				blocks_had_pass_meshbuf++;
			else
				blocks_without_stuff++;
		}
	}
	} // ScopeProfiler
	
	// Log only on solid pass because values are the same
	if(pass == scene::ESNRP_SOLID){
		g_profiler->avg("CM: blocks in range", blocks_in_range);
		g_profiler->avg("CM: blocks occlusion culled", blocks_occlusion_culled);
		if(blocks_in_range != 0)
			g_profiler->avg("CM: blocks in range without mesh (frac)",
					(float)blocks_in_range_without_mesh/blocks_in_range);
		g_profiler->avg("CM: blocks drawn", blocks_drawn);
		g_profiler->avg("CM: animated meshes", mesh_animate_count);
		g_profiler->avg("CM: animated meshes (far)", mesh_animate_count_far);
	}
	
	g_profiler->avg(prefix+"vertices drawn", vertex_count);
	if(blocks_had_pass_meshbuf != 0)
		g_profiler->avg(prefix+"meshbuffers per block",
				(float)meshbuffer_count / (float)blocks_had_pass_meshbuf);
	if(blocks_drawn != 0)
		g_profiler->avg(prefix+"empty blocks (frac)",
				(float)blocks_without_stuff / blocks_drawn);

	m_control.blocks_drawn = blocks_drawn;
	m_control.blocks_would_have_drawn = blocks_would_have_drawn;

	/*infostream<<"renderMap(): is_transparent_pass="******", rendered "<<vertex_count<<" vertices."<<std::endl;*/
}
Пример #3
0
int main(int argc, char **argv) {
    SmartPointer<Foo> sp(nullptr);
    std::cout << sp->Sum() << std::endl;
    return 0;
}
Пример #4
0
int main(void)
{
    int64 t0,t1;
    d();
    s=(int64*)calloc(q,sizeof(int64));
    gw(0,2,99);
_1:
    if(gr(0,2)!=1000)goto _2;else goto _47;
_2:
    t0=gr(0,2)+1;
    t1=gr(0,2)+1;
    gw(0,2,gr(0,2)+1);
    t1%=2;
    t1=(t1!=0)?0:1;
    if((t1)!=0)goto _1;else goto _3;
_3:
    t0%=5;
    t0=(t0!=0)?0:1;
    if((t0)!=0)goto _1;else goto _4;
_4:
    gw(1,2,3);
_5:
    t0=gr(1,2)+1;
    gw(1,2,gr(1,2)+1);
    t0-=14;
    t0=(t0!=0)?0:1;
    if((t0)!=0)goto _1;else goto _6;
_6:
    gw(2,2,0);
    if(((gr(0,gr(1,2))-48)+gr(2,2))!=0)goto _8;else goto _7;
_7:
    t0=gr(2,2)+1;
    gw(2,2,gr(2,2)+1);
    t0-=3;
    t0=(t0!=0)?0:1;
    if((t0)!=0)goto _5;else goto _8;
_8:
    gw(4,2,gr(0,2));
    sa(5);
    sa(gr(5,gr(1,2))-48);
_9:
    if(sp()!=0)goto _10;else goto _46;
_10:
    sa(sr());
    sa((tm(gr(4,2),10))+48);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sp()+7LL);
    sa(gr(1,2));
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    gw(4,2,td(gr(4,2),10));
_11:
    sa(sr());
    sa((sp()!=0)?0:1);
    if(sp()!=0)goto _12;else goto _45;
_12:
    sp();
    sa(gr(12,gr(1,2))-48);
    sa(4);
_13:
    sa(sr()+7);
    sa(gr(1,2));
    {int64 v0=sp();sa(gr(sp(),v0));}
    sa(sp()-48LL);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sr());
    if(sp()!=0)goto _44;else goto _14;
_14:
    sp();
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sr());
    gw(7,2,sp());
    if(tm(sr(),2)!=0)goto _16;else goto _15;
_15:
    sp();
    goto _7;
_16:
    if(tm(sr(),3)!=0)goto _17;else goto _15;
_17:
    gw(5,2,sp());
    sa(7);
    sa(tm(gr(5,2),7));
_18:
    if(sp()!=0)goto _19;else goto _15;
_19:
    if(sr()>(td(gr(5,2),2)))goto _22;else goto _20;
_20:
    sa(sr()-2);
    sa(gr(5,2));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    {int64 v0=sp();sa(tm(sp(),v0));}
    sa((sp()!=0)?0:1);
    if(sp()!=0)goto _15;else goto _21;
_21:
    sa(sp()+6LL);
    sa(sr());
    sa(gr(5,2));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    {int64 v0=sp();sa(tm(sp(),v0));}
    goto _18;
_22:
    gw(8,2,1);
    gw(9,2,gr(2,2));
    gw(9,2,gr(9,2)+1);
    gw(4,2,gr(0,2));
    sp();
_23:
    sa(5);
    sa(gr(5,gr(1,2))-48);
_24:
    if(sp()!=0)goto _25;else goto _43;
_25:
    sa(sr());
    sa((tm(gr(4,2),10))+48);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sp()+7LL);
    sa(gr(9,2)+4);
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    gw(4,2,td(gr(4,2),10));
_26:
    sa(sr());
    if(sp()!=0)goto _42;else goto _27;
_27:
    sp();
    sa(gr(12,gr(9,2)+4)-48);
    sa(4);
_28:
    sa(sr()+7);
    sa(gr(9,2)+4);
    {int64 v0=sp();sa(gr(sp(),v0));}
    sa(sp()-48LL);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sr());
    if(sp()!=0)goto _41;else goto _29;
_29:
    sp();
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    sa(sp()*10LL);
    sa(sp()+sp());
    if(tm(sr(),2)!=0)goto _34;else goto _30;
_30:
    sp();
    if(gr(9,2)!=9)goto _31;else goto _32;
_31:
    gw(9,2,gr(9,2)+1);
    gw(4,2,gr(0,2));
    goto _23;
_32:
    if(gr(8,2)!=8)goto _7;else goto _33;
_33:
    printf("%lld", gr(7,2));
    return 0;
_34:
    if(tm(sr(),3)!=0)goto _35;else goto _30;
_35:
    gw(5,2,sp());
    sa(7);
    sa(tm(gr(5,2),7));
_36:
    if(sp()!=0)goto _37;else goto _30;
_37:
    if(sr()>(td(gr(5,2),2)))goto _40;else goto _38;
_38:
    sa(sr()-2);
    sa(gr(5,2));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    {int64 v0=sp();sa(tm(sp(),v0));}
    sa((sp()!=0)?0:1);
    if(sp()!=0)goto _30;else goto _39;
_39:
    sa(sp()+6LL);
    sa(sr());
    sa(gr(5,2));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    {int64 v0=sp();sa(tm(sp(),v0));}
    goto _36;
_40:
    gw(8,2,gr(8,2)+1);
    goto _30;
_41:
    sa(sp()-1LL);
    goto _28;
_42:
    sa(sp()-1LL);
    sa(sr());
    sa(gr(1,2));
    {int64 v0=sp();sa(gr(sp(),v0));}
    sa(sp()-48LL);
    goto _24;
_43:
    sa(sr());
    sa(gr(9,2)+48);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sp()+7LL);
    sa(gr(9,2)+4);
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    goto _26;
_44:
    sa(sp()-1LL);
    goto _13;
_45:
    sa(sp()-1LL);
    sa(sr());
    sa(gr(1,2));
    {int64 v0=sp();sa(gr(sp(),v0));}
    sa(sp()-48LL);
    goto _9;
_46:
    sa(sr());
    sa(gr(2,2)+48);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sp()+7LL);
    sa(gr(1,2));
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    goto _11;
_47:
    return 0;
}
Пример #5
0
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
                                        f32 pos_max_d, const aabb3f &box_0,
                                        f32 stepheight, f32 dtime,
                                        v3f &pos_f, v3f &speed_f,
                                        v3f &accel_f,ActiveObject* self,
                                        bool collideWithObjects)
{
    static bool time_notification_done = false;
    Map *map = &env->getMap();
    //TimeTaker tt("collisionMoveSimple");
    ScopeProfiler sp(g_profiler, "collisionMoveSimple avg", SPT_AVG);

    collisionMoveResult result;

    /*
    	Calculate new velocity
    */
    if (dtime > 0.5) {
        if (!time_notification_done) {
            time_notification_done = true;
            infostream << "collisionMoveSimple: maximum step interval exceeded,"
                       " lost movement details!"<<std::endl;
        }
        dtime = 0.5;
    } else {
        time_notification_done = false;
    }
    speed_f += accel_f * dtime;

    // If there is no speed, there are no collisions
    if(speed_f.getLength() == 0)
        return result;

    // Limit speed for avoiding hangs
    speed_f.Y=rangelim(speed_f.Y,-5000,5000);
    speed_f.X=rangelim(speed_f.X,-5000,5000);
    speed_f.Z=rangelim(speed_f.Z,-5000,5000);

    /*
    	Collect node boxes in movement range
    */
    std::vector<aabb3f> cboxes;
    std::vector<bool> is_unloaded;
    std::vector<bool> is_step_up;
    std::vector<bool> is_object;
    std::vector<int> bouncy_values;
    std::vector<v3s16> node_positions;
    {
        //TimeTaker tt2("collisionMoveSimple collect boxes");
        ScopeProfiler sp(g_profiler, "collisionMoveSimple collect boxes avg", SPT_AVG);

        v3s16 oldpos_i = floatToInt(pos_f, BS);
        v3s16 newpos_i = floatToInt(pos_f + speed_f * dtime, BS);
        s16 min_x = MYMIN(oldpos_i.X, newpos_i.X) + (box_0.MinEdge.X / BS) - 1;
        s16 min_y = MYMIN(oldpos_i.Y, newpos_i.Y) + (box_0.MinEdge.Y / BS) - 1;
        s16 min_z = MYMIN(oldpos_i.Z, newpos_i.Z) + (box_0.MinEdge.Z / BS) - 1;
        s16 max_x = MYMAX(oldpos_i.X, newpos_i.X) + (box_0.MaxEdge.X / BS) + 1;
        s16 max_y = MYMAX(oldpos_i.Y, newpos_i.Y) + (box_0.MaxEdge.Y / BS) + 1;
        s16 max_z = MYMAX(oldpos_i.Z, newpos_i.Z) + (box_0.MaxEdge.Z / BS) + 1;

        bool any_position_valid = false;

        for(s16 x = min_x; x <= max_x; x++)
            for(s16 y = min_y; y <= max_y; y++)
                for(s16 z = min_z; z <= max_z; z++)
                {
                    v3s16 p(x,y,z);

                    bool is_position_valid;
                    MapNode n = map->getNodeNoEx(p, &is_position_valid);

                    if (is_position_valid) {
                        // Object collides into walkable nodes

                        any_position_valid = true;
                        const ContentFeatures &f = gamedef->getNodeDefManager()->get(n);
                        if(f.walkable == false)
                            continue;
                        int n_bouncy_value = itemgroup_get(f.groups, "bouncy");

                        std::vector<aabb3f> nodeboxes = n.getCollisionBoxes(gamedef->ndef());
                        for(std::vector<aabb3f>::iterator
                                i = nodeboxes.begin();
                                i != nodeboxes.end(); ++i)
                        {
                            aabb3f box = *i;
                            box.MinEdge += v3f(x, y, z)*BS;
                            box.MaxEdge += v3f(x, y, z)*BS;
                            cboxes.push_back(box);
                            is_unloaded.push_back(false);
                            is_step_up.push_back(false);
                            bouncy_values.push_back(n_bouncy_value);
                            node_positions.push_back(p);
                            is_object.push_back(false);
                        }
                    }
                    else {
                        // Collide with unloaded nodes
                        aabb3f box = getNodeBox(p, BS);
                        cboxes.push_back(box);
                        is_unloaded.push_back(true);
                        is_step_up.push_back(false);
                        bouncy_values.push_back(0);
                        node_positions.push_back(p);
                        is_object.push_back(false);
                    }
                }

        // Do not move if world has not loaded yet, since custom node boxes
        // are not available for collision detection.
        if (!any_position_valid)
            return result;

    } // tt2

    if(collideWithObjects)
    {
        ScopeProfiler sp(g_profiler, "collisionMoveSimple objects avg", SPT_AVG);
        //TimeTaker tt3("collisionMoveSimple collect object boxes");

        /* add object boxes to cboxes */

        std::vector<ActiveObject*> objects;
#ifndef SERVER
        ClientEnvironment *c_env = dynamic_cast<ClientEnvironment*>(env);
        if (c_env != 0) {
            f32 distance = speed_f.getLength();
            std::vector<DistanceSortedActiveObject> clientobjects;
            c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
            for (size_t i=0; i < clientobjects.size(); i++) {
                if ((self == 0) || (self != clientobjects[i].obj)) {
                    objects.push_back((ActiveObject*)clientobjects[i].obj);
                }
            }
        }
        else
#endif
        {
            ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
            if (s_env != 0) {
                f32 distance = speed_f.getLength();
                std::vector<u16> s_objects;
                s_env->getObjectsInsideRadius(s_objects, pos_f, distance * 1.5);
                for (std::vector<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); ++iter) {
                    ServerActiveObject *current = s_env->getActiveObject(*iter);
                    if ((self == 0) || (self != current)) {
                        objects.push_back((ActiveObject*)current);
                    }
                }
            }
        }

        for (std::vector<ActiveObject*>::const_iterator iter = objects.begin();
                iter != objects.end(); ++iter) {
            ActiveObject *object = *iter;

            if (object != NULL) {
                aabb3f object_collisionbox;
                if (object->getCollisionBox(&object_collisionbox) &&
                        object->collideWithObjects()) {
                    cboxes.push_back(object_collisionbox);
                    is_unloaded.push_back(false);
                    is_step_up.push_back(false);
                    bouncy_values.push_back(0);
                    node_positions.push_back(v3s16(0,0,0));
                    is_object.push_back(true);
                }
            }
        }
    } //tt3

    assert(cboxes.size() == is_unloaded.size());    // post-condition
    assert(cboxes.size() == is_step_up.size());     // post-condition
    assert(cboxes.size() == bouncy_values.size());  // post-condition
    assert(cboxes.size() == node_positions.size()); // post-condition
    assert(cboxes.size() == is_object.size());      // post-condition

    /*
    	Collision detection
    */

    /*
    	Collision uncertainty radius
    	Make it a bit larger than the maximum distance of movement
    */
    f32 d = pos_max_d * 1.1;
    // A fairly large value in here makes moving smoother
    //f32 d = 0.15*BS;

    // This should always apply, otherwise there are glitches
    assert(d > pos_max_d);	// invariant

    int loopcount = 0;

    while(dtime > BS * 1e-10) {
        //TimeTaker tt3("collisionMoveSimple dtime loop");
        ScopeProfiler sp(g_profiler, "collisionMoveSimple dtime loop avg", SPT_AVG);

        // Avoid infinite loop
        loopcount++;
        if (loopcount >= 100) {
            warningstream << "collisionMoveSimple: Loop count exceeded, aborting to avoid infiniite loop" << std::endl;
            dtime = 0;
            break;
        }

        aabb3f movingbox = box_0;
        movingbox.MinEdge += pos_f;
        movingbox.MaxEdge += pos_f;

        int nearest_collided = -1;
        f32 nearest_dtime = dtime;
        u32 nearest_boxindex = -1;

        /*
        	Go through every nodebox, find nearest collision
        */
        for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
            // Ignore if already stepped up this nodebox.
            if(is_step_up[boxindex])
                continue;

            // Find nearest collision of the two boxes (raytracing-like)
            f32 dtime_tmp;
            int collided = axisAlignedCollision(
                               cboxes[boxindex], movingbox, speed_f, d, dtime_tmp);

            if (collided == -1 || dtime_tmp >= nearest_dtime)
                continue;

            nearest_dtime = dtime_tmp;
            nearest_collided = collided;
            nearest_boxindex = boxindex;
        }

        if (nearest_collided == -1) {
            // No collision with any collision box.
            pos_f += speed_f * dtime;
            dtime = 0;  // Set to 0 to avoid "infinite" loop due to small FP numbers
        } else {
            // Otherwise, a collision occurred.

            const aabb3f& cbox = cboxes[nearest_boxindex];
            // Check for stairs.
            bool step_up = (nearest_collided != 1) && // must not be Y direction
                           (movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
                           (movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
                           (!wouldCollideWithCeiling(cboxes, movingbox,
                                   cbox.MaxEdge.Y - movingbox.MinEdge.Y,
                                   d));

            // Get bounce multiplier
            bool bouncy = (bouncy_values[nearest_boxindex] >= 1);
            float bounce = -(float)bouncy_values[nearest_boxindex] / 100.0;

            // Move to the point of collision and reduce dtime by nearest_dtime
            if (nearest_dtime < 0) {
                // Handle negative nearest_dtime (can be caused by the d allowance)
                if (!step_up) {
                    if (nearest_collided == 0)
                        pos_f.X += speed_f.X * nearest_dtime;
                    if (nearest_collided == 1)
                        pos_f.Y += speed_f.Y * nearest_dtime;
                    if (nearest_collided == 2)
                        pos_f.Z += speed_f.Z * nearest_dtime;
                }
            } else {
                pos_f += speed_f * nearest_dtime;
                dtime -= nearest_dtime;
            }

            bool is_collision = true;
            if (is_unloaded[nearest_boxindex])
                is_collision = false;

            CollisionInfo info;
            if (is_object[nearest_boxindex])
                info.type = COLLISION_OBJECT;
            else
                info.type = COLLISION_NODE;

            info.node_p = node_positions[nearest_boxindex];
            info.bouncy = bouncy;
            info.old_speed = speed_f;

            // Set the speed component that caused the collision to zero
            if (step_up) {
                // Special case: Handle stairs
                is_step_up[nearest_boxindex] = true;
                is_collision = false;
            } else if(nearest_collided == 0) { // X
                if (fabs(speed_f.X) > BS * 3)
                    speed_f.X *= bounce;
                else
                    speed_f.X = 0;
                result.collides = true;
                result.collides_xz = true;
            }
            else if(nearest_collided == 1) { // Y
                if(fabs(speed_f.Y) > BS * 3)
                    speed_f.Y *= bounce;
                else
                    speed_f.Y = 0;
                result.collides = true;
            } else if(nearest_collided == 2) { // Z
                if (fabs(speed_f.Z) > BS * 3)
                    speed_f.Z *= bounce;
                else
                    speed_f.Z = 0;
                result.collides = true;
                result.collides_xz = true;
            }

            info.new_speed = speed_f;
            if (info.new_speed.getDistanceFrom(info.old_speed) < 0.1 * BS)
                is_collision = false;

            if (is_collision) {
                result.collisions.push_back(info);
            }
        }
    }

    /*
    	Final touches: Check if standing on ground, step up stairs.
    */
    aabb3f box = box_0;
    box.MinEdge += pos_f;
    box.MaxEdge += pos_f;
    for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
        const aabb3f& cbox = cboxes[boxindex];

        /*
        	See if the object is touching ground.

        	Object touches ground if object's minimum Y is near node's
        	maximum Y and object's X-Z-area overlaps with the node's
        	X-Z-area.

        	Use 0.15*BS so that it is easier to get on a node.
        */
        if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X &&
                cbox.MaxEdge.Z - d > box.MinEdge.Z &&
                cbox.MinEdge.Z + d < box.MaxEdge.Z) {
            if (is_step_up[boxindex]) {
                pos_f.Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
                box = box_0;
                box.MinEdge += pos_f;
                box.MaxEdge += pos_f;
            }
            if (fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.15 * BS) {
                result.touching_ground = true;

                if (is_object[boxindex])
                    result.standing_on_object = true;
                if (is_unloaded[boxindex])
                    result.standing_on_unloaded = true;
            }
        }
    }

    return result;
}
Пример #6
0
void OutdoorPvP::OnCreatureCreate(Creature* creature)
{
    CreatureScriptPair sp(creature->GetGUID().GetCounter(), creature);
    m_CreatureScriptStore.insert(sp);
}
Пример #7
0
void tb(void) {		// print a mini-trace
	if (!trace) return;
	sp("@");printHex((unsigned long)fetchptr); spb(' ');
	sp("s");printHex(sym); spb(' ');
	sp("i");printHex(inchar); speol();
}
Пример #8
0
void frame::patch_fp(int* fp) {
  frame previous(NULL, ((int*) sp()) - frame_sender_sp_offset, NULL);
  previous.set_link(fp);
}
// Return a unique id for this frame. The id must have a value where
// we can distinguish identity and younger/older relationship. NULL
// represents an invalid (incomparable) frame.
inline intptr_t* frame::id() const {
  return sp();
}
inline intptr_t* frame::unextended_sp() const { return sp(); }
Пример #11
0
void frame::patch_pc(char* pc) {
  char** pc_addr = (char**) sp() - 1;
  *pc_addr = pc;
}
inline int frame::frame_size() const { return sender_sp() - sp(); }
Пример #13
0
void Cql2Dnf::_buildEvalHeap()
{
	PEG_METHOD_ENTER(TRC_CQL, "Cql2Dnf::_buildEvalHeap");

    Stack<stack_el> stack;

    // Counter for Operands
    Uint32 j = 0;

    for (Uint32 i = 0, n = _operations.size(); i < n; i++)
    {
        OperationType op = _operations[i];

        switch (op)
        {
            case CQL_OR:
            case CQL_AND:
            {
                PEGASUS_ASSERT(stack.size() >= 2);

                stack_el op1 = stack.top();
                stack.pop();

                stack_el op2 = stack.top();

                // generate Eval expression
                eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal,
                                 op2.opn , op2.is_terminal));

                stack.top() = stack_el(eval_heap.size()-1, false);

                break;
            }

            case CQL_NOT:
            {
                PEGASUS_ASSERT(stack.size() >= 1);

                stack_el op1 = stack.top();

                // generate Eval expression
                eval_heap.append(eval_el(0, op , op1.opn, op1.is_terminal,
                                 -1, true));

                stack.top() = stack_el(eval_heap.size()-1, false);

                break;
            }

            case CQL_EQ: 
            case CQL_NE:
            case CQL_LT:
            case CQL_LE:
            case CQL_GT:
            case CQL_GE:
				case CQL_ISA:
				case CQL_LIKE:
            {
                PEGASUS_ASSERT(_operands.size() >= 2);

                CQLExpression lhs = _operands[j++];

                CQLExpression rhs = _operands[j++];

		CQLSimplePredicate sp(lhs,rhs,_convertOpType(op));
                terminal_heap.push(term_el(false, sp));

                stack.push(stack_el(terminal_heap.size()-1, true));

                break;
            }

            case CQL_IS_NULL:
            {
                PEGASUS_ASSERT(_operands.size() >= 1);
                CQLExpression expression = _operands[j++];
		CQLSimplePredicate dummy(expression,IS_NULL);
                terminal_heap.push(term_el(false, dummy));

                stack.push(stack_el(terminal_heap.size()-1, true));

                break;
            }

            case CQL_IS_NOT_NULL:
            {
                PEGASUS_ASSERT(_operands.size() >= 1);
                CQLExpression expression = _operands[j++];
                CQLSimplePredicate dummy(expression,IS_NOT_NULL);
                terminal_heap.push(term_el(false, dummy));

                stack.push(stack_el(terminal_heap.size()-1, true));

                break;
            }
	    case CQL_NOOP:
	    default: break;
        }
    }

    PEGASUS_ASSERT(stack.size() == 1);

    PEG_METHOD_EXIT();
}
Пример #14
0
int main(void)
{
    int64 t0,t1,t2,t3;
    d();
    s=(int64*)calloc(q,sizeof(int64));
    gw(2,0,1000);
    gw(3,0,1500000);
    sa(gr(3,0));
    gw(tm(gr(3,0),gr(2,0)),(td(gr(3,0),gr(2,0)))+3,0);
_1:
    sa(sr()-1);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa((sp()!=0)?0:1);
    if(sp()!=0)goto _3;else goto _2;
_2:
    sa(sr());
    sa(0);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(tm(sr(),gr(2,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(2,0)));
    sa(sp()+3LL);
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    goto _1;
_3:
    gw(6,0,0);
    gw(8,0,1);
    sp();
_4:
    if(((gr(8,0)*gr(8,0)*4)+(gr(8,0)*6)+2)>gr(3,0))goto _20;else goto _5;
_5:
    sa(gr(8,0)+1);
    gw(9,0,gr(8,0)+1);
_6:
    sa(sr());
    t0=sr()*2;
    sa(sp()*t0);
    t1=sp();
    sa(sp()*gr(8,0)*2);
    sa(t1);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sp()+sp());
    t0=sp();
    t0=t0>gr(3,0)?1:0;
    if((t0)!=0)goto _19;else goto _7;
_7:
    t0=(gr(9,0)*gr(9,0))-(gr(8,0)*gr(8,0));
    gw(2,1,(gr(9,0)*gr(9,0))-(gr(8,0)*gr(8,0)));
    t1=gr(8,0)*gr(9,0)*2;
    gw(3,1,gr(8,0)*gr(9,0)*2);
    t2=(gr(9,0)*gr(9,0))+(gr(8,0)*gr(8,0));
    gw(4,1,(gr(9,0)*gr(9,0))+(gr(8,0)*gr(8,0)));
    t3=t1+t2;
    t1=t0+t3;
    gw(6,1,t1);
    if(gr(2,1)>gr(3,1))goto _18;else goto _8;
_8:
    sa(1);
    sa(gr(6,1)>gr(3,0)?1:0);
_9:
    if(sp()!=0)goto _17;else goto _10;
_10:
    t0=sr()*((((gr(2,1)*7)+gr(3,1))*5)+gr(4,1));
    gw(8,1,t0);
    sa(sr()*gr(6,1));
    sa(tm(sr(),gr(2,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(2,0)));
    sa(sp()+3LL);
    {int64 v0=sp();sa(gr(sp(),v0));}
    sa(sr());
    if(sp()!=0)goto _13;else goto _11;
_11:
    sp();
    sa(sr()*gr(6,1));
    sa(gr(8,1));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(tm(sr(),gr(2,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(2,0)));
    sa(sp()+3LL);
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    gw(6,0,gr(6,0)+1);
_12:
    sa(sp()+1LL);
    sa((sr()*gr(6,1))>gr(3,0)?1:0);
    goto _9;
_13:
    if(sr()!=gr(8,1))goto _14;else goto _16;
_14:
    sa((sp()<0)?1:0);
    if(sp()!=0)goto _12;else goto _15;
_15:
    sa(sr()*gr(6,1));
    sa(-1);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(tm(sr(),gr(2,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(2,0)));
    sa(sp()+3LL);
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    gw(6,0,gr(6,0)-1);
    goto _12;
_16:
    sp();
    goto _12;
_17:
    sp();
    sa(gr(9,0)+1);
    gw(9,0,gr(9,0)+1);
    goto _6;
_18:
    t0=gr(2,1);
    gw(2,1,gr(3,1));
    gw(3,1,t0);
    goto _8;
_19:
    gw(8,0,gr(8,0)+1);
    goto _4;
_20:
    printf("%lld", gr(6,0));
    return 0;
}
int main(void)
{
    int64 t0;
    int64 x0=10000000000;
    int64 x1=32;
    int64 x2=32;
    s=(int64*)calloc(q,sizeof(int64));
    sa(0);
    sa(1000);
    sa(1000);
_1:
    if(sp()!=0)goto _3;else goto _2;
_2:
    sp();
    printf("%lld ", (int64)(sp()));
    return 0;
_3:
    x2=sr();
    sa(sr());
    x1=sr();
_4:
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(sp()-1LL);

    sa(sr());

    if(sp()!=0)goto _6;else goto _5;
_5:
    sp();
    sp();
    sa(sp()+x1);

    sa(tm(sp(),x0));

    sa(x2-1);
    sa(x2-1);
    goto _1;
_6:
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    t0=tm(sr()*x1,x0);
    x1=t0;
    goto _4;
}
Пример #16
0
bool TraceBuilder::constrainStack(int32_t idx, TypeConstraint tc) {
  return constrainStack(sp(), idx, tc);
}
Пример #17
0
int main(void)
{
    int64 t0;
    d();
    s=(int64*)calloc(q,sizeof(int64));
    gw(1,0,600);
    gw(2,0,150);
    gw(9,0,90000);
    gw(3,0,2);
    gw(4,0,1000);
    gw(3,1,0);
_1:
    gw(tm(gr(3,0),gr(1,0)),(td(gr(3,0),gr(1,0)))+3,88);
    sa(gr(3,0)+gr(3,0));
    sa((gr(3,0)+gr(3,0))<gr(9,0)?1:0);
_2:
    if(sp()!=0)goto _21;else goto _3;
_3:
    sp();
_4:
    sa(gr(3,0)+1);
    gw(3,0,gr(3,0)+1);
    sa(tm(sr(),gr(1,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(1,0)));
    sa(sp()+3LL);
    {int64 v0=sp();t0=gr(sp(),v0);}
    t0-=32;
    if((t0)!=0)goto _6;else goto _4;
_6:
    if(gr(9,0)>gr(3,0))goto _1;else goto _7;
_7:
    gw(0,3,32);
    gw(1,3,32);
    gw(5,0,1-gr(4,0));
    gw(6,0,2);
_8:
    gw(7,0,0);
    sa((gr(5,0)*gr(7,0))+gr(6,0));
    sa(((gr(5,0)*gr(7,0))+gr(6,0))>1?1:0);
_9:
    if(sp()!=0)goto _10;else goto _20;
_10:
    sa(tm(sr(),gr(1,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(1,0)));
    sa(sp()+3LL);
    {int64 v0=sp();t0=gr(sp(),v0);}
    t0-=32;
    if((t0)!=0)goto _19;else goto _11;
_11:
    t0=gr(7,0);
    if(gr(7,0)>gr(3,1))goto _18;else goto _12;
_12:
    t0=gr(5,0)+2;
    gw(5,0,gr(5,0)+2);
    t0=t0>gr(4,0)?1:0;
    t0=(t0!=0)?0:1;
    if((t0)!=0)goto _8;else goto _13;
_13:
    gw(5,0,1-gr(4,0));
_14:
    sa(gr(6,0)+1);
    gw(6,0,gr(6,0)+1);
    sa(tm(sr(),gr(1,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(1,0)));
    sa(sp()+3LL);
    {int64 v0=sp();t0=gr(sp(),v0);}
    t0-=32;
    t0=(t0!=0)?0:1;
    if((t0)!=0)goto _14;else goto _16;
_16:
    if(gr(6,0)<=gr(4,0))goto _8;else goto _17;
_17:
    printf("%lld", gr(1,1)*gr(2,1));
    return 0;
_18:
    gw(3,1,t0);
    gw(1,1,gr(5,0));
    gw(2,1,gr(6,0));
    goto _12;
_19:
    sa(gr(7,0)+1);
    gw(7,0,gr(7,0)+1);
    sa(sr());
    sa(sp()*sp());
    sa(sp()+(gr(5,0)*gr(7,0))+gr(6,0));
    sa(sr()>1?1:0);
    goto _9;
_20:
    sp();
    goto _11;
_21:
    sa(sr());
    sa(32);
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(tm(sr(),gr(1,0)));
    {int64 v0=sp();int64 v1=sp();sa(v0);sa(v1);}
    sa(td(sp(),gr(1,0)));
    sa(sp()+3LL);
    {int64 v0=sp();int64 v1=sp();gw(v1,v0,sp());}
    sa(sp()+gr(3,0));
    sa(sr()<gr(9,0)?1:0);
    goto _2;
}
Пример #18
0
bool installSpecies(size_t k, const XML_Node& s, thermo_t& th,
                    SpeciesThermo* spthermo_ptr, int rule,
                    XML_Node* phaseNode_ptr,
                    VPSSMgr* vpss_ptr,
                    SpeciesThermoFactory* factory)
{
    std::string xname = s.name();
    if (xname != "species") {
        throw CanteraError("installSpecies",
                           "Unexpected XML name of species XML_Node: " + xname);
    }

    if (rule) {
        th.ignoreUndefinedElements();
    }

    // get the composition of the species
    const XML_Node& a = s.child("atomArray");
    map<string,string> comp;
    getMap(a, comp);

    // construct a vector of atom numbers for each element in phase th. Elements
    // not declared in the species (i.e., not in map comp) will have zero
    // entries in the vector.
    size_t nel = th.nElements();
    vector_fp ecomp(nel, 0.0);
    compositionMap comp_map = parseCompString(a.value());
    for (size_t m = 0; m < nel; m++) {
        std::string& es = comp[th.elementName(m)];
        if (!es.empty()) {
            ecomp[m] = fpValueCheck(es);
        }
    }

    // get the species charge, if any. Note that the charge need
    // not be explicitly specified if special element 'E'
    // (electron) is one of the elements.
    doublereal chrg = 0.0;
    if (s.hasChild("charge")) {
        chrg = getFloat(s, "charge");
    }

    // get the species size, if any. (This is used by surface
    // phases to represent how many sites a species occupies.)
    doublereal sz = 1.0;
    if (s.hasChild("size")) {
        sz = getFloat(s, "size");
    }

    if (vpss_ptr) {
        th.addUniqueSpecies(s["name"], &ecomp[0], chrg, sz);
        VPStandardStateTP* vp_ptr = dynamic_cast<VPStandardStateTP*>(&th);
        vp_ptr->createInstallPDSS(k, s, phaseNode_ptr);
    } else {
        SpeciesThermoInterpType* st = newSpeciesThermoInterpType(s);
        Species sp(s["name"], comp_map, st, chrg, sz);

        // Read gas-phase transport data, if provided
        if (s.hasChild("transport") &&
                s.child("transport")["model"] == "gas_transport") {
            XML_Node& tr = s.child("transport");

            string geometry, dummy;
            getString(tr, "geometry", geometry, dummy);

            double diam = getFloat(tr, "LJ_diameter");
            double welldepth = getFloat(tr, "LJ_welldepth");

            double dipole = 0.0;
            getOptionalFloat(tr, "dipoleMoment", dipole);

            double polar = 0.0;
            getOptionalFloat(tr, "polarizability", polar);

            double rot = 0.0;
            getOptionalFloat(tr, "rotRelax", rot);
            double acentric = 0.0;
            getOptionalFloat(tr, "acentric_factor", acentric);

            GasTransportData* gastran = new GasTransportData;
            gastran->setCustomaryUnits(sp.name, geometry, diam, welldepth,
                                       dipole, polar, rot, acentric);
            sp.transport.reset(gastran);
            gastran->validate(sp);
        }
        th.addSpecies(sp);
    }

    return true;
}
Пример #19
0
void *EmergeThread::Thread() {
	ThreadStarted();
	log_register_thread("EmergeThread" + itos(id));
	DSTACK(__FUNCTION_NAME);
	BEGIN_DEBUG_EXCEPTION_HANDLER

	v3s16 last_tried_pos(-32768,-32768,-32768); // For error output
	v3s16 p;
	u8 flags;

	map    = (ServerMap *)&(m_server->m_env->getMap());
	emerge = m_server->m_emerge;
	mapgen = emerge->mapgen[id];
	enable_mapgen_debug_info = emerge->mapgen_debug_info;

	while (!StopRequested())
	try {
		if (!popBlockEmerge(&p, &flags)) {
			qevent.wait();
			continue;
		}

		last_tried_pos = p;
		if (blockpos_over_limit(p))
			continue;

		bool allow_generate = flags & BLOCK_EMERGE_ALLOWGEN;
		EMERGE_DBG_OUT("p=" PP(p) " allow_generate=" << allow_generate);

		/*
			Try to fetch block from memory or disk.
			If not found and asked to generate, initialize generator.
		*/
		BlockMakeData data;
		MapBlock *block = NULL;
		std::map<v3s16, MapBlock *> modified_blocks;

		if (getBlockOrStartGen(p, &block, &data, allow_generate) && mapgen) {
			{
				ScopeProfiler sp(g_profiler, "EmergeThread: Mapgen::makeChunk", SPT_AVG);
				TimeTaker t("mapgen::make_block()");

				mapgen->makeChunk(&data);

				if (enable_mapgen_debug_info == false)
					t.stop(true); // Hide output
			}

			{
				//envlock: usually 0ms, but can take either 30 or 400ms to acquire
				JMutexAutoLock envlock(m_server->m_env_mutex);
				ScopeProfiler sp(g_profiler, "EmergeThread: after "
						"Mapgen::makeChunk (envlock)", SPT_AVG);

				map->finishBlockMake(&data, modified_blocks);

				block = map->getBlockNoCreateNoEx(p);
				if (block) {
					/*
						Do some post-generate stuff
					*/
					v3s16 minp = data.blockpos_min * MAP_BLOCKSIZE;
					v3s16 maxp = data.blockpos_max * MAP_BLOCKSIZE +
								 v3s16(1,1,1) * (MAP_BLOCKSIZE - 1);

					// Ignore map edit events, they will not need to be sent
					// to anybody because the block hasn't been sent to anybody
					MapEditEventAreaIgnorer
						ign(&m_server->m_ignore_map_edit_events_area,
						VoxelArea(minp, maxp));
					try {  // takes about 90ms with -O1 on an e3-1230v2
						m_server->getScriptIface()->environment_OnGenerated(
								minp, maxp, emerge->getBlockSeed(minp));
					} catch(LuaError &e) {
						m_server->setAsyncFatalError(e.what());
					}

					EMERGE_DBG_OUT("ended up with: " << analyze_block(block));

					m_server->m_env->activateBlock(block, 0);
				}
			}
		}

		/*
			Set sent status of modified blocks on clients
		*/
		// Add the originally fetched block to the modified list
		if (block)
			modified_blocks[p] = block;

		if (modified_blocks.size() > 0) {
			m_server->SetBlocksNotSent(modified_blocks);
		}
	}
	catch (VersionMismatchException &e) {
		std::ostringstream err;
		err << "World data version mismatch in MapBlock "<<PP(last_tried_pos)<<std::endl;
		err << "----"<<std::endl;
		err << "\""<<e.what()<<"\""<<std::endl;
		err << "See debug.txt."<<std::endl;
		err << "World probably saved by a newer version of Minetest."<<std::endl;
		m_server->setAsyncFatalError(err.str());
	}
	catch (SerializationError &e) {
		std::ostringstream err;
		err << "Invalid data in MapBlock "<<PP(last_tried_pos)<<std::endl;
		err << "----"<<std::endl;
		err << "\""<<e.what()<<"\""<<std::endl;
		err << "See debug.txt."<<std::endl;
		err << "You can ignore this using [ignore_world_load_errors = true]."<<std::endl;
		m_server->setAsyncFatalError(err.str());
	}

	END_DEBUG_EXCEPTION_HANDLER(errorstream)
	log_deregister_thread();
	return NULL;
}
int UHD_SAFE_MAIN(int argc, char *argv[]){



    if (uhd::set_thread_priority_safe(1,true)) {
       std::cout << "set priority went well " << std::endl;
    };


    #if 0
    int portno=30000;
    //int s=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in  server;
    struct hostent *hp;
    struct in_addr ipv4addr;
    

    inet_pton(AF_INET, "127.0.0.1", &ipv4addr);

    bzero((char *)&server, sizeof (server));
    hp = gethostbyaddr(&ipv4addr,sizeof(ipv4addr), AF_INET);
    bcopy(hp->h_addr, (char *)&server.sin_addr,
          hp->h_length);  
    server.sin_family = hp->h_addrtype;
    server.sin_port = htons(portno);
    int s = socket(hp->h_addrtype, SOCK_STREAM, 0);
    if (s < 0) 
      std::cerr << "ERROR opening socket";

    connect(s, (struct sockaddr *)&server, sizeof(server));
    usleep(1003);

    char buffer[6];
    usleep(1e6);
    buffer[0]=65;
    buffer[1]=66;
    buffer[2]=67;
    buffer[3]=68;
    buffer[4]=10;
    buffer[5]=0;

    short nb[5];
    nb[0]=htons(23); nb[1]=htons(-24); nb[2]=htons(77); 
    nb[3]=htons(-18);  nb[4]=htons(-33); 

    std::cout << "strlen=" << strlen(buffer) << "\n";

    
    for (int i1=0;i1<10;i1++) {
      std::cout << "buffer[" << i1 << "]=" << (unsigned int)buffer[i1] << "\n";
    };
    

    //int n = write(s,buffer,strlen(buffer));
    int n = write(s,nb,sizeof(nb));

    std::cout << "n=" << n << "\n";
    if (n < 0) 
      std::cerr << "ERROR writing to socket";

    close(s);
    usleep(100e6);
    #endif


    //variables to be set by po
    std::string args;
    double seconds_in_future;
    size_t total_num_samps, total_num_repeats;
    int send_to_listener;
    
    double rate, freq_tx, freq_rx;
    float gain;
    std::string filename_rx, filename_tx;
    uhd::tx_streamer::sptr tx_stream;
    uhd::rx_streamer::sptr rx_stream;
    uhd::device_addr_t dev_addr;
    uhd::usrp::multi_usrp::sptr dev;
    uhd::stream_args_t stream_args;

    //setup the program options
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "help message")
        ("args", po::value<std::string>(&args)->default_value(""), "simple uhd device address args")
        ("secs", po::value<double>(&seconds_in_future)->default_value(0.5), "number of seconds in the future to transmit")
        ("nsamps", po::value<size_t>(&total_num_samps)->default_value(1000), "Total number of samples to transmit and receive")
        ("nrep", po::value<size_t>(&total_num_repeats)->default_value(1), "Total number of repeats")
        ("rate", po::value<double>(&rate)->default_value(100e6/8), "rate of outgoing and ingoing samples")
        ("freq_rx", po::value<double>(&freq_rx)->default_value(20e6), "receive center frequency in Hz")
        ("freq_tx", po::value<double>(&freq_tx)->default_value(20e6), "transmit center frequency in Hz")
        ("filename_tx",po::value<std::string>(&filename_tx)->default_value("data_to_usrp.dat"), "tx filename")
        ("filename_rx",po::value<std::string>(&filename_rx)->default_value("data_from_usrp.dat"), "rx filename")        
        ("gain",po::value<float>(&gain)->default_value(0), "gain of transmitter")        
        ("n",po::value<int>(&send_to_listener)->default_value(0), "Every n:th received buffer is sent to a client listening on port 3000. ")        

    ;

    

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);

    if (vm.count("help")){
        std::cout << boost::format("rxtx_bidirectional %s") % desc << std::endl;
        return ~0;
    }





    int s; 

    if (send_to_listener>0) {

      struct sockaddr_in  server;
      struct hostent *hp;
      struct in_addr ipv4addr;
      int portno=30000;    

      inet_pton(AF_INET, "127.0.0.1", &ipv4addr);

      bzero((char *)&server, sizeof (server));
      hp = gethostbyaddr(&ipv4addr,sizeof(ipv4addr), AF_INET);
      bcopy(hp->h_addr, (char *)&server.sin_addr,
          hp->h_length);  
      server.sin_family = hp->h_addrtype;
      server.sin_port = htons(portno);
      s = socket(hp->h_addrtype, SOCK_STREAM, 0);
      if (s < 0) 
	std::cerr << "ERROR opening socket";

      connect(s, (struct sockaddr *)&server, sizeof(server));
    } ;



    int process_buffer_size=9000; // Buffer size in processing
    int tx_ahead_buffers=3; // Number of buffers transmitted before starting
                            // to receive.

    signal_processing sp(total_num_samps,total_num_repeats,send_to_listener,s,
	       process_buffer_size,filename_rx,filename_tx);


    std::complex<int16_t> *process_buffer_tx;
    process_buffer_tx = new std::complex<int16_t>[process_buffer_size];

    std::complex<int16_t> *process_buffer_rx;
    process_buffer_rx = new std::complex<int16_t>[process_buffer_size];

    
    /* Create buffer storage for trailing zeros */
    std::complex<int16_t> *buffer_zeros;
    buffer_zeros = new std::complex<int16_t>[process_buffer_size]();
    

    //create a usrp device and streamer
    dev_addr["addr0"]="192.168.10.2";
    dev = uhd::usrp::multi_usrp::make(dev_addr);    

    dev->set_clock_source("internal");
    dev->set_time_now(uhd::time_spec_t(0.0), 0);

    // Internal variables 
    uhd::clock_config_t my_clock_config; 



    uhd::tune_result_t tr;
    uhd::tune_request_t trq_rx(freq_rx,0); //std::min(tx_rate,10e6));
    tr=dev->set_rx_freq(trq_rx,0);

    uhd::tune_request_t trq_tx(freq_tx,0); //std::min(tx_rate,10e6));
    tr=dev->set_tx_freq(trq_tx,0);

    

    uhd::dict<std::string, std::string> tx_info;    
    tx_info=dev->get_usrp_tx_info(0);


    dev->set_tx_gain(gain);
    std::cout << tr.to_pp_string() << "\n";
 

    stream_args.cpu_format="sc16";
    tx_stream=dev->get_tx_stream(stream_args);
    rx_stream=dev->get_rx_stream(stream_args);



    //set properties on the device
    dev->set_tx_rate(rate);
    dev->set_rx_rate(rate);
    std::cout << boost::format("Actual TX Rate: %f Msps...") % (dev->get_tx_rate()/1e6) << std::endl;
    std::cout << boost::format("Actual RX Rate: %f Msps...") % (dev->get_rx_rate()/1e6) << std::endl;
    std::cout << boost::format("Setting device timestamp to 0...") << std::endl;
    uhd::tx_metadata_t md;
  


    dev->set_time_now(uhd::time_spec_t(0.0));



    uhd::rx_metadata_t md_rx;
    //uhd::stream_cmd_t 
    //  stream_cmd(uhd::stream_cmd_t::STREAM_MODE_NUM_SAMPS_AND_DONE);

    uhd::stream_cmd_t 
      stream_cmd(uhd::stream_cmd_t::STREAM_MODE_START_CONTINUOUS);


    stream_cmd.num_samps = total_num_samps;
    stream_cmd.stream_now = false;
    stream_cmd.time_spec = uhd::time_spec_t(seconds_in_future);
    rx_stream->issue_stream_cmd(stream_cmd);


    md.start_of_burst = true;
    md.end_of_burst = false;
    md.has_time_spec = true;
    md.time_spec = uhd::time_spec_t(seconds_in_future);

    for (int i1=tx_ahead_buffers;i1>0;i1--) {
      tx_stream->send(buffer_zeros, 
		    process_buffer_size , md);
      md.start_of_burst = false;
      md.has_time_spec = false;
    };
 
    md.start_of_burst = false;
    int return_value=1;

    while (return_value!=0) {

       rx_stream->recv(process_buffer_rx,
	    process_buffer_size, md_rx, seconds_in_future+1);
       return_value=sp.process_buffers(process_buffer_rx, process_buffer_tx);
       tx_stream->send(process_buffer_tx, 
		    process_buffer_size , md); 

      
    };

    md.end_of_burst = true;
    tx_stream->send(buffer_zeros, process_buffer_size , md);


    //finished
    std::cout << std::endl << "Done!" << std::endl << std::endl;



    return 0;
}
Пример #21
0
inline bool CDS_YHay<Tprec, Dim>::calcCoefficients3D () 
{
    prec_t dyz = dy * dz, dyz_dx = Gamma * dyz / dx;
    prec_t dxz = dx * dz, dxz_dy = Gamma * dxz / dy;
    prec_t dxy = dx * dy, dxy_dz = Gamma * dxy / dz;
    prec_t dxyz_dt = dx * dy * dz / dt;
    prec_t ce, cep, cem, cw, cwp, cwm, CE, CW;
    prec_t cn, cnp, cnm, cs, csp, csm, CN, CS;
    prec_t cf, cfp, cfm, cb, cbp, cbm, CF, CB;
    prec_t RaGaVol = Rayleigh * Gamma * 0.5 * dx * dy * dz;
    aE = 0.0; aW = 0.0; aN = 0.0; aS = 0.0; aF = 0.0; aB = 0.0; aP = 0.0; 
    sp = 0.0;

    for (int k = bk; k <= ek; ++k)
      for (int i =  bi; i <= ei; ++i)
	for (int j = bj; j <= ej; ++j)
	  {
	    CE = ce = ( u(i  ,j,k) + u(i  ,j+1,k  ) ) * 0.5 * dyz;
	    CW = cw = ( u(i-1,j,k) + u(i-1,j+1,k  ) ) * 0.5 * dyz;
	    CN = cn = ( v(i  ,j,k) + v(i  ,j+1,k  ) ) * 0.5 * dxz;
	    CS = cs = ( v(i  ,j,k) + v(i  ,j-1,k  ) ) * 0.5 * dxz;
	    CF = cf = ( w(i  ,j,k) + w(i  ,j  ,k+1) ) * 0.5 * dxy;
	    CB = cb = ( w(i-1,j,k) + w(i-1,j  ,k+1) ) * 0.5 * dxy;
	    cem = cep = 0;
	    cwm = cwp = 0;
	    cnm = cnp = 0;
	    csm = csp = 0;
	    cfm = cfp = 0;
	    cbm = cbp = 0;

	    if ( ce > 0 ){
	      CE = 0;
	      cep = ce * 0.5 * (-phi_0(i,j,k) + phi_0(i+1,j,k));
	    } else {
	      cem = ce * 0.5 * (phi_0(i,j,k) - phi_0(i+1,j,k));
	    } 
	  
	    if ( cw > 0 ){
	      cwp = cw * 0.5 * (-phi_0(i-1,j,k) + phi_0(i,j,k));
	    } else {
	      CW = 0.0;
	      cwm = cw * 0.5 * (phi_0(i-1,j,k) - phi_0(i,j,k));
	    } 	    
	    
	    if ( cn > 0 ){
	      CN = 0;
	      cnp = cn * 0.5 * (-phi_0(i,j,k) + phi_0(i,j+1,k));
	    } else {
	      cnm = cn * 0.5 * (phi_0(i,j,k) - phi_0(i,j+1,k));
	    } 
	    
	    if ( cs > 0 ){
	      csp = cs * 0.5 * (-phi_0(i,j-1,k) + phi_0(i,j,k));
	    } else {
	      CS = 0.0;
	      csm = cs * 0.5 * (phi_0(i,j-1,k) - phi_0(i,j,k));
	    } 

	    if ( cf > 0 ){
	      CF = 0;
	      cfp = cf * 0.5 * (-phi_0(i,j,k) + phi_0(i,j,k+1));
	    } else {
	      cfm = cf * 0.5 * (phi_0(i,j,k) - phi_0(i,j,k+1));
	    } 
	    
	    if ( cb > 0 ){
	      cbp = cb * 0.5 * (-phi_0(i,j,k-1) + phi_0(i,j,k));
	    } else {
	      CB = 0.0;
	      cbm = cb * 0.5 * (phi_0(i,j,k-1) - phi_0(i,j,k));
	    } 
	
	    aE (i,j,k) = dyz_dx - CE;
	    aW (i,j,k) = dyz_dx + CW;
	    aN (i,j,k) = dxz_dy - CN;
	    aS (i,j,k) = dxz_dy + CS;
	    aF (i,j,k) = dxy_dz - CF;
	    aB (i,j,k) = dxy_dz + CB;
	    aP (i,j,k) = aE (i,j,k) + aW (i,j,k) + aN (i,j,k) + aS (i,j,k)
	      + aF (i,j,k) + aB (i,j,k) + dxyz_dt
	      + (ce - cw) + (cn - cs) + (cn - cs);
	    sp (i,j,k) += v(i,j,k) * dxyz_dt - 
	      ( p(i,j+1,k) - p(i,j,k) ) * dxz +
	      RaGaVol * ( T(i,j,k) + T(i,j+1,k) )
	      - (cep + cem - cwp - cwm + cnp + cnm - csp - csm + cfp + cfm - cbp - cbm); 
	  }    
    calc_dv_3D();
    applyBoundaryConditions3D();
    return 0;
}
Пример #22
0
void TraceBuilder::constrainStack(int32_t idx, DataTypeCategory cat) {
    constrainStack(sp(), idx, cat);
}
Пример #23
0
int main(void)
{
    int64 t0,t1,t2,t3;
    int64 x0=1000;
    int64 x1=2;
    int64 x2=34;
    int64 x3=53;
    s=(int64*)calloc(q,sizeof(int64));
_1:
    x2=1;
_2:
    sa((x2*x2)+(x1*x1));
    x3=(x2*x2)+(x1*x1);
    sa(0);
    sa(0-x3);
_3:
    if(sp()!=0)goto _4;else goto _10;
_4:
    sa(sp()+1LL);
    if(sr()!=x0)goto _9;else goto _5;
_5:
    sp();
    sp();
_6:
    t0=x2+1;
    x2++;
    t0-=x1;
    if((t0)!=0)goto _2;else goto _7;
_7:
    t0=x1+1;
    x1++;
    t0-=x0;
    if((t0)!=0)goto _1;else goto _8;
_8:
    return 0;
_9:
    sa(sr());
    sa(sr());
    sa(sp()*sp());
    sa(sp()-x3);
    goto _3;
_10:
    x3=sr();
    sa(sp()+x2+x1);
    sa(sp()-x0);
    if(sp()!=0)goto _11;else goto _12;
_11:
    sp();
    goto _6;
_12:
    t0=x2;
    printf("%lld", x2);
    printf(" ");
    t1=x1;
    printf("%lld", x1);
    printf(" ");
    t2=x3;
    printf("%lld", x3);
    printf("=");
    t3=t1*t2;
    t1=t0*t3;
    printf("%lld", t1);
    return 0;
}
Пример #24
0
int RemoteClient::GetNextBlocks (
		ServerEnvironment *env,
		EmergeManager * emerge,
		float dtime,
		double m_uptime,
		std::vector<PrioritySortedBlockTransfer> &dest)
{
	DSTACK(FUNCTION_NAME);

	auto lock = lock_unique_rec();
	if (!lock->owns_lock())
		return 0;

	// Increment timers
	m_nothing_to_send_pause_timer -= dtime;
	m_nearest_unsent_reset_timer += dtime;
	m_time_from_building += dtime;

	if (m_nearest_unsent_reset) {
		m_nearest_unsent_reset = 0;
		m_nearest_unsent_reset_timer = 999;
		m_nothing_to_send_pause_timer = 0;
		m_time_from_building = 999;
	}

	if(m_nothing_to_send_pause_timer >= 0)
		return 0;

	Player *player = env->getPlayer(peer_id);
	// This can happen sometimes; clients and players are not in perfect sync.
	if(player == NULL)
		return 0;

	v3f playerpos = player->getPosition();
	v3f playerspeed = player->getSpeed();
	if(playerspeed.getLength() > 1000.0*BS) //cheater or bug, ignore him
		return 0;
	v3f playerspeeddir(0,0,0);
	if(playerspeed.getLength() > 1.0*BS)
		playerspeeddir = playerspeed / playerspeed.getLength();
	// Predict to next block
	v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS;

	v3s16 center_nodepos = floatToInt(playerpos_predicted, BS);

	v3s16 center = getNodeBlockPos(center_nodepos);

	// Camera position and direction
	v3f camera_pos = player->getEyePosition();
	v3f camera_dir = v3f(0,0,1);
	camera_dir.rotateYZBy(player->getPitch());
	camera_dir.rotateXZBy(player->getYaw());

	//infostream<<"camera_dir=("<<camera_dir<<")"<< " camera_pos="<<camera_pos<<std::endl;

	/*
		Get the starting value of the block finder radius.
	*/

	if(m_last_center != center)
	{
		m_last_center = center;
		m_nearest_unsent_reset_timer = 999;
	}

	if (m_last_direction.getDistanceFrom(camera_dir)>0.4) { // 1 = 90deg
		m_last_direction = camera_dir;
		m_nearest_unsent_reset_timer = 999;
	}

	/*infostream<<"m_nearest_unsent_reset_timer="
			<<m_nearest_unsent_reset_timer<<std::endl;*/

	// Reset periodically to workaround for some bugs or stuff
	if(m_nearest_unsent_reset_timer > 120.0)
	{
		m_nearest_unsent_reset_timer = 0;
		m_nearest_unsent_d = 0;
		m_nearest_unsent_reset = 0;
		//infostream<<"Resetting m_nearest_unsent_d for "<<peer_id<<std::endl;
	}

	//s16 last_nearest_unsent_d = m_nearest_unsent_d;
	s16 d_start = m_nearest_unsent_d;

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

	static const u16 max_simul_sends_setting = g_settings->getU16
			("max_simultaneous_block_sends_per_client");
	static const u16 max_simul_sends_usually = max_simul_sends_setting;

	/*
		Check the time from last addNode/removeNode.

		Decrease send rate if player is building stuff.
	*/
	static const auto full_block_send_enable_min_time_from_building = g_settings->getFloat("full_block_send_enable_min_time_from_building");
	if(m_time_from_building < full_block_send_enable_min_time_from_building)
	{
		/*
		max_simul_sends_usually
			= LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
		*/
		if(d_start<=1)
			d_start=2;
		m_nearest_unsent_reset_timer = 999; //magical number more than ^ other number 120 - need to reset d on next iteration
	}

	/*
		Number of blocks sending + number of blocks selected for sending
	*/
	u32 num_blocks_selected = 0;
	u32 num_blocks_sending = 0;

	/*
		next time d will be continued from the d from which the nearest
		unsent block was found this time.

		This is because not necessarily any of the blocks found this
		time are actually sent.
	*/
	s32 new_nearest_unsent_d = -1;

	static const auto max_block_send_distance = g_settings->getS16("max_block_send_distance");
	s16 full_d_max = max_block_send_distance;
	if (wanted_range) {
		s16 wanted_blocks = wanted_range / MAP_BLOCKSIZE + 1;
		if (wanted_blocks < full_d_max)
			full_d_max = wanted_blocks;
	}

	s16 d_max = full_d_max;
	static const s16 d_max_gen = g_settings->getS16("max_block_generate_distance");

	// Don't loop very much at a time
	s16 max_d_increment_at_time = 10;
	if(d_max > d_start + max_d_increment_at_time)
		d_max = d_start + max_d_increment_at_time;
	/*if(d_max_gen > d_start+2)
		d_max_gen = d_start+2;*/

	//infostream<<"Starting from "<<d_start<<std::endl;

	s32 nearest_emerged_d = -1;
	s32 nearest_emergefull_d = -1;
	s32 nearest_sent_d = -1;
	//bool queue_is_full = false;

	f32 speed_in_blocks = (playerspeed/(MAP_BLOCKSIZE*BS)).getLength();


	int blocks_occlusion_culled = 0;
	static const bool server_occlusion = g_settings->getBool("server_occlusion");
	bool occlusion_culling_enabled = server_occlusion;

	auto cam_pos_nodes = floatToInt(playerpos, BS);

	auto nodemgr = env->getGameDef()->getNodeDefManager();
	MapNode n;
	{
#if !ENABLE_THREADS
		auto lock = env->getServerMap().m_nothread_locker.lock_shared_rec();
#endif
		n = env->getMap().getNodeTry(cam_pos_nodes);
	}

	if(n && nodemgr->get(n).solidness == 2)
		occlusion_culling_enabled = false;

	unordered_map_v3POS<bool> occlude_cache;


	s16 d;
	for(d = d_start; d <= d_max; d++) {
		/*errorstream<<"checking d="<<d<<" for "
				<<server->getPlayerName(peer_id)<<std::endl;*/
		//infostream<<"RemoteClient::SendBlocks(): d="<<d<<" d_start="<<d_start<<" d_max="<<d_max<<" d_max_gen="<<d_max_gen<<std::endl;

		std::vector<v3POS> list;
		if (d > 2 && d == d_start && m_nearest_unsent_reset_timer != 999) { // oops, again magic number from up ^
			list.push_back(v3POS(0,0,0));
		}

		bool can_skip = d > 1;
		// Fast fall/move optimize. speed_in_blocks now limited to 6.4
		if (speed_in_blocks>0.8 && d <= 2) {
			can_skip = false;
			if (d == 0) {
				for(s16 addn = 0; addn < (speed_in_blocks+1)*2; ++addn)
					list.push_back(floatToInt(playerspeeddir*addn, 1));
			} else if (d == 1) {
				for(s16 addn = 0; addn < (speed_in_blocks+1)*1.5; ++addn) {
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( 0,  0,  1)); // back
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( -1, 0,  0)); // left
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( 1,  0,  0)); // right
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( 0,  0, -1)); // front
				}
			} else if (d == 2) {
				for(s16 addn = 0; addn < (speed_in_blocks+1)*1.5; ++addn) {
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( -1, 0,  1)); // back left
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( 1,  0,  1)); // left right
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( -1, 0, -1)); // right left
					list.push_back(floatToInt(playerspeeddir*addn, 1) + v3POS( 1,  0, -1)); // front right
				}
			}
		} else {
		/*
			Get the border/face dot coordinates of a "d-radiused"
			box
		*/
			list = FacePositionCache::getFacePositions(d);
		}


		for(auto li=list.begin(); li!=list.end(); ++li)
		{
			v3POS p = *li + center;

			/*
				Send throttling
				- Don't allow too many simultaneous transfers
				- EXCEPT when the blocks are very close

				Also, don't send blocks that are already flying.
			*/

			// Start with the usual maximum
			u16 max_simul_dynamic = max_simul_sends_usually;

			// If block is very close, allow full maximum
			if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
				max_simul_dynamic = max_simul_sends_setting;

			// Don't select too many blocks for sending
			if (num_blocks_selected + num_blocks_sending >= max_simul_dynamic) {
				//queue_is_full = true;
				goto queue_full_break;
			}

			/*
				Do not go over-limit
			*/
			if (blockpos_over_limit(p))
				continue;

			// If this is true, inexistent block will be made from scratch
			bool generate = d <= d_max_gen;

			{
				/*// Limit the generating area vertically to 2/3
				if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
					generate = false;*/

				/* maybe good idea (if not use block culling) but brokes far (25+) area generate by flooding emergequeue with no generate blocks
				// Limit the send area vertically to 1/2
				if(can_skip && abs(p.Y - center.Y) > full_d_max / 2)
					generate = false;
				*/
			}


			//infostream<<"d="<<d<<std::endl;
			/*
				Don't generate or send if not in sight
				FIXME This only works if the client uses a small enough
				FOV setting. The default of 72 degrees is fine.
			*/

			float camera_fov = ((fov+5)*M_PI/180) * 4./3.;
			if(can_skip && isBlockInSight(p, camera_pos, camera_dir, camera_fov, 10000*BS) == false)
			{
				continue;
			}

			/*
				Don't send already sent blocks
			*/
			unsigned int block_sent = 0;
			{
				auto lock = m_blocks_sent.lock_shared_rec();
				block_sent = m_blocks_sent.find(p) != m_blocks_sent.end() ? m_blocks_sent.get(p) : 0;
			}
			if(block_sent > 0 && (/* (block_overflow && d>1) || */ block_sent + (d <= 2 ? 1 : d*d*d) > m_uptime)) {
				continue;
			}

			/*
				Check if map has this block
			*/

			MapBlock *block;
			{
#if !ENABLE_THREADS
			auto lock = env->getServerMap().m_nothread_locker.lock_shared_rec();
#endif

			block = env->getMap().getBlockNoCreateNoEx(p);
			}

			bool surely_not_found_on_disk = false;
			bool block_is_invalid = false;
			if(block != NULL)
			{

				if (d > 3 && block->content_only == CONTENT_AIR) {
					continue;
				}

				if (block_sent > 0 && block_sent >= block->m_changed_timestamp) {
					continue;
				}

		if (occlusion_culling_enabled) {
			ScopeProfiler sp(g_profiler, "SMap: Occusion calls");
			//Occlusion culling
			auto cpn = p*MAP_BLOCKSIZE;

			// No occlusion culling when free_move is on and camera is
			// inside ground
			cpn += v3POS(MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2, MAP_BLOCKSIZE/2);

			float step = 1;
			float stepfac = 1.3;
			float startoff = 5;
			float endoff = -MAP_BLOCKSIZE;
			v3POS spn = cam_pos_nodes + v3POS(0,0,0);
			s16 bs2 = MAP_BLOCKSIZE/2 + 1;
			u32 needed_count = 1;
#if !ENABLE_THREADS
			auto lock = env->getServerMap().m_nothread_locker.lock_shared_rec();
#endif
			//VERY BAD COPYPASTE FROM clientmap.cpp!
			if( d >= 1 &&
				occlusion_culling_enabled &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(0,0,0),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(bs2,bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(bs2,bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(bs2,-bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(bs2,-bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(-bs2,bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(-bs2,bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(-bs2,-bs2,bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache) &&
				isOccluded(&env->getMap(), spn, cpn + v3POS(-bs2,-bs2,-bs2),
					step, stepfac, startoff, endoff, needed_count, nodemgr, occlude_cache)
			)
			{
				//infostream<<" occlusion player="<<cam_pos_nodes<<" d="<<d<<" block="<<cpn<<" total="<<blocks_occlusion_culled<<"/"<<num_blocks_selected<<std::endl;
				g_profiler->add("SMap: Occlusion skip", 1);
				blocks_occlusion_culled++;
				continue;
			}
		}

				// Reset usage timer, this block will be of use in the future.
				block->resetUsageTimer();

				if (block->getLightingExpired()) {
					//env->getServerMap().lighting_modified_blocks.set(p, nullptr);
					env->getServerMap().lighting_modified_add(p, d);
				}

				if (block->lighting_broken > 0 && (block_sent || d > 0))
					continue;

				// Block is valid if lighting is up-to-date and data exists
				if(block->isValid() == false)
				{
					block_is_invalid = true;
				}

				if(block->isGenerated() == false)
				{
					continue;
				}

				/*
					If block is not close, don't send it unless it is near
					ground level.

					Block is near ground level if night-time mesh
					differs from day-time mesh.
				*/
/*
				if(d >= 4)
				{
					if(block->getDayNightDiff() == false)
						continue;
				}
*/
			}

			/*
				If block has been marked to not exist on disk (dummy)
				and generating new ones is not wanted, skip block.
			*/
			if(generate == false && surely_not_found_on_disk == true)
			{
				// get next one.
				continue;
			}

			/*
				Add inexistent block to emerge queue.
			*/
			if(block == NULL || surely_not_found_on_disk || block_is_invalid)
			{
				//infostream<<"start gen d="<<d<<" p="<<p<<" notfound="<<surely_not_found_on_disk<<" invalid="<< block_is_invalid<<" block="<<block<<" generate="<<generate<<std::endl;

				if (emerge->enqueueBlockEmerge(peer_id, p, generate)) {
					if (nearest_emerged_d == -1)
						nearest_emerged_d = d;
				} else {
					if (nearest_emergefull_d == -1)
						nearest_emergefull_d = d;
					goto queue_full_break;
				}

				// get next one.
				continue;
			}

			if(nearest_sent_d == -1)
				nearest_sent_d = d;

			/*
				Add block to send queue
			*/

			PrioritySortedBlockTransfer q((float)d, p, peer_id);

			dest.push_back(q);

			num_blocks_selected += 1;
		}
	}
queue_full_break:

	//infostream<<"Stopped at "<<d<<" d_start="<<d_start<< " d_max="<<d_max<<" nearest_emerged_d="<<nearest_emerged_d<<" nearest_emergefull_d="<<nearest_emergefull_d<< " new_nearest_unsent_d="<<new_nearest_unsent_d<< " sel="<<num_blocks_selected<< "+"<<num_blocks_sending << " culled=" << blocks_occlusion_culled <<" cEN="<<occlusion_culling_enabled<<std::endl;
	num_blocks_selected += num_blocks_sending;
	if(!num_blocks_selected && d_start <= d) {
		//new_nearest_unsent_d = 0;
		m_nothing_to_send_pause_timer = 1.0;
	}
		

	// If nothing was found for sending and nothing was queued for
	// emerging, continue next time browsing from here
	if(nearest_emerged_d != -1){
		new_nearest_unsent_d = nearest_emerged_d;
	} else if(nearest_emergefull_d != -1){
		new_nearest_unsent_d = nearest_emergefull_d;
	} else {
		if(d > full_d_max){
			new_nearest_unsent_d = 0;
			m_nothing_to_send_pause_timer = 1.0;
		} else {
			if(nearest_sent_d != -1)
				new_nearest_unsent_d = nearest_sent_d;
			else
				new_nearest_unsent_d = d;
		}
	}

	if(new_nearest_unsent_d != -1)
		m_nearest_unsent_d = new_nearest_unsent_d;
	return num_blocks_selected - num_blocks_sending;
}
Пример #25
0
void RigidBody2D::_direct_state_changed(Object *p_state) {

	//eh.. f**k
#ifdef DEBUG_ENABLED

	state=p_state->cast_to<Physics2DDirectBodyState>();
#else
	state=(Physics2DDirectBodyState*)p_state; //trust it
#endif

	if (contact_monitor) {

		//untag all
		int rc=0;
		for( Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {

			for(int i=0;i<E->get().shapes.size();i++) {

				E->get().shapes[i].tagged=false;
				rc++;
			}
		}

		_RigidBody2DInOut *toadd=(_RigidBody2DInOut*)alloca(state->get_contact_count()*sizeof(_RigidBody2DInOut));
		int toadd_count=0;//state->get_contact_count();
		RigidBody2D_RemoveAction *toremove=(RigidBody2D_RemoveAction*)alloca(rc*sizeof(RigidBody2D_RemoveAction));
		int toremove_count=0;

		//put the ones to add

		for(int i=0;i<state->get_contact_count();i++) {

			ObjectID obj = state->get_contact_collider_id(i);
			int local_shape = state->get_contact_local_shape(i);
			int shape = state->get_contact_collider_shape(i);
			toadd[i].local_shape=local_shape;
			toadd[i].id=obj;
			toadd[i].shape=shape;

//			bool found=false;

			Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.find(obj);
			if (!E) {
				toadd_count++;
				continue;
			}

			ShapePair sp( shape,local_shape );
			int idx = E->get().shapes.find(sp);
			if (idx==-1) {

				toadd_count++;
				continue;
			}

			E->get().shapes[idx].tagged=true;
		}

		//put the ones to remove

		for( Map<ObjectID,BodyState>::Element *E=contact_monitor->body_map.front();E;E=E->next()) {

			for(int i=0;i<E->get().shapes.size();i++) {

				if (!E->get().shapes[i].tagged) {

					toremove[toremove_count].body_id=E->key();
					toremove[toremove_count].pair=E->get().shapes[i];
					toremove_count++;
				}
			}
		}


		//process remotions

		for(int i=0;i<toremove_count;i++) {

			_body_inout(0,toremove[i].body_id,toremove[i].pair.body_shape,toremove[i].pair.local_shape);
		}

		//process aditions

		for(int i=0;i<toadd_count;i++) {

			_body_inout(1,toadd[i].id,toadd[i].shape,toadd[i].local_shape);
		}

	}

	set_block_transform_notify(true); // don't want notify (would feedback loop)
	if (mode!=MODE_KINEMATIC)
		set_global_transform(state->get_transform());
	linear_velocity=state->get_linear_velocity();
	angular_velocity=state->get_angular_velocity();
	active=!state->is_sleeping();
	if (get_script_instance())
		get_script_instance()->call("_integrate_forces",state);
	set_block_transform_notify(false); // want it back

	state=NULL;
}
Пример #26
0
QList<Polygon> Polygon::convexPartition() const { // precondition: ccw; see mnbayazit.com/406/bayazit for details about how this works
    QList<Polygon> list;
    qreal d, dist1, dist2;
    QPointF ip, ip1, ip2; // intersection points
    int ind1, ind2;
    Polygon poly1, poly2;

    for(int i = 0; i < size(); ++i) {
        if(reflex(i)) {
            dist1 = dist2 = std::numeric_limits<qreal>::max();
            for(int j = 0; j < size(); ++j) {
                if(left(at(i - 1), at(i), at(j)) && rightOn(at(i - 1), at(i), at(j - 1))) { // if ray (i-1)->(i) intersects with edge (j, j-1)
                    QLineF(at(i - 1), at(i)).intersect(QLineF(at(j), at(j - 1)), &ip);
                    if(right(at(i + 1), at(i), ip)) { // intersection point isn't caused by backwards ray
                        d = sqdist(at(i), ip);
                        if(d < dist1) { // take the closest intersection so we know it isn't blocked by another edge
                            dist1 = d;
                            ind1 = j;
                            ip1 = ip;
                        }
                    }
                }
                if(left(at(i + 1), at(i), at(j + 1)) && rightOn(at(i + 1), at(i), at(j))) { // if ray (i+1)->(i) intersects with edge (j+1, j)
                    QLineF(at(i + 1), at(i)).intersect(QLineF(at(j), at(j + 1)), &ip);
                    if(left(at(i - 1), at(i), ip)) {
                        d = sqdist(at(i), ip);
                        if(d < dist2) {
                            dist2 = d;
                            ind2 = j;
                            ip2 = ip;
                        }
                    }
                }
            }
            if(ind1 == (ind2 + 1) % size()) { // no vertices in range
                QPointF sp((ip1 + ip2) / 2);
                poly1 = copy(i, ind2);
                poly1.append(sp);
                poly2 = copy(ind1, i);
                poly2.append(sp);
            } else {
                double highestScore = 0, bestIndex = ind1, score;
                while(ind2 < ind1) ind2 += size();
                for(int j = ind1; j <= ind2; ++j) {
                    if(canSee(i, j)) {
                        score = 1 / (sqdist(at(i), at(j)) + 1);
                        if(reflex(j)) {
                            if(rightOn(at(j - 1), at(j), at(i)) && leftOn(at(j + 1), at(j), at(i))) {
                                score += 3;
                            } else {
                                score += 2;
                            }
                        } else {
                            score += 1;
                        }
                        if(score > highestScore) {
                            bestIndex = j;
                            highestScore = score;
                        }
                    }
                }
                poly1 = copy(i, bestIndex);
                poly2 = copy(bestIndex, i);
            }
            list += poly1.convexPartition();
            list += poly2.convexPartition();
            return list;
        }
    }
    // polygon is already convex
    if(size() > b2_maxPolygonVertices) {
        poly1 = copy(0, size() / 2);
        poly2 = copy(size() / 2, 0);
        list += poly1.convexPartition();
        list += poly2.convexPartition();
    } else list.append(*this);
    return list;
}
Пример #27
0
void Language_C::_write_parse_func( std::ostream &os ) {
    StreamSepMaker<std::ostream> on( os );
    int nb_spaces = 5;
    String sp( nb_spaces, ' ' );
    on.beg = sp.c_str();

    // parse
    os << "int parse" << f_suf << "( " << cp->struct_name << " *sipe_data, SIPE_CHARP data, SIPE_CHARP end ) {\n";
    if ( nb_marks )
        on << "SIPE_CHARP beg_data = data;\n";
    on << "if ( sipe_data->_inp_cont )";
    on << "    goto *sipe_data->_inp_cont;";
    on << "";
    on << "#define INCR( N ) if ( ++data >= end ) goto p_##N; c_##N:";
    on << "";

    // blocks
    for( int i = 0; i < block_seq.size(); ++i ) {
        Block *b = block_seq[ i ];
        if ( not b->write )
            continue;

        //
        if ( b->label >= 0 ) {
            os << "l_" << b->label << ":";
            on.first_beg = on.beg + std::min( nb_spaces, 3 + nb_digits( b->label ) );
        }

        //
        if ( b->state ) {
            // action
            if ( b->state->action )
                b->state->action->write_code( on, this );

            // end ?
            if ( b->state->end ) {
                on << "sipe_data->_inp_cont = &&l_" << b->label << ";";
                on << "return " << b->state->end << ";";
            }

            //
            if ( b->state->set_mark ) {
                on << "sipe_data->_mark[ " << marks[ b->state ] << " ] = data;";
                on << "sipe_data->_mark_data[ " << marks[ b->state ] << " ].clear();";
            }

            //
            if ( b->state->use_mark ) {
                int nm = marks[ b->state->use_mark ];
                on << "if ( sipe_data->_mark[ " << nm << " ] ) {";
                on << "    data = sipe_data->_mark[ " << nm << " ];";
                on << "} else {";
                // on << "    std::cout << '-' << sipe_data->_mark_data[ " << nm << " ] << '-' << std::endl;";
                on << "    sipe_data->_inp_cont = &&cnt_mark_" << b << ";";
                on << "    SIPE_CHARP beg = (SIPE_CHARP)sipe_data->_mark_data[ " << nm << " ].data();";
                on << "    int res = parse( sipe_data, beg, beg + sipe_data->_mark_data[ " << nm << " ].size() );";
                on << "    if ( res )";
                on << "        return res;";
                on << "    data = beg_data;";
                on << "    goto *sipe_data->_inp_cont;";
                on << "}";
                os << "cnt_mark_" << b << ":\n";
            }

            //
            if ( b->state->rem_mark ) {
            }

            //
            if ( b->state->incc ) {
                on << "INCR( " << cnt.size() << " )";

                Cnt c;
                c.block = b;
                c.label = b->label;
                cnt << c;
            }
        }

        //
        if ( b->ko ) {
            if ( b->t_ok ) { // if ( cond ) goto ok;
                String cond = b->cond.ok_cpp( "*data", &b->not_in );
                on << "if ( " << cond << " ) goto l_" << b->ok->label << ";";
            } else { // if ( not cond ) goto ko;
                String cond = b->cond.ko_cpp( "*data", &b->not_in );
                on << "if ( " << cond << " ) goto l_" << b->ko->label << ";";
            }
        }

        //
        if ( b->write_goto )
            on << "goto l_" << b->write_goto->label << ";";
    }

    // cnt
    for( int i = 0; i < cnt.size(); ++i ) {
        os << "p_" << i << ":";
        on.first_beg = on.beg + std::min( nb_spaces, 3 + nb_digits( i ) );
        if ( const State *m = cnt[ i ].block->mark ) {
            // on << "std::cout << *sipe_data->_mark[ " << marks[ m ] << " ] << std::endl;";
            on << "sipe_data->_mark_data[ " << marks[ m ] << " ].append( sipe_data->_mark[ " << marks[ m ] << " ] ? sipe_data->_mark[ " << marks[ m ] << " ] : beg_data, data );";
            on << "sipe_data->_mark[ " << marks[ m ] << " ] = 0;";
        }
        on << "sipe_data->_inp_cont = &&c_" << i << "; return 0;";
    }
    os << "}\n";
}
Пример #28
0
TEST(RecordIOTest, Randomized) {
  SCOPED_TRACE(to<std::string>("Random seed is ", FLAGS_random_seed));
  std::mt19937 rnd(FLAGS_random_seed);

  size_t recordCount =
    std::uniform_int_distribution<uint32_t>(30, 300)(rnd);

  std::uniform_int_distribution<uint32_t> recordSizeDist(1, 3 << 16);
  std::uniform_int_distribution<uint32_t> charDist(0, 255);
  std::uniform_int_distribution<uint32_t> junkDist(0, 1 << 20);
  // corrupt 1/5 of all records
  std::uniform_int_distribution<uint32_t> corruptDist(0, 4);

  std::vector<std::pair<fbstring, off_t>> records;
  std::vector<off_t> corruptPositions;
  records.reserve(recordCount);
  TemporaryFile file;

  fbstring record;
  // Recreate the writer multiple times so we test that we create a
  // continuous stream
  for (size_t i = 0; i < 3; ++i) {
    RecordIOWriter writer(File(file.fd()));
    for (size_t j = 0; j < recordCount; ++j) {
      off_t beginPos = writer.filePos();
      record.clear();
      size_t recordSize = recordSizeDist(rnd);
      record.reserve(recordSize);
      for (size_t k = 0; k < recordSize; ++k) {
        record.push_back(charDist(rnd));
      }
      writer.write(iobufs({record}));

      bool corrupt = (corruptDist(rnd) == 0);
      if (corrupt) {
        // Corrupt one random byte in the record (including header)
        std::uniform_int_distribution<uint32_t> corruptByteDist(
            0, recordSize + recordio_helpers::headerSize() - 1);
        off_t corruptRel = corruptByteDist(rnd);
        VLOG(1) << "n=" << records.size() << " bpos=" << beginPos
                << " rsize=" << record.size()
                << " corrupt rel=" << corruptRel
                << " abs=" << beginPos + corruptRel;
        corruptPositions.push_back(beginPos + corruptRel);
      } else {
        VLOG(2) << "n=" << records.size() << " bpos=" << beginPos
                << " rsize=" << record.size()
                << " good";
        records.emplace_back(std::move(record), beginPos);
      }
    }
    VLOG(1) << "n=" << records.size() << " close abs=" << writer.filePos();
  }

  for (auto& pos : corruptPositions) {
    corrupt(file.fd(), pos);
  }

  {
    size_t i = 0;
    RecordIOReader reader(File(file.fd()));
    for (auto& r : reader) {
      SCOPED_TRACE(i);
      ASSERT_LT(i, records.size());
      EXPECT_EQ(records[i].first, sp(r.first));
      EXPECT_EQ(records[i].second, r.second);
      ++i;
    }
    EXPECT_EQ(records.size(), i);
  }
}
Пример #29
0
void Client::step(float dtime)
{
	DSTACK(__FUNCTION_NAME);

	// Limit a bit
	if(dtime > 2.0)
		dtime = 2.0;

	if(m_ignore_damage_timer > dtime)
		m_ignore_damage_timer -= dtime;
	else
		m_ignore_damage_timer = 0.0;

	m_animation_time += dtime;
	if(m_animation_time > 60.0)
		m_animation_time -= 60.0;

	m_time_of_day_update_timer += dtime;

	ReceiveAll();

	/*
		Packet counter
	*/
	{
		float &counter = m_packetcounter_timer;
		counter -= dtime;
		if(counter <= 0.0)
		{
			counter = 20.0;

			infostream << "Client packetcounter (" << m_packetcounter_timer
					<< "):"<<std::endl;
			m_packetcounter.print(infostream);
			m_packetcounter.clear();
		}
	}

	// UGLY hack to fix 2 second startup delay caused by non existent
	// server client startup synchronization in local server or singleplayer mode
	static bool initial_step = true;
	if (initial_step) {
		initial_step = false;
	}
	else if(m_state == LC_Created) {
		float &counter = m_connection_reinit_timer;
		counter -= dtime;
		if(counter <= 0.0) {
			counter = 2.0;

			Player *myplayer = m_env.getLocalPlayer();
			FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment.");

			// Send TOSERVER_INIT_LEGACY
			// [0] u16 TOSERVER_INIT_LEGACY
			// [2] u8 SER_FMT_VER_HIGHEST_READ
			// [3] u8[20] player_name
			// [23] u8[28] password (new in some version)
			// [51] u16 minimum supported network protocol version (added sometime)
			// [53] u16 maximum supported network protocol version (added later than the previous one)

			char pName[PLAYERNAME_SIZE];
			char pPassword[PASSWORD_SIZE];
			memset(pName, 0, PLAYERNAME_SIZE * sizeof(char));
			memset(pPassword, 0, PASSWORD_SIZE * sizeof(char));

			std::string hashed_password = translatePassword(myplayer->getName(), m_password);
			snprintf(pName, PLAYERNAME_SIZE, "%s", myplayer->getName());
			snprintf(pPassword, PASSWORD_SIZE, "%s", hashed_password.c_str());

			sendLegacyInit(pName, pPassword);
			if (LATEST_PROTOCOL_VERSION >= 25)
				sendInit(myplayer->getName());
		}

		// Not connected, return
		return;
	}

	/*
		Do stuff if connected
	*/

	/*
		Run Map's timers and unload unused data
	*/
	const float map_timer_and_unload_dtime = 5.25;
	if(m_map_timer_and_unload_interval.step(dtime, map_timer_and_unload_dtime)) {
		ScopeProfiler sp(g_profiler, "Client: map timer and unload");
		std::vector<v3s16> deleted_blocks;
		m_env.getMap().timerUpdate(map_timer_and_unload_dtime,
				g_settings->getFloat("client_unload_unused_data_timeout"),
				&deleted_blocks);

		/*
			Send info to server
			NOTE: This loop is intentionally iterated the way it is.
		*/

		std::vector<v3s16>::iterator i = deleted_blocks.begin();
		std::vector<v3s16> sendlist;
		for(;;) {
			if(sendlist.size() == 255 || i == deleted_blocks.end()) {
				if(sendlist.empty())
					break;
				/*
					[0] u16 command
					[2] u8 count
					[3] v3s16 pos_0
					[3+6] v3s16 pos_1
					...
				*/

				sendDeletedBlocks(sendlist);

				if(i == deleted_blocks.end())
					break;

				sendlist.clear();
			}

			sendlist.push_back(*i);
			++i;
		}
	}

	/*
		Handle environment
	*/
	// Control local player (0ms)
	LocalPlayer *player = m_env.getLocalPlayer();
	assert(player != NULL);
	player->applyControl(dtime, &m_env);

	// Step environment
	m_env.step(dtime);

	/*
		Get events
	*/
	for(;;) {
		ClientEnvEvent event = m_env.getClientEvent();
		if(event.type == CEE_NONE) {
			break;
		}
		else if(event.type == CEE_PLAYER_DAMAGE) {
			if(m_ignore_damage_timer <= 0) {
				u8 damage = event.player_damage.amount;

				if(event.player_damage.send_to_server)
					sendDamage(damage);

				// Add to ClientEvent queue
				ClientEvent event;
				event.type = CE_PLAYER_DAMAGE;
				event.player_damage.amount = damage;
				m_client_event_queue.push(event);
			}
		}
		else if(event.type == CEE_PLAYER_BREATH) {
				u16 breath = event.player_breath.amount;
				sendBreath(breath);
		}
	}

	/*
		Print some info
	*/
	float &counter = m_avg_rtt_timer;
	counter += dtime;
	if(counter >= 10) {
		counter = 0.0;
		// connectedAndInitialized() is true, peer exists.
		float avg_rtt = getRTT();
		infostream << "Client: avg_rtt=" << avg_rtt << std::endl;
	}

	/*
		Send player position to server
	*/
	{
		float &counter = m_playerpos_send_timer;
		counter += dtime;
		if((m_state == LC_Ready) && (counter >= m_recommended_send_interval))
		{
			counter = 0.0;
			sendPlayerPos();
		}
	}

	/*
		Replace updated meshes
	*/
	{
		int num_processed_meshes = 0;
		while (!m_mesh_update_thread.m_queue_out.empty())
		{
			num_processed_meshes++;

			MinimapMapblock *minimap_mapblock = NULL;
			bool do_mapper_update = true;

			MeshUpdateResult r = m_mesh_update_thread.m_queue_out.pop_frontNoEx();
			MapBlock *block = m_env.getMap().getBlockNoCreateNoEx(r.p);
			if (block) {
				// Delete the old mesh
				if (block->mesh != NULL) {
					delete block->mesh;
					block->mesh = NULL;
				}

				if (r.mesh) {
					minimap_mapblock = r.mesh->moveMinimapMapblock();
					if (minimap_mapblock == NULL)
						do_mapper_update = false;
				}

				if (r.mesh && r.mesh->getMesh()->getMeshBufferCount() == 0) {
					delete r.mesh;
				} else {
					// Replace with the new mesh
					block->mesh = r.mesh;
				}
			} else {
				delete r.mesh;
			}

			if (do_mapper_update)
				m_mapper->addBlock(r.p, minimap_mapblock);

			if (r.ack_block_to_server) {
				/*
					Acknowledge block
					[0] u8 count
					[1] v3s16 pos_0
				*/
				sendGotBlocks(r.p);
			}
		}

		if (num_processed_meshes > 0)
			g_profiler->graphAdd("num_processed_meshes", num_processed_meshes);
	}

	/*
		Load fetched media
	*/
	if (m_media_downloader && m_media_downloader->isStarted()) {
		m_media_downloader->step(this);
		if (m_media_downloader->isDone()) {
			received_media();
			delete m_media_downloader;
			m_media_downloader = NULL;
		}
	}

	/*
		If the server didn't update the inventory in a while, revert
		the local inventory (so the player notices the lag problem
		and knows something is wrong).
	*/
	if(m_inventory_from_server)
	{
		float interval = 10.0;
		float count_before = floor(m_inventory_from_server_age / interval);

		m_inventory_from_server_age += dtime;

		float count_after = floor(m_inventory_from_server_age / interval);

		if(count_after != count_before)
		{
			// Do this every <interval> seconds after TOCLIENT_INVENTORY
			// Reset the locally changed inventory to the authoritative inventory
			Player *player = m_env.getLocalPlayer();
			player->inventory = *m_inventory_from_server;
			m_inventory_updated = true;
		}
	}

	/*
		Update positions of sounds attached to objects
	*/
	{
		for(std::map<int, u16>::iterator
				i = m_sounds_to_objects.begin();
				i != m_sounds_to_objects.end(); i++)
		{
			int client_id = i->first;
			u16 object_id = i->second;
			ClientActiveObject *cao = m_env.getActiveObject(object_id);
			if(!cao)
				continue;
			v3f pos = cao->getPosition();
			m_sound->updateSoundPosition(client_id, pos);
		}
	}

	/*
		Handle removed remotely initiated sounds
	*/
	m_removed_sounds_check_timer += dtime;
	if(m_removed_sounds_check_timer >= 2.32) {
		m_removed_sounds_check_timer = 0;
		// Find removed sounds and clear references to them
		std::vector<s32> removed_server_ids;
		for(std::map<s32, int>::iterator
				i = m_sounds_server_to_client.begin();
				i != m_sounds_server_to_client.end();) {
			s32 server_id = i->first;
			int client_id = i->second;
			i++;
			if(!m_sound->soundExists(client_id)) {
				m_sounds_server_to_client.erase(server_id);
				m_sounds_client_to_server.erase(client_id);
				m_sounds_to_objects.erase(client_id);
				removed_server_ids.push_back(server_id);
			}
		}

		// Sync to server
		if(!removed_server_ids.empty()) {
			sendRemovedSounds(removed_server_ids);
		}
	}

	// Write server map
	if (m_localdb && m_localdb_save_interval.step(dtime,
			m_cache_save_interval)) {
		m_localdb->endSave();
		m_localdb->beginSave();
	}
}
Пример #30
0
inline address* frame::I0_addr() const  { return (address*) &sp()[ I0->sp_offset_in_saved_window()]; }