Added wrapper states to actors. Wrapping an actor inside a frame when building a screen is now unnecessary.
This commit is contained in:
@@ -4,6 +4,13 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes
|
||||
from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt.
|
||||
________________________________________________________________________________
|
||||
|
||||
2015/01/30
|
||||
----------
|
||||
* [Actor] Wrapper states added. This makes wrapping an Actor inside an
|
||||
ActorFrame for any reason unnecessary, and makes it possible to do things
|
||||
that were only possible by wrapping an Actor in an ActorFrame to Actors
|
||||
that you couldn't put inside a frame before. [kyzentun]
|
||||
|
||||
2015/01/20
|
||||
----------
|
||||
* [ScreenSelect] ChoiceNames can be a lua command that is evaluated to get a
|
||||
|
||||
@@ -257,6 +257,7 @@
|
||||
</GlobalFunctions>
|
||||
<Classes>
|
||||
<Class name='Actor'>
|
||||
<Function name='AddWrapperState'/>
|
||||
<Function name='Center'/>
|
||||
<Function name='CenterX'/>
|
||||
<Function name='CenterY'/>
|
||||
@@ -278,6 +279,7 @@
|
||||
<Function name='GetHeight'/>
|
||||
<Function name='GetName'/>
|
||||
<Function name='GetNumStates'/>
|
||||
<Function name='GetNumWrapperStates'/>
|
||||
<Function name='GetParent'/>
|
||||
<Function name='GetRotationX'/>
|
||||
<Function name='GetRotationY'/>
|
||||
@@ -287,6 +289,7 @@
|
||||
<Function name='GetVAlign'/>
|
||||
<Function name='GetVisible'/>
|
||||
<Function name='GetWidth'/>
|
||||
<Function name='GetWrapperState'/>
|
||||
<Function name='GetX'/>
|
||||
<Function name='GetY'/>
|
||||
<Function name='GetZ'/>
|
||||
@@ -301,6 +304,7 @@
|
||||
<Function name='MaskSource'/>
|
||||
<Function name='Real'/>
|
||||
<Function name='RealInverse'/>
|
||||
<Function name='RemoveWrapperState'/>
|
||||
<Function name='RunCommandsRecursively'/>
|
||||
<Function name='SetFakeParent'/>
|
||||
<Function name='SetHeight'/>
|
||||
|
||||
@@ -831,6 +831,20 @@ save yourself some time, copy this for undocumented things:
|
||||
<!-- Classes -->
|
||||
<Classes>
|
||||
<Class name='Actor'>
|
||||
<Function name='AddWrapperState' return='ActorFrame' arguments=''>
|
||||
This adds a wrapper state around the Actor, which is like wrapping the Actor in an ActorFrame, except that you can use it on any actor, and add or remove wrapper states in response to things that happen while the screen is being used. (wrapping an Actor in an ActorFrame normally requires setting it up before the screen starts)<br />
|
||||
The ActorFrame that is returned is the wrapper state, for convenience.<br />
|
||||
An Actor can have any number of wrapper states. Use GetWrapperState to access wrapper states for the actor.
|
||||
</Function>
|
||||
<Function name='GetNumWrapperStates' return='ActorFrame' arguments=''>
|
||||
Returns the number of wrapper states the actor has.
|
||||
</Function>
|
||||
<Function name='GetWrapperState' return='ActorFrame' arguments='int i'>
|
||||
Returns the wrapper state at index i. Think of wrapper states with a higher index as being "further out". Actor is inside Wrapper 1, Wrapper 1 is inside Wrapper 2, Wrapper 2 is inside Wrapper 3, and so on.
|
||||
</Function>
|
||||
<Function name='RemoveWrapperState' return='' arguments='int i'>
|
||||
Removes the wrapper state at index i.
|
||||
</Function>
|
||||
<Function name='GetParent' return='Actor' arguments=''>
|
||||
Returns the Actor's parent, or <code>nil</code> if it doesn't have one.
|
||||
</Function>
|
||||
|
||||
+157
-20
@@ -1,5 +1,6 @@
|
||||
#include "global.h"
|
||||
#include "Actor.h"
|
||||
#include "ActorFrame.h"
|
||||
#include "RageDisplay.h"
|
||||
#include "RageUtil.h"
|
||||
#include "RageMath.h"
|
||||
@@ -172,6 +173,11 @@ Actor::~Actor()
|
||||
{
|
||||
StopTweening();
|
||||
UnsubscribeAll();
|
||||
for(size_t i= 0; i < m_WrapperStates.size(); ++i)
|
||||
{
|
||||
SAFE_DELETE(m_WrapperStates[i]);
|
||||
}
|
||||
m_WrapperStates.clear();
|
||||
}
|
||||
|
||||
Actor::Actor( const Actor &cpy ):
|
||||
@@ -187,6 +193,12 @@ Actor::Actor( const Actor &cpy ):
|
||||
CPY( m_FakeParent );
|
||||
CPY( m_pLuaInstance );
|
||||
|
||||
m_WrapperStates.resize(cpy.m_WrapperStates.size());
|
||||
for(size_t i= 0; i < m_WrapperStates.size(); ++i)
|
||||
{
|
||||
m_WrapperStates[i]= new ActorFrame(*dynamic_cast<ActorFrame*>(cpy.m_WrapperStates[i]));
|
||||
}
|
||||
|
||||
CPY( m_baseRotation );
|
||||
CPY( m_baseScale );
|
||||
CPY( m_fBaseAlpha );
|
||||
@@ -296,7 +308,6 @@ void Actor::Draw()
|
||||
{
|
||||
return; // early abort
|
||||
}
|
||||
bool fake_parent_partially_opaque= true;
|
||||
if(m_FakeParent)
|
||||
{
|
||||
if(!m_FakeParent->m_bVisible || m_FakeParent->m_fHibernateSecondsLeft > 0
|
||||
@@ -305,31 +316,99 @@ void Actor::Draw()
|
||||
return;
|
||||
}
|
||||
m_FakeParent->PreDraw();
|
||||
fake_parent_partially_opaque= m_FakeParent->PartiallyOpaque();
|
||||
}
|
||||
|
||||
this->PreDraw();
|
||||
ASSERT( m_pTempState != NULL );
|
||||
if(PartiallyOpaque() && fake_parent_partially_opaque)
|
||||
{
|
||||
if(m_FakeParent)
|
||||
if(!m_FakeParent->PartiallyOpaque())
|
||||
{
|
||||
m_FakeParent->BeginDraw();
|
||||
}
|
||||
// call the most-derived versions
|
||||
this->BeginDraw();
|
||||
this->DrawPrimitives(); // call the most-derived version of DrawPrimitives();
|
||||
this->EndDraw();
|
||||
if(m_FakeParent)
|
||||
{
|
||||
m_FakeParent->EndDraw();
|
||||
m_FakeParent->PostDraw();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this->PostDraw();
|
||||
|
||||
if(m_FakeParent)
|
||||
{
|
||||
m_FakeParent->BeginDraw();
|
||||
}
|
||||
size_t wrapper_states_used= 0;
|
||||
RageColor last_diffuse;
|
||||
RageColor last_glow;
|
||||
bool use_last_diffuse= false;
|
||||
// dont_abort_draw exists because if one of the layers is invisible,
|
||||
// there's no point in continuing. -Kyz
|
||||
bool dont_abort_draw= true;
|
||||
// abort_with_end_draw exists because PreDraw happens before the
|
||||
// opaqueness test, so if we abort at the opaqueness test, there isn't
|
||||
// a BeginDraw to match the EndDraw. -Kyz
|
||||
bool abort_with_end_draw= true;
|
||||
// It's more intuitive to apply the highest index wrappers first.
|
||||
// On the lua side, it looks like this:
|
||||
// wrapper[3] is the outermost frame. wrapper[2] is inside wrapper[3].
|
||||
// wrapper[1] is inside wrapper[2]. The actor is inside wrapper[1].
|
||||
// -Kyz
|
||||
for(size_t i= m_WrapperStates.size(); i > 0 && dont_abort_draw; --i)
|
||||
{
|
||||
Actor* state= m_WrapperStates[i-1];
|
||||
if(!state->m_bVisible || state->m_fHibernateSecondsLeft > 0 ||
|
||||
state->EarlyAbortDraw())
|
||||
{
|
||||
dont_abort_draw= false;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->PreDraw();
|
||||
if(state->PartiallyOpaque())
|
||||
{
|
||||
state->BeginDraw();
|
||||
last_diffuse= state->m_pTempState->diffuse[0];
|
||||
last_glow= state->m_pTempState->glow;
|
||||
use_last_diffuse= true;
|
||||
if(i > 1)
|
||||
{
|
||||
m_WrapperStates[i-2]->SetInternalDiffuse(last_diffuse);
|
||||
m_WrapperStates[i-2]->SetInternalGlow(last_glow);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dont_abort_draw= false;
|
||||
abort_with_end_draw= false;
|
||||
}
|
||||
++wrapper_states_used;
|
||||
}
|
||||
}
|
||||
// call the most-derived versions
|
||||
if(dont_abort_draw)
|
||||
{
|
||||
if(use_last_diffuse)
|
||||
{
|
||||
this->SetInternalDiffuse(last_diffuse);
|
||||
this->SetInternalGlow(last_glow);
|
||||
}
|
||||
this->PreDraw();
|
||||
ASSERT( m_pTempState != NULL );
|
||||
if(PartiallyOpaque())
|
||||
{
|
||||
this->BeginDraw();
|
||||
this->DrawPrimitives();
|
||||
this->EndDraw();
|
||||
}
|
||||
this->PostDraw();
|
||||
}
|
||||
for(size_t i= 0; i < wrapper_states_used; ++i)
|
||||
{
|
||||
Actor* state= m_WrapperStates[i];
|
||||
if(abort_with_end_draw)
|
||||
{
|
||||
state->EndDraw();
|
||||
}
|
||||
abort_with_end_draw= true;
|
||||
state->PostDraw();
|
||||
state->m_pTempState= NULL;
|
||||
}
|
||||
|
||||
if(m_FakeParent)
|
||||
{
|
||||
m_FakeParent->EndDraw();
|
||||
m_FakeParent->PostDraw();
|
||||
m_FakeParent->m_pTempState= NULL;
|
||||
}
|
||||
m_pTempState = NULL;
|
||||
}
|
||||
@@ -728,6 +807,10 @@ void Actor::Update( float fDeltaTime )
|
||||
fDeltaTime = -m_fHibernateSecondsLeft;
|
||||
m_fHibernateSecondsLeft = 0;
|
||||
}
|
||||
for(size_t i= 0; i < m_WrapperStates.size(); ++i)
|
||||
{
|
||||
m_WrapperStates[i]->Update(fDeltaTime);
|
||||
}
|
||||
|
||||
this->UpdateInternal( fDeltaTime );
|
||||
}
|
||||
@@ -823,6 +906,26 @@ RString Actor::GetLineage() const
|
||||
return sPath;
|
||||
}
|
||||
|
||||
void Actor::AddWrapperState()
|
||||
{
|
||||
ActorFrame* wrapper= new ActorFrame;
|
||||
wrapper->InitState();
|
||||
m_WrapperStates.push_back(wrapper);
|
||||
}
|
||||
|
||||
void Actor::RemoveWrapperState(size_t i)
|
||||
{
|
||||
ASSERT(i < m_WrapperStates.size());
|
||||
SAFE_DELETE(m_WrapperStates[i]);
|
||||
m_WrapperStates.erase(m_WrapperStates.begin()+i);
|
||||
}
|
||||
|
||||
Actor* Actor::GetWrapperState(size_t i)
|
||||
{
|
||||
ASSERT(i < m_WrapperStates.size());
|
||||
return m_WrapperStates[i];
|
||||
}
|
||||
|
||||
void Actor::BeginTweening( float time, ITween *pTween )
|
||||
{
|
||||
ASSERT( time >= 0 );
|
||||
@@ -1765,6 +1868,36 @@ public:
|
||||
}
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
static int AddWrapperState(T* p, lua_State* L)
|
||||
{
|
||||
p->AddWrapperState();
|
||||
p->GetWrapperState(p->GetNumWrapperStates()-1)->PushSelf(L);
|
||||
return 1;
|
||||
}
|
||||
static size_t get_state_index(T* p, lua_State* L, int stack_index)
|
||||
{
|
||||
// Lua is one indexed.
|
||||
int i= IArg(stack_index)-1;
|
||||
const size_t si= static_cast<size_t>(i);
|
||||
if(i < 0 || si >= p->GetNumWrapperStates())
|
||||
{
|
||||
luaL_error(L, "%d is not a valid wrapper state index.", i+1);
|
||||
}
|
||||
return si;
|
||||
}
|
||||
static int RemoveWrapperState(T* p, lua_State* L)
|
||||
{
|
||||
size_t si= get_state_index(p, L, 1);
|
||||
p->RemoveWrapperState(si);
|
||||
COMMON_RETURN_SELF;
|
||||
}
|
||||
DEFINE_METHOD(GetNumWrapperStates, GetNumWrapperStates());
|
||||
static int GetWrapperState(T* p, lua_State* L)
|
||||
{
|
||||
size_t si= get_state_index(p, L, 1);
|
||||
p->GetWrapperState(si)->PushSelf(L);
|
||||
return 1;
|
||||
}
|
||||
static int Draw( T* p, lua_State *L )
|
||||
{
|
||||
LUA->YieldLua();
|
||||
@@ -1938,6 +2071,10 @@ public:
|
||||
ADD_METHOD( GetParent );
|
||||
ADD_METHOD( GetFakeParent );
|
||||
ADD_METHOD( SetFakeParent );
|
||||
ADD_METHOD( AddWrapperState );
|
||||
ADD_METHOD( RemoveWrapperState );
|
||||
ADD_METHOD( GetNumWrapperStates );
|
||||
ADD_METHOD( GetWrapperState );
|
||||
|
||||
ADD_METHOD( Draw );
|
||||
}
|
||||
|
||||
@@ -310,6 +310,11 @@ public:
|
||||
void SetFakeParent(Actor* mailman) { m_FakeParent= mailman; }
|
||||
Actor* GetFakeParent() { return m_FakeParent; }
|
||||
|
||||
void AddWrapperState();
|
||||
void RemoveWrapperState(size_t i);
|
||||
Actor* GetWrapperState(size_t i);
|
||||
size_t GetNumWrapperStates() const { return m_WrapperStates.size(); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the Actor's x position.
|
||||
* @return the Actor's x position. */
|
||||
@@ -616,6 +621,9 @@ protected:
|
||||
// state without making that actor the parent. It's like having multiple
|
||||
// parents. -Kyz
|
||||
Actor* m_FakeParent;
|
||||
// WrapperStates provides a way to wrap the actor inside ActorFrames,
|
||||
// applicable to any actor, not just ones the theme creates.
|
||||
vector<Actor*> m_WrapperStates;
|
||||
|
||||
/** @brief Some general information about the Tween. */
|
||||
struct TweenInfo
|
||||
|
||||
@@ -251,6 +251,12 @@ void ActorFrame::DrawPrimitives()
|
||||
RageColor diffuse = m_pTempState->diffuse[0];
|
||||
RageColor glow = m_pTempState->glow;
|
||||
|
||||
// Word of warning: Actor::Draw duplicates the structure of how an Actor
|
||||
// is drawn inside of an ActorFrame for its wrapping feature. So if
|
||||
// you're adding something new to ActorFrames that affects how Actors are
|
||||
// drawn, make sure to also apply it in Actor::Draw's handling of the
|
||||
// wrappers. -Kyz
|
||||
|
||||
// draw all sub-ActorFrames while we're in the ActorFrame's local coordinate space
|
||||
if( m_bDrawByZPosition )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user