ObjectDir.cpp #4

  • //
  • guest/
  • sam_stafford/
  • p4hl/
  • src/
  • dlls/
  • ObjectDir.cpp
  • View
  • Commits
  • Open Download .zip Download (6 KB)
// ObjectDir.cpp: implementation of the CObjectDir class.
//
//////////////////////////////////////////////////////////////////////

#include "p4objects.h"

LINK_ENTITY_TO_CLASS( object_dir, CObjectDir);

void CObjectDir::Spawn()
{
	Precache( );
			
	SET_MODEL( ENT(pev), "models/dir/w_dir.mdl" );

	UTIL_SetOrigin( pev, pev->origin );
	target = (Vector)pev->origin;  //by default, we're already where we want to be.

	UTIL_SetSize( pev, Vector(-20, -15, 38), Vector( 30, 4, 78) );  //collision box!

	level = 0;

	pev->movetype = MOVETYPE_FLY;
//			pev->sequence = LookupActivity (ACT_IDLE);
//			pev->frame = 0;
//			pev->framerate = 1;
	pev->solid = SOLID_BBOX; 

	SetThink( Think );
	SetTouch( Touch );

	pev->nextthink = gpGlobals->time + 0.5;
}

void CObjectDir::Precache()
{
	PRECACHE_MODEL("models/dir/w_dir.mdl");
}

void CObjectDir :: Think( void )
{
	if (!IsInWorld())
	{
		parent -> disown ( this );
		UTIL_Remove( this );
		return;
	}

	if (UTIL_VecUpdate( &(pev->origin), target )) {
		pev->nextthink = gpGlobals->time + 0.05;
		UTIL_SetSize( pev, Vector(-20, -15, 38), Vector( 30, 4, 78) );  //collision box!
	}
	else pev->nextthink = gpGlobals->time + 0.5;
}

void CObjectDir :: Touch( CBaseEntity* Thing )
{ 
	CBasePlayer *pl;
	CBaseEntity *be = CBaseEntity::Instance(Thing->pev->owner);

	if (Thing->IsPlayer()) pl = (CBasePlayer*) Thing;
	else if (be->IsPlayer()) pl = (CBasePlayer*) be;
	else return;
	if (pl->m_flNextP4Time > gpGlobals->time) return;
	if (Thing->IsExpand()) {
		Expand( pl );
		pl->m_flNextP4Time = gpGlobals->time + 0.5;
		return;
	}

	if (Thing->IsLong()) {
		Long( pl );
		pl->m_flNextP4Time = gpGlobals->time + 0.5;
		return;
	}
	pl->m_flNextP4Time = gpGlobals->time + 0.2;
	UTIL_PrintHud(pl, path.Text());
}

void CObjectDir :: Long( CBasePlayer* pl )
{
	ClientDirUser ui;
	ui.changeflag = TRUE;
	ClientApi client;
	if (P4PORT.Length()) client.SetPort(P4PORT.Text());
	Error e;
	StrBuf msg = StrBuf();

	client.Init( &e );
	if (e.GetSeverity()) {
		e.Fmt(&msg);
		UTIL_FatalHud(pl, msg.Text());
		pl->m_flNextP4Time = gpGlobals->time + 20.0; //20 second delay on connect error
		return;
	}
	
	char* args[3];
	StrBuf changepath = StrBuf();
	changepath.Append(path.Text());
	changepath.Append("/...");
	args[0] = "-m";
	args[1] = "10";
	args[2] = changepath.Text();

	client.SetArgv(3, args);
	client.Run( "changes", &ui );

	client.Final( &e );
	if (e.GetSeverity()) {
		e.Fmt(&msg);
		UTIL_WarningHud(pl, msg.Text());
	}

	UTIL_PrintHud( pl, ui.changes.Text());
}

void CObjectDir :: Expand ( CBasePlayer* pl )
{
	if (level == 1) return;

	short sofar = 0;

	StrBuf hudmsg = StrBuf();
	hudmsg.Append("Expanding directory ");
	hudmsg.Append(path.Text());
	hudmsg.Append("...");
	UTIL_PrintHud( pl, hudmsg.Text());
	killKids(this);

	newLevel(1);
	parent->killKids(this);

	ClientDirUser ui;
	ui.changeflag = FALSE;
	ClientApi client;
	if (P4PORT.Length()) client.SetPort(P4PORT.Text());
	Error e;

	client.Init( &e );
	if (e.GetSeverity()) 
	{
		StrBuf msg = StrBuf();
		e.Fmt(&msg);
		UTIL_FatalHud(pl, msg.Text());
		pl->m_flNextP4Time = gpGlobals->time + 20.0;
		return;
	}

	StrBuf dirpath = StrBuf();
	dirpath.Append(path.Text());
	dirpath.Append("/*");

	char* args[1];
	args[0] = dirpath.Text();
	
	client.SetArgv(1, args);
	client.Run( "dirs", &ui );

	StrBuf dir = ui.dirs.SPop();
	float xcoord = 1.0;
	CObjectDir *newdir;

	while (dir.Length() > 0)
	{
		if (sofar > MAXRESULTS) break;
		newdir = GetClassPtr( (CObjectDir *)NULL );
		dirs.Append(newdir);
		newdir->pev->classname = MAKE_STRING("object_dir");
		newdir->Spawn();
		newdir->pev->origin = pev->origin;
		newdir->target = target - Vector(0,0,100);
		newdir->target.x -= xcoord*70;
		newdir->path = dir;
		newdir->parent = this;
		newdir->pev->nextthink = gpGlobals->time;
		dir = ui.dirs.SPop();
		xcoord++;
		sofar++;
	}

	if (sofar > MAXRESULTS) {
		UTIL_WarningHud(pl, "Output truncated!");
		return;
	}

	ClientFileUser fui;
	fui.logflag = FALSE;
	
	args[0] = dirpath.Text();
	client.SetArgv(1, args);
	client.Run( "files", &fui );

	client.Final( &e );
			if (e.GetSeverity()) {
				StrBuf warn = StrBuf();
				e.Fmt(&warn);
				UTIL_WarningHud(pl, warn.Text());
			}

	StrBuf file = fui.files.SPop();
	StrBuf ftype = fui.ftypes.SPop();
	float ycoord = 1.0;
	CObjectFile *newfile;

	while (file.Length() > 0)
	{
		if (sofar > MAXRESULTS) break;
		newfile = GetClassPtr( (CObjectFile *)NULL );
		files.Append(newfile);
		newfile->pev->classname = MAKE_STRING("object_file");
		switch (*(ftype.Text()))
		{
		default:
		case 't':
			newfile->ftype = FTYPE_TEX;
			break;
		case 'b':
			newfile->ftype = FTYPE_BIN;
			break;
		case 'a':
			newfile->ftype = FTYPE_APP;
			break;
		case 's':
			newfile->ftype = FTYPE_SYM;
			break;
		}		
		newfile->Spawn();
		newfile->pev->origin = pev->origin;
		newfile->pev->angles = Vector(-1,-1,-1);
		newfile->target = target - Vector(0,0,100);
		newfile->target.y -= ycoord*60;
		newfile->path = file;
		newfile->parent = this;
		newfile->pev->nextthink = gpGlobals->time;
		file = fui.files.SPop();
		ftype = fui.ftypes.SPop();
		ycoord++;
		sofar++;
	}
	if (sofar > MAXRESULTS) UTIL_WarningHud(pl, "Output truncated!\n");

	return;
}

void CObjectDir :: newLevel( short newlev )
{
	if (newlev > 0)
	{
		Vector parvec = parent->targvec();
		target.x = parvec.x;
		target.y = parvec.y;
	}
	target.z += (newlev - level)*100;
	level = newlev;
	parent->newLevel(level+1);
}

void CObjectDir :: disown ( CBaseEntity *Target ) //this does the OPPOSITE of killKids!!!
{
	dirs.EKill(Target);
	files.EKill(Target);
	return;
}

void CObjectDir :: killKids( CBaseEntity *Caller )
{
	bool callerFlag = false;
	CBaseEntity* kid = dirs.EPop();
	while (kid != NULL)
	{
		if (kid == Caller) 
		{
			callerFlag = TRUE;
			kid = dirs.EPop();
			continue;
		}
		kid -> killKids(this);
		UTIL_Remove(kid);
		kid = dirs.EPop();
	}
	if (callerFlag) dirs.Append(Caller);
	
	callerFlag = false;
	kid = files.EPop();
	while (kid != NULL)
	{
		if (kid == Caller)
		{
			callerFlag = TRUE;
			kid = files.EPop();
			continue;
		}
		kid -> killKids(this);
		UTIL_Remove(kid);
		kid = files.EPop();
	}
	if (callerFlag) files.Append(Caller);
}

CObjectDir::CObjectDir()
{

}

//CObjectDir::~CObjectDir()
//{

//}
# Change User Description Committed
#6 1689 Sam Stafford Integrate 02.1 API and code cleanup to P4HL.
 Lots of work.  Phew.
#5 1024 Sam Stafford Reworked entity creation in most cases - it's done one at a time now rather
than all at once.  This allows us to have more entities than the previous limit
of 130, and also looks a little nicer.

Folders and files now pop into existence instantly instead of sliding - makes
navigation easier.  Depots still slide because there typically aren't as many
of them (okay, I might eventually make them pop too, but I'm tired now).
Revisions slide because it looks really cool - like a waterfall pouring out of
the file.

The upper limit to entities is now due to the "visible entity packet" thing,
which I'm certain I have no control over - it's as high as it can possibly be
right now.
#4 1007 Sam Stafford A stab at making P4HL a bit more accessible to Perforce novices.
During the Precache() phase of the P4HL objects, a "p4 info" is
executed.  If this returns any errors, odds are there's no server
there (I can't think of what other error "p4 info" would return).
If this happens, use "public.perforce.com:1666" as the new port
value for all future Perforce transactions during this session,
and send a message to the console explaining this.
#3 1005 Sam Stafford Whoops, I lied - NOW text is the default in all cases.
#2 1003 Sam Stafford Different file types now displayed differently.
 Also flipped
around the file model so that its text doesn't look backwards
any more.
#1 937 Sam Stafford Renaming my guest directory to the more conventional
sam_stafford.
//guest/samwise/p4hl/src/dlls/ObjectDir.cpp
#1 936 Sam Stafford Adding P4HL to the public depot.
 See relnotes.txt for
installation instructions; all relevant files are under
p4hl/dist.

Source code is under p4hl/src in the form of a VC++ project.