// ObjectDir.cpp: implementation of the CObjectDir class. // ////////////////////////////////////////////////////////////////////// #include "clientapi.h" #include "listnode.h" #include "clientdepotuser.h" #include "clientdiruser.h" #include "clientfileuser.h" #include "filehead.h" #include "changesorter.h" #include "filelogcache.h" #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; if (level == 1) { StrBuf dir = dui.dirs.SPop(); if (dir.Length() > 0) //as long as "dir" contains something: { CObjectDir* newdir = GetClassPtr( (CObjectDir *)NULL ); //create a new ObjectDir newdir->pev->classname = MAKE_STRING("object_dir"); //set its classname newdir->pev->origin = pev->origin; //set its origin as this depot's origin newdir->target = target - Vector(0,0,100); //with a target directly under its target newdir->target.x -= xcoord*70; //and xcoord*70 steps to the right newdir->pev->origin = newdir->target; //instant placing newdir->path = dir; //set its path so it knows what it is newdir->parent = this; //set its parent newdir->Spawn(); //tell it to spawn in the world newdir->pev->nextthink = gpGlobals->time; //tell it to start thinking now. dirs.Append(newdir); //add this dir to this depot's list of known children. xcoord++; //make the next dir one space over. } StrBuf file = fui.files.SPop(); StrBuf ftype = fui.ftypes.SPop(); if (file.Length() > 0) { CObjectFile* 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->pev->origin = pev->origin; newfile->target = target - Vector(0,0,100); newfile->target.y -= ycoord*70; newfile->pev->origin = newfile->target; newfile->path = file; newfile->parent = this; newfile->Spawn(); newfile->pev->nextthink = gpGlobals->time; ycoord++; } if (file.Length() || dir.Length()) pev->nextthink = gpGlobals->time + 0.1; else if (pev->origin == target) pev->nextthink = gpGlobals->time + 1.0; } } 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; 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); dui = ClientDirUser(); dui.changeflag = FALSE; dui.maxresults = MAXRESULTS; 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", &dui ); xcoord = 1; fui = ClientFileUser(); fui.logflag = FALSE; fui.maxresults = MAXRESULTS; 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()); } ycoord = 1; pl->m_flNextP4Time = gpGlobals->time + 1.0; 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 | |
---|---|---|---|---|---|
#1 | 7292 | Andrew McDonald | initial submittal | ||
//guest/sam_stafford/p4hl/src/dlls/ObjectDir.cpp | |||||
#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. |