载入中...
搜索中...
未找到
PcgGrowth.cpp
浏览该文件的文档.
8namespace eve::scene{namespace{float random01(std::uint32_t x){x^=x>>16;x*=0x7feb352du;x^=x>>15;x*=0x846ca68bu;x^=x>>16;return float(x>>8)*(1.f/16777216.f);}}
9Result<void> PcgGrowth::configure(float a,float b,float v,float d){if(!std::isfinite(a)||!std::isfinite(b)||!std::isfinite(v)||!std::isfinite(d)||a<.1f||a>2||b<.1f||b>2||v<0||v>2||d<.5f||d>60)return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"growth configuration is outside Pcg ranges","scene.pcgGrowth.configure"));startScale_=a;endScale_=b;variance_=v;duration_=d;return Result<void>::success();}
10Result<void> PcgGrowth::start(float now,std::uint32_t seed){if(!std::isfinite(now))return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"start time must be finite","scene.pcgGrowth.start"));startTime_=now;actualEnd_=endScale_+random01(seed)*variance_;scale_=startScale_;started_=true;finished_=false;dying_=false;return Result<void>::success();}
11Result<float> PcgGrowth::advance(float now){if(!started_)return Result<float>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"growth has not started","scene.pcgGrowth.advance"));if(!std::isfinite(now)||now<startTime_)return Result<float>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"time must be finite and monotonic","scene.pcgGrowth.advance"));float t=std::min((now-startTime_)/duration_,1.f);scale_=startScale_+t*(actualEnd_-startScale_);finished_=t>=1;return Result<float>::success(scale_);}
12Result<void> PcgGrowth::die(float now){if(!std::isfinite(now))return Result<void>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"death time must be finite","scene.pcgGrowth.die"));deathTime_=now+5;dying_=true;return Result<void>::success();}
13Result<bool> PcgGrowth::shouldDestroy(float now)const{if(!std::isfinite(now))return Result<bool>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"time must be finite","scene.pcgGrowth.destroy"));return Result<bool>::success(dying_&&now>=deathTime_);}
14Result<bool> applyPcgGrowth(PcgGrowth& g,SceneNodeRef& node,float now){auto due=g.shouldDestroy(now);if(!due)return Result<bool>::failure(due.status());if(due.value()){auto*s=node.getScene();if(!s||!s->removeNodeAt(node.getHostName(),node.getNodeId()))return Result<bool>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"growth node cannot be removed","scene.pcgGrowth.node"));return Result<bool>::success(true);}auto scale=g.advance(now);if(!scale)return Result<bool>::failure(scale.status());if(!node.setScale(scale.value(),scale.value(),scale.value()))return Result<bool>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"growth node cannot be scaled","scene.pcgGrowth.node"));return Result<bool>::success(false);}
15void exposePcgGrowthBindings(ssq::Table&t){auto c=t.addClass("PcgGrowth",ssq::Class::Ctor<PcgGrowth()>());auto vm=t.getHandle();c.addFunc("configure",[vm](PcgGrowth*s,float a,float b,float v,float d){return eve::script::projectResult(vm,s->configure(a,b,v,d));});c.addFunc("start",[vm](PcgGrowth*s,float n,int seed){return eve::script::projectResult(vm,s->start(n,std::uint32_t(seed)));});c.addFunc("advance",[vm](PcgGrowth*s,float n){return eve::script::projectResult(vm,s->advance(n),[](float v){return Value(v);});});c.addFunc("die",[vm](PcgGrowth*s,float n){return eve::script::projectResult(vm,s->die(n));});c.addFunc("shouldDestroy",[vm](const PcgGrowth*s,float n){return eve::script::projectResult(vm,s->shouldDestroy(n),[](bool v){return Value(v);});});c.addFunc("getActualEndScale",[](const PcgGrowth*s){return s->getActualEndScale();});c.addFunc("getScale",[](const PcgGrowth*s){return s->getScale();});c.addFunc("getFinished",[](const PcgGrowth*s){return s->getFinished();});t.addFunc("applyPcgGrowth",[vm](PcgGrowth*g,SceneNodeRef*n,float now){auto r=g&&n?applyPcgGrowth(*g,*n,now):Result<bool>::failure(Diagnostic::error(DiagnosticCode::InvalidArgument,"growth and node are required","scene.pcgGrowth.node"));return eve::script::projectResult(vm,std::move(r),[](bool v){return Value(v);});});}
The single Squirrel projection for common Result, Status and Value.
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
static Result failure(Status status)
Construct a failed result from a structured status.
Definition Result.h:175
Caller-owned one-shot Pcg Growth state with explicit time and random seed.
Definition PcgGrowth.h:8
Result< void > configure(float startScale, float endScale, float variance, float duration)
Configure scale interval, variance, and duration atomically.
Definition PcgGrowth.cpp:9
Result< void > die(float now)
Schedule destruction five seconds from absolute real time.
Definition PcgGrowth.cpp:12
Result< float > advance(float now)
Evaluate the linear scale at absolute real time.
Definition PcgGrowth.cpp:11
Result< void > start(float now, std::uint32_t seed)
Choose the final scale from seed and begin at absolute real time.
Definition PcgGrowth.cpp:10
Result< bool > shouldDestroy(float now) const
Return whether delayed destruction is due.
Definition PcgGrowth.cpp:13
Script handle to a scene node (hostName + nodeId). Deliberately holds strings rather than arena point...
Definition SceneNodeRef.h:20
Definition AvatarInstance.h:33
Result< bool > applyPcgGrowth(PcgGrowth &g, SceneNodeRef &node, float now)
Advance growth on a real scene node; returns true when it removed the node.
Definition PcgGrowth.cpp:14
ssq::Table projectResult(HSQUIRRELVM vm, Result< void > &&result)
Consume and project a void native Result using the common schema.
Definition SquirrelBinding.cpp:470
@ InvalidArgument