This commit is contained in:
watrabi
2025-09-18 17:55:52 -04:00
commit 977f1ff4b8
15030 changed files with 17324420 additions and 0 deletions
+182
View File
@@ -0,0 +1,182 @@
/* Copyright 2003-2013 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/IEquipable.h"
#include "V8DataModel/PartInstance.h"
#include "V8Tree/Instance.h"
#include "GfxBase/IAdornable.h"
#include "Util/CameraSubject.h"
#include "Util/Selectable.h"
namespace RBX {
class PartInstance;
class ModelInstance;
class Weld;
class ServiceProvider;
class Workspace;
class Attachment;
namespace Network {
class Player;
}
extern const char *const sAccoutrement;
extern const char *const sHat;
extern const char *const sAccessory;
class Accoutrement
: public DescribedCreatable<Accoutrement, Instance, sAccoutrement>
, public IEquipable // TODO - move stuff here that's common with Tool
, public IAdornable
, public CameraSubject
{
typedef DescribedCreatable<Accoutrement, Instance, sAccoutrement> Super;
protected:
typedef enum { NOTHING,
HAS_HANDLE,
IN_WORKSPACE,
IN_CHARACTER,
EQUIPPED
} AccoutrementState;
// Replicated Properties
AccoutrementState backendAccoutrementState; // backend writes, frontend reads
CoordinateFrame attachmentPoint; // replicates, stores
// "Backend" connections
rbx::signals::scoped_connection_logged handleTouched; // watches for handle touched
rbx::signals::scoped_connection characterChildAdded;
rbx::signals::scoped_connection characterChildRemoved;
rbx::signals::scoped_connection attachmentAdjusted;
// Event handlers - hooked to these signals
void onEvent_AddedBackend(shared_ptr<Instance> child);
void onEvent_RemovedBackend(shared_ptr<Instance> child);
void onEvent_HandleTouched(shared_ptr<Instance> other);
void onEvent_AttachmentAdjusted(const RBX::Reflection::PropertyDescriptor*);
static AccoutrementState characterCanPickUpAccoutrement(Instance* touchingCharacter);
static void UnequipThis(shared_ptr<Instance> instance);
void updateWeld();
///////////////////////////////////////////////////////////////
//
// Backend side
//
AccoutrementState computeDesiredState();
AccoutrementState computeDesiredState(Instance *testParent);
void setDesiredState(AccoutrementState desiredState, const ServiceProvider* serviceProvider);
void setBackendAccoutrementStateNoReplicate(int value);
void rebuildBackendState();
void connectTouchEvent();
void connectAttachmentAdjustedEvent();
// Backend - climbing state
void upTo_Equipped();
void upTo_InCharacter();
void upTo_InWorkspace();
void upTo_HasHandle();
// Backend - dropping state
void downFrom_Equipped();
void downFrom_InCharacter();
void downFrom_InWorkspace();
void downFrom_HasHandle();
///////////////////////////////////////////////////////////////////////
//
// Frontend side
// Instance
/*override*/ void onChildAdded(Instance* child);
/*override*/ void onChildRemoved(Instance* child);
/*override*/ void onAncestorChanged(const AncestorChanged& event);
/*override*/ bool askSetParent(const Instance* instance) const {return true;}
/*override*/ bool askAddChild(const Instance* instance) const {return true;}
////////////////////////////////////////////////////////////////////////
// IHasLocation
/*override*/ const CoordinateFrame getLocation();
////////////////////////////////////////////////////////////////////////
// CameraSubject
//
/*override*/ const CoordinateFrame getRenderLocation() {return getLocation();}
/*override*/ const Vector3 getRenderSize()
{
if(PartInstance* handle = getHandle())
return handle->getPartSizeUi();
return Vector3(0,0,0);
}
/*override*/ void onCameraNear(float distance);
// BackpackItem
/*override*/ bool drawSelected() const {return (backendAccoutrementState >= EQUIPPED);}
// IAdornable
/*override*/ void render3dSelect(Adorn* adorn, SelectState selectState);
public:
Accoutrement();
~Accoutrement();
static void dropAll(ModelInstance* character);
static void dropAllOthers(ModelInstance *character, Accoutrement *exception);
PartInstance* getHandle();
const PartInstance* getHandleConst() const;
Attachment* findFirstMatchingAttachment(Instance* model, const std::string& originalAttachment);
//////////////////////////////////////////////////////////
//
// REPLICATION Signals
void setBackendAccoutrementState(int value);
int getBackendAccoutrementState() const {return backendAccoutrementState;}
const CoordinateFrame& getAttachmentPoint() const {return attachmentPoint;}
void setAttachmentPoint(const CoordinateFrame& value);
// Auxillary UI props
const Vector3 getAttachmentPos() const;
const Vector3 getAttachmentForward() const;
const Vector3 getAttachmentUp() const;
const Vector3 getAttachmentRight() const;
void setAttachmentPos(const Vector3& v);
void setAttachmentForward(const Vector3& v);
void setAttachmentUp(const Vector3& v);
void setAttachmentRight(const Vector3& v);
};
class Hat
: public DescribedCreatable<Hat, Accoutrement, sHat>
{
public:
Hat();
};
class Accessory
: public DescribedCreatable<Accessory, Accoutrement, sAccessory>
{
public:
Accessory();
};
} // namespace
+53
View File
@@ -0,0 +1,53 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/JointInstance.h"
#include "V8DataModel/Workspace.h"
#include "Humanoid/Humanoid.h"
#include "V8World/Primitive.h"
#include "V8World/Assembly.h"
#include "rbx/rbxTime.h"
DYNAMIC_FASTINT(ActionStationDebounceTime)
namespace RBX {
template<class Base>
class ActionStation : public Base
{
private:
typedef Base Super;
protected:
Time sleepTime;
Time debounceTime;
bool sleepTimeUp() const {
return (Time::now<Time::Fast>() - sleepTime).seconds() > 3.0;
}
bool debounceTimeUp() const {
return (Time::now<Time::Fast>() - debounceTime).seconds() > DFInt::ActionStationDebounceTime;
}
// Instance
// TODO: Ultra mega super hack - setName is setting the internal Primitive::sizeMultiplier
void setName(const std::string& value) {
Super::setName(value);
this->getPartPrimitive()->setSizeMultiplier(Primitive::SEAT_SIZE);
}
public:
ActionStation() : sleepTime(Time::now<Time::Fast>() - Time::Interval(4.0)), debounceTime(Time::now<Time::Fast>())
{
RBXASSERT(this->sleepTimeUp());
RBXASSERT(this->getPartPrimitive());
this->getPartPrimitive()->setSizeMultiplier(Primitive::SEAT_SIZE);
}
virtual ~ActionStation() {}
};
} // namespace
+55
View File
@@ -0,0 +1,55 @@
//
// AdService.h
// Copyright ROBLOX Corp 2014
//
// Created by Ben Tkacheff on 4/16/14.
//
//
#pragma once
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include "V8DataModel/UserInputService.h"
namespace RBX
{
extern const char* const sAdService;
class AdService
: public DescribedCreatable<AdService, Instance, sAdService, Reflection::ClassDescriptor::INTERNAL>
, public Service
{
private:
typedef DescribedCreatable<AdService, Instance, sAdService, Reflection::ClassDescriptor::INTERNAL> Super;
bool showingVideoAd;
std::string platformToWebString(const UserInputService::Platform userPlatform);
bool canUseService();
protected:
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
public:
AdService();
rbx::signal<void(bool)> videoAdClosedSignal;
rbx::signal<void()> playVideoAdSignal;
rbx::remote_signal<void(int, UserInputService::Platform)> sendServerVideoAdVerification;
rbx::remote_signal<void(bool, int, std::string)> sendClientVideoAdVerificationResults;
rbx::remote_signal<void(int, UserInputService::Platform, bool)> sendServerRecordImpression;
void showVideoAd();
void videoAdClosed(bool didPlay);
void sendAdImpression(int userId, UserInputService::Platform platform, bool didPlay);
void verifyCanPlayVideoAdReceivedResponseNoDMLock(const std::string& response, int userId);
void verifyCanPlayVideoAdReceivedErrorNoDMLock(const std::string& error, int userId);
void verifyCanPlayVideoAdReceivedError(const std::string& error, int userId);
void checkCanPlayVideoAd(int userId, UserInputService::Platform userPlatform);
void receivedServerShowAdMessage(const bool success, int userId, const std::string& errorMessage);
};
}
+46
View File
@@ -0,0 +1,46 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/GuiBase3d.h"
#include "Util/BrickColor.h"
namespace RBX {
class PartInstance;
class PVInstance;
extern const char* const sPartAdornment;
//A base class for "adornment" of PartInstances (3D objects that adorn Instances)
class PartAdornment : public DescribedNonCreatable<PartAdornment, GuiBase3d, sPartAdornment>
{
public:
PartAdornment(const char* name);
const PartInstance* getAdornee() const { return adornee.lock().get(); }
PartInstance* getAdornee() { return adornee.lock().get(); }
void setAdornee(PartInstance* value);
PartInstance* getAdorneeDangerous() const { return adornee.lock().get(); }
protected:
weak_ptr<PartInstance> adornee;
};
extern const char* const sPVAdornment;
//A base class for "adornment" of PartInstances (3D objects that adorn Instances)
class PVAdornment : public DescribedNonCreatable<PVAdornment, GuiBase3d, sPVAdornment>
{
public:
PVAdornment(const char* name);
const PVInstance* getAdornee() const { return adornee.lock().get(); }
PVInstance* getAdornee() { return adornee.lock().get(); }
void setAdornee(PVInstance* value);
PVInstance* getAdorneeDangerous() const { return adornee.lock().get(); }
protected:
weak_ptr<PVInstance> adornee;
};
}
@@ -0,0 +1,22 @@
#pragma once
#include "V8DataModel/PartInstance.h"
#include "V8DataModel/IAnimatableJoint.h"
namespace RBX
{
class AnimatableRootJoint : public IAnimatableJoint
{
bool isAnimating;
shared_ptr<PartInstance> part;
CoordinateFrame lastCFrame;
public:
AnimatableRootJoint(const shared_ptr<PartInstance>& part);
PartInstance* getPart() const { return part.get(); }
/*override*/ void setAnimating(bool value);
/*override*/ const std::string& getParentName();
/*override*/ const std::string& getPartName();
/*override*/ void applyPose(const CachedPose& pose);
};
}
+36
View File
@@ -0,0 +1,36 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "Util/AnimationId.h"
namespace RBX {
extern const char *const sAnimation;
class KeyframeSequence;
class Animation
: public DescribedCreatable<Animation, Instance, sAnimation>
{
private:
typedef DescribedCreatable<Animation, Instance, sAnimation> Super;
ContentId assetId;
public:
Animation();
shared_ptr<const KeyframeSequence> getKeyframeSequence() const;
shared_ptr<const KeyframeSequence> getKeyframeSequence(const Instance* context) const;
AnimationId getAssetId() const { return assetId; }
void setAssetId(AnimationId value);
bool isEmbeddedAsset() const;
/*override*/ bool askSetParent(const Instance* instance) const { return true; }
/*override*/ int getPersistentDataCost() const
{
return Super::getPersistentDataCost() + Instance::computeStringCost(getAssetId().toString());
}
};
} // namespace
@@ -0,0 +1,42 @@
/* Copyright 2003-2013 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "Util/SteppedInstance.h"
#include "Util/RunStateOwner.h"
namespace RBX {
// class Workspace;
// class Primitive;
// class PartInstance;
class Animator;
extern const char* const sAnimationController;
class AnimationController : public DescribedCreatable<AnimationController, Instance, sAnimationController>
, public IStepped
{
private:
typedef DescribedCreatable<AnimationController, Instance, sAnimationController> Super;
shared_ptr<Animator> animator;
Animator* getAnimator();
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
// IStepped
/*override*/ void onStepped(const Stepped& event);
public:
AnimationController();
virtual ~AnimationController();
shared_ptr<Instance> loadAnimation(shared_ptr<Instance> animation);
shared_ptr<const Reflection::ValueArray> getPlayingAnimationTracks();
rbx::signal<void(shared_ptr<Instance>)> animationPlayedSignal;
};
} // namespace RBX
+65
View File
@@ -0,0 +1,65 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "V8DataModel/KeyframeSequence.h"
namespace RBX {
class Animator;
class AnimationTrackState;
class Animation;
extern const char *const sAnimationTrack;
//A controller class that wraps an AnimationTrackState and allows for interaction with Lua
class AnimationTrack
: public DescribedNonCreatable<AnimationTrack, Instance, sAnimationTrack>
{
protected:
//Keeps animationTrackState alive (in case we need to restart it)
shared_ptr<AnimationTrackState> animationTrackState;
//Keeps a weak ptr to our animator, so we can restart an animation if it has become stopped
weak_ptr<Animator> animator;
shared_ptr<Animation> animation;
rbx::signals::connection keyframeReachedConnection;
rbx::signals::connection stoppedConnection;
void forwardKeyframeReached(std::string);
void forwardStopped();
double getGameTime() const;
public:
AnimationTrack(shared_ptr<AnimationTrackState> animationTrackState, weak_ptr<Animator> animator, shared_ptr<Animation> anim);
~AnimationTrack();
void play(float fadeTime, float weight, float speed);
void localPlay(float fadeTime, float weight, float speed);
void stop(float fadeTime);
void localStop(float fadeTime);
void adjustWeight(float weight, float fadeTime);
void adjustSpeed(float speed);
void localAdjustSpeed(float speed);
float getLength() const;
bool getIsPlaying() const;
Animation* getAnimation() const;
double getTimePosition() const;
void setTimePosition(double timePosition);
void localSetTimePosition(double timePosition);
double getTimeOfKeyframe(std::string keyframeName);
KeyframeSequence::Priority getPriority() const;
void setPriority(KeyframeSequence::Priority priority);
const std::string getAnimationName() const;
rbx::signal<void(std::string)> keyframeReachedSignal;
rbx::signal<void()> stoppedSignal;
};
} // namespace
@@ -0,0 +1,99 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "Util/ContentId.h"
#include "V8DataModel/KeyframeSequence.h"
namespace RBX {
extern const char *const sAnimationTrackState;
class KeyframeSequence;
class Animator;
class AnimationTrack;
struct PoseAccumulator;
class AnimationTrackState
: public DescribedNonCreatable<AnimationTrackState, Instance, sAnimationTrackState>
{
protected:
//Either set directly for solo/debugging or replicated by the AssetId
shared_ptr<const KeyframeSequence> keyframeSequence;
shared_ptr<AnimationTrack> animationTrack;
int preKeyframe;
//Keep a weak ptr to our parent
weak_ptr<const Animator> animator;
double startTime; // reset by the "play" function.
double speed;
double phase; // speed-independent adjustment to keyframetime.
double fadeStartTime;
double fadeStartWeight;
double fadeEndTime;
double fadeEndWeight;
bool isPlaying;
double getGameTime(); // helper
void onPlay(float gameTime, float fadeTime, float weight, float speed);
void onStop(float gameTime, float fadeTime);
void onAdjustWeight(float gameTime, float weight, float fadeTime);
void onAdjustSpeed(float gameTime, float speed);
bool inReverse();
void detectKeyframeReached(double animationTime, double lastAnimationTime);
KeyframeSequence::Priority priority;
bool priorityOverridden;
// helper for step()
void triggerKeyframeReachedSignal(const shared_ptr<Instance>& child, double minKeyframeTime, double maxKeyframeTime);
protected:
double lastKeyframeTime; // keep track of last played frame for keyframe events.
public:
AnimationTrackState(shared_ptr<const KeyframeSequence> keyframeSequence, weak_ptr<const Animator> animator);
~AnimationTrackState() {}
void play(float fadeTime, float weight, float speed);
void stop(float fadeTime);
void adjustWeight(float weight, float fadeTime);
void adjustSpeed(float speed);
//Should be private
rbx::remote_signal<void(float,float,float, float)> internalPlaySignal;
rbx::remote_signal<void(float,float)> internalStopSignal;
rbx::remote_signal<void(float,float,float)> internalAdjustWeightSignal;
rbx::remote_signal<void(float,float)> internalAdjustSpeedSignal;
rbx::remote_signal<void(std::string)> keyframeReachedSignal;
rbx::remote_signal<void()> stoppedSignal;
const KeyframeSequence* getKeyframeSequence() const { return keyframeSequence.get(); };
void setKeyframeSequence(shared_ptr<KeyframeSequence>);
double getWeightAtTime(double time);
double getKeyframeAtTime(double time);
void setKeyframeAtTime(double gameTime, double keyframeTime); // adjust phase to get animation on a specific keyframe.
double getSpeed() { return speed; }
float getDuration();
bool isStopped(double time);
bool getIsPlaying() const { return isPlaying; };
double getDurationClampedKeyframeTime(double keyframeTime);
KeyframeSequence::Priority getPriority() const;
void setPriority(KeyframeSequence::Priority priority);
void resetKeyframeReachedDetection(double keyframeTime);
void step(std::vector<PoseAccumulator>& jointposes, double time);
void setAnimationTrack(shared_ptr<AnimationTrack> animationTrackIn);
shared_ptr<AnimationTrack> getAnimationTrack() const { return animationTrack; };
};
} // namespace
+96
View File
@@ -0,0 +1,96 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "Util/SteppedInstance.h"
#include "V8DataModel/KeyframeSequence.h" //for Animation::Priority, CachedPose
namespace RBX {
class AnimatableRootJoint;
class AnimationTrackState;
class PartInstance;
class AnimationTrack;
extern const char *const sAnimator;
class Animator
: public DescribedCreatable<Animator, Instance, sAnimator>
, public IStepped
{
private:
typedef DescribedCreatable<Animator, Instance, sAnimator> Super;
RBX::Time serverLockTimer;
Instance* getRootInstance();
void setupClumpChangedListener(Instance* rootInstance);
protected:
std::map<ContentId, shared_ptr<AnimationTrack> > animationTrackMap;
std::string activeAnimation;
typedef std::vector<JointPair> AnimatableJointSet;
AnimatableJointSet animatableJoints;
void calcAnimatableJoints(Instance* rootInstance, shared_ptr<Instance> descendant = shared_ptr<Instance>());
void appendAnimatableJointsRec(shared_ptr<Instance> instance, shared_ptr<Instance> exclude);
scoped_ptr<AnimatableRootJoint> animatableRootJoint;
rbx::signals::scoped_connection descentdantAdded;
rbx::signals::scoped_connection descentdantRemoved;
rbx::signals::scoped_connection ancestorChanged;
rbx::signals::scoped_connection clumpChangedConnection;
void onEvent_DescendantAdded(shared_ptr<Instance> descendant);
void onEvent_DescendantRemoving(shared_ptr<Instance> descendant);
void onEvent_AncestorModified();
void onEvent_ClumpChanged(shared_ptr<Instance> instance);
std::list<shared_ptr<AnimationTrackState> > activeAnimations;
public:
Animator();
Animator(Instance* replicatingContainer); // use this to add Animator behavor to another Instance in the tree, like Humanoid.
virtual ~Animator();
float getGameTime() const;
shared_ptr<Instance> loadAnimation(shared_ptr<Instance> animation);
void reloadAnimation(shared_ptr<AnimationTrackState> animationTrackState);
shared_ptr<PartInstance> testForServerLockPart;
/*implement*/ void onStepped(const Stepped& event);
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
/*override*/ void verifySetParent(const Instance* instance) const;
/*override*/ bool askSetParent(const Instance* instance) const { return true; }
/*override*/ bool askAddChild(const Instance* instance) const;
/*override*/ void onAncestorChanged(const AncestorChanged& event);
rbx::remote_signal<void(ContentId, float, float, float)> onPlaySignal;
rbx::remote_signal<void(ContentId, float)> onStopSignal;
rbx::remote_signal<void(ContentId, float)> onAdjustSpeedSignal;
rbx::remote_signal<void(ContentId, float)> onSetTimePositionSignal;
void onPlay(ContentId animation, float fadeTime, float weight, float speed);
void onStop(ContentId animation, float fadeTime);
void onAdjustSpeed(ContentId animation, float speed);
void onSetTimePosition(ContentId animation, float timePosition);
void passiveLoadAnimation(ContentId animation);
void replicateAnimationPlay(ContentId animation, float fadeTime, float weight, float speed, shared_ptr<Instance> track);
void replicateAnimationStop(ContentId animation, float fadeTime);
void replicateAnimationSpeed(ContentId animation, float speed);
void replicateAnimationTimePosition(ContentId animation, float timePosition);
std::string getActiveAnimation() const {return activeAnimation;}
void tellParentAnimationPlayed(shared_ptr<Instance> animationTrack);
shared_ptr<const Reflection::ValueArray> getPlayingAnimationTracks();
private:
void onTrackStepped(shared_ptr<AnimationTrackState> trackinst, double time, KeyframeSequence::Priority priority,
std::vector<PoseAccumulator>* poses
);
};
} // namespace
+69
View File
@@ -0,0 +1,69 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/HandlesBase.h"
#include "V8DataModel/EventReplicator.h"
#include "GfxBase/IAdornable.h"
#include "Util/Axes.h"
#include "AppDraw/HandleType.h"
namespace RBX
{
extern const char* const sArcHandles;
class ArcHandles
: public DescribedCreatable<ArcHandles, HandlesBase, sArcHandles>
{
private:
typedef DescribedCreatable<ArcHandles, HandlesBase, sArcHandles> Super;
public:
ArcHandles();
rbx::remote_signal<void(RBX::Vector3::Axis)> mouseEnterSignal;
rbx::remote_signal<void(RBX::Vector3::Axis)> mouseLeaveSignal;
rbx::remote_signal<void(RBX::Vector3::Axis,float,float)> mouseDragSignal;
rbx::remote_signal<void(RBX::Vector3::Axis)> mouseButton1DownSignal;
rbx::remote_signal<void(RBX::Vector3::Axis)> mouseButton1UpSignal;
DECLARE_EVENT_REPLICATOR_SIG(ArcHandles,MouseEnter, void(RBX::Vector3::Axis));
DECLARE_EVENT_REPLICATOR_SIG(ArcHandles,MouseLeave, void(RBX::Vector3::Axis));
DECLARE_EVENT_REPLICATOR_SIG(ArcHandles,MouseDrag, void(RBX::Vector3::Axis,float,float));
DECLARE_EVENT_REPLICATOR_SIG(ArcHandles,MouseButton1Down, void(RBX::Vector3::Axis));
DECLARE_EVENT_REPLICATOR_SIG(ArcHandles,MouseButton1Up, void(RBX::Vector3::Axis));
void setAxes(Axes value);
Axes getAxes() const { return axes; }
////////////////////////////////////////////////////////////////////////////////////
//
// Instance
/*override*/ void onPropertyChanged(const Reflection::PropertyDescriptor& descriptor);
////////////////////////////////////////////////////////////////////////////////////
//
// GuiBase
/*override*/ GuiResponse process(const shared_ptr<InputObject>& event);
////////////////////////////////////////////////////////////////////////////////////
//
// HandlesBase
/*override*/ RBX::HandleType getHandleType() const;
protected:
////////////////////////////////////////////////////////////////////////////////////
//
// HandlesBase
/*override*/ int getHandlesNormalIdMask() const;
/*override*/ void setServerGuiObject();
private:
Axes axes;
};
}
+65
View File
@@ -0,0 +1,65 @@
#pragma once
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
namespace RBX {
extern const char* const sAssetService;
class AssetService
:public DescribedNonCreatable<AssetService, Instance, sAssetService>
,public Service
{
ThrottlingHelper createPlaceThrottle, savePlaceThrottle;
public:
enum AccessType
{
ME = 0,
FRIENDS = 1,
EVERYONE = 2,
INVITEONLY = 3,
};
AssetService();
void setPlaceAccessUrl(std::string url);
void setAssetRevertUrl(std::string url);
void setAssetVersionsUrl(std::string url);
void revertAsset(int assetId, int versionNumber, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getAssetVersions(int assetId, int pageNum, boost::function<void(shared_ptr<const Reflection::ValueTable>)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getPlacePermissions(int placeId, boost::function<void(shared_ptr<const Reflection::ValueTable>)> resumeFunction, boost::function<void(std::string)> errorFunction);
void setPlacePermissions(int placeId, AccessType type, shared_ptr<const Reflection::ValueArray> inviteList,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getCreatorAssetID(int creationID, boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
void createPlaceAsync(std::string placeName, int templatePlaceId, std::string desc,
boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
void createPlaceInPlayerInventoryAsync(shared_ptr<Instance> player, std::string placeName, int templatePlaceId, std::string desc,
boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
void savePlaceAsync(boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
void getGamePlacesAsync(boost::function<void(shared_ptr<Instance>) > resumeFunction,
boost::function<void(std::string)> errorFunction);
private:
std::string placeAccessUrl;
std::string assetRevertUrl;
std::string assetVersionsUrl;
void httpPostHelper(std::string* response, std::exception* httpException, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void processServiceResults(std::string *result, const std::exception* httpException,
boost::function<void(shared_ptr<const Reflection::ValueTable>)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getCreatorAssetIDSuccessHelper(std::string response, boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getCreatorAssetIDErrorHelper(std::string error, boost::function<void(std::string)> errorFunction);
void createPlaceAsyncInternal(bool check, std::string placeName, int templatePlaceId, std::string desc, shared_ptr<Instance> player,
boost::function<void(int)> resumeFunction, boost::function<void(std::string)> errorFunction);
bool checkCreatePlaceAccess(const std::string& placeName, int templatePlaceId, std::string& message);
};
}
+123
View File
@@ -0,0 +1,123 @@
/* Copyright 2003-2012 ROBLOX Corporation, All Rights Reserved */
#if 1 // disable until we are ready for new joint schema
#pragma once
#include "V8Tree/Instance.h"
#include "GfxBase/IAdornable.h"
#include "Util/NormalId.h"
namespace RBX {
// This is not a streaming/replication safe option, do not enable!
// #define RBX_ATTACHMENT_LOCKING
extern const char *const sAttachment;
class Attachment
: public DescribedCreatable<Attachment, Instance, sAttachment>
, public IAdornable
{
public:
// The adorn looks of the attachment
static float adornRadius;
// The attachment adorn looks under the AttachmentTool
static float toolAdornHandleRadius;
static float toolAdornMajorAxisSize;
static float toolAdornMajorAxisRadius;
static float toolAdornMinorAxisSize;
static float toolAdornMinorAxisRadius;
private:
typedef DescribedCreatable<Attachment, Instance, sAttachment> Super;
// Should we render something in game
bool visible;
bool locked;
Vector3 pivotPositionInPart;
Vector3 axisDirectionInPart;
Vector3 secondaryAxisDirectionInPart;
bool shouldRender3dAdorn() const override {return true;}
void verifySetParent(const Instance* instance) const override;
void verifyAddChild(const Instance* newChild) const override;
public:
static Reflection::PropDescriptor<Attachment, CoordinateFrame> prop_Frame;
Attachment();
~Attachment() {}
// For UI, scripting and streaming
bool getVisible( void ) const { return visible; }
void setVisible( bool value );
bool getLocked( void ) const { return locked; }
void setLocked( bool value );
// UI and replication
CoordinateFrame getFrameInPart() const;
void setFrameInPart( const CoordinateFrame& frame );
CoordinateFrame getFrameInWorld() const;
// UI and scripting
Vector3 getPivotInPart() const;
void setPivotInPart( const Vector3& pivot );
Vector3 getPivotInWorld(void) const;
Vector3 getEulerAnglesInPart() const;
void setEulerAnglesInPart( const Vector3& v );
Vector3 getEulerAnglesInWorld() const;
Vector3 getAxisInPart( void ) const;
Vector3 getAxisInWorld(void) const;
Vector3 getSecondaryAxisInPart( void ) const;
Vector3 getSecondaryAxisInWorld(void) const;
CoordinateFrame getParentFrame() const;
// Only for scripting
void setAxes( Vector3 axis, Vector3 secondaryAxis );
// Hidden from API as it has side effects
// Used only by AttachmentTool
void setAxisInPart( Vector3 axis );
virtual float intersectAdornWithRay( const RbxRay& r );
#ifdef RBX_ATTACHMENT_LOCKING
// disabled because not streaming/replication safe
static const Reflection::PropDescriptor<Attachment, bool> prop_Locked;
#endif
// Rendering
enum SelectState
{
SelectState_None = 0,
SelectState_Normal = 1,
SelectState_Hovered = 2,
SelectState_Paired = 4,
SelectState_Hidden = 8
};
void render3dToolAdorn(Adorn* adorn, Attachment::SelectState selectState);
void render3dAdorn(Adorn* adorn) override;
private:
// Hidden from API for having order dependency issues
// This might change the secondary axis in order to keep it orthogonal to the axis
void setAxisInPartInternal( const Vector3& axis );
// This will not change the axis, but will project the secondary axis onto the orthogonormal circle to the axis
void setSecondaryAxisInPartInternal( const Vector3& axis );
void setOrientationInPartInternal( const Matrix3& o );
Matrix3 getOrientationInPart( ) const;
Matrix3 getOrientationInWorld( ) const;
};
} // namespace
#endif
+24
View File
@@ -0,0 +1,24 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/Hopper.h"
#include "Script/IScriptFilter.h"
namespace RBX {
extern const char *const sBackpack;
class Backpack
: public DescribedCreatable<Backpack, Hopper, sBackpack>
, public IScriptFilter
{
private:
// IScriptOwner
/*override*/ bool scriptShouldRun(BaseScript* script);
public:
Backpack();
};
} // namespace
+86
View File
@@ -0,0 +1,86 @@
#pragma once
#include "V8Tree/Service.h"
#include "V8DataModel/PartInstance.h"
namespace RBX {
extern const char *const sBadgeService;
class BadgeService
: public DescribedCreatable<BadgeService, Instance, sBadgeService, Reflection::ClassDescriptor::INTERNAL>
, public Service
{
private:
std::string awardBadgeUrl;
std::string hasBadgeUrl;
std::string isBadgeDisabledUrl;
std::string isBadgeLegalUrl;
int placeId;
int cooldownTime;
boost::recursive_mutex badgeAwardSync;
std::map<int, std::set<int> > badgeAwardCache;
boost::recursive_mutex badgeQuerySync;
std::map<int, std::set<int> > badgeQueryCache;
boost::recursive_mutex badgeIsDisabledSync;
std::map<int, bool> badgeIsDisabledCache;
boost::recursive_mutex badgeIsLegalSync;
std::map<int, bool> badgeIsLegalCache;
struct HotUserHasBadge
{
int userId;
int badgeId;
RBX::Time expiration;
HotUserHasBadge(int userId, int badgeId, int cooldownTime);
bool expired() const;
};
std::list<HotUserHasBadge> hotBadges;
bool isHasBadgeHot(int userId, int badgeId);
public:
BadgeService();
~BadgeService()
{}
rbx::remote_signal<void(std::string, int, int)> badgeAwardedSignal;
void userHasBadge(int userId, int badgeId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void awardBadge(int userId, int badgeId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void isDisabled(int badgeId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void isLegal(int badgeId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void setPlaceId(int placeId);
void setHasBadgeCooldown(int seconds);
void setAwardBadgeUrl(std::string);
void setHasBadgeUrl(std::string);
void setIsBadgeDisabledUrl(std::string);
void setIsBadgeLegalUrl(std::string);
private:
static void hasBadgeResultHelper(weak_ptr<BadgeService>, int userId, int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void hasBadgeResult(int userId, int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
static void awardBadgeResultHelper(weak_ptr<BadgeService>, int userId, int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void awardBadgeResult(int userId, int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
static void isDiabledResultHelper(weak_ptr<BadgeService>, int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void isDisabledResult(int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
static void isLegalResultHelper(weak_ptr<BadgeService>, int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void isLegalResult(int badgeId, std::string* response, std::exception* err,
boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
};
}
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <boost/weak_ptr.hpp>
#include "v8datamodel/DataModel.h"
#include "rbx/rbxTime.h"
#include "rbx/TaskScheduler.h"
#include "rbx/TaskScheduler.Job.h"
#include "util/IMetric.h"
namespace RBX {
class View;
// This is the base class for all Rendering Jobs. All rendering jobs will inherit from this.
class BaseRenderJob : public DataModelJob
{
protected:
Time lastRenderTime;
volatile bool isAwake;
double minFrameRate;
double maxFrameRate;
public:
BaseRenderJob(double minFrameRate, double maxFrameRate, boost::shared_ptr<DataModel> dataModel );
virtual void wake();
virtual bool tryJobAgain();
virtual bool isCyclicExecutiveJob();
virtual Time::Interval timeSinceLastRender() const;
virtual Job::Error error(const Stats& stats);
//virtual RBX::TaskScheduler::StepResult stepDataModelJob(const Stats&);
virtual TaskScheduler::StepResult step(const Stats& stats);
};
}
@@ -0,0 +1,60 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/PartInstance.h"
namespace RBX {
extern const char* const sFormFactorPart;
class FormFactorPart
: public DescribedNonCreatable<FormFactorPart, PartInstance, sFormFactorPart>
{
typedef DescribedNonCreatable<FormFactorPart, PartInstance, sFormFactorPart> Super;
public:
/*override*/ virtual FormFactor getFormFactor() const { return formFactor; }
void setFormFactorUi(FormFactor value);
void setFormFactorXml(FormFactor value);
FormFactorPart();
virtual ~FormFactorPart();
/* override */ void readProperty(const XmlElement* propertyElement, IReferenceBinder& binder);
protected:
virtual void validateFormFactor(FormFactor& value) {}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
extern const char* const sBasicPart;
class BasicPartInstance
: public DescribedCreatable<BasicPartInstance, FormFactorPart, sBasicPart>
{
private:
/*override*/ void validateFormFactor(FormFactor& value);
public:
static const Reflection::EnumPropDescriptor<BasicPartInstance, LegacyPartType> prop_shapeXml;
BasicPartInstance();
virtual ~BasicPartInstance();
/*override*/ virtual bool hasThreeDimensionalSize();
void setLegacyPartTypeUi(LegacyPartType _type);
void setLegacyPartTypeXml(LegacyPartType _type);
/*override*/ virtual PartType getPartType() const;
LegacyPartType getLegacyPartType() const {return legacyPartType; }
};
} // namespace
+29
View File
@@ -0,0 +1,29 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "DataModelMesh.h"
namespace RBX
{
extern const char* const sBevelMesh;
class BevelMesh
: public DescribedNonCreatable<BevelMesh, DataModelMesh, sBevelMesh>
{
protected :
float bevel;
float roundness;
float bulge; // TODO : note, quick hack putting it in here.
public:
BevelMesh();
const float getRoundness() const;
void setRoundness(const float roundness);
const float getBevel() const;
void setBevel(const float bevel);
const float getBulge() const;
void setBulge(const float bulge);
};
}
+117
View File
@@ -0,0 +1,117 @@
#pragma once
#include "V8DataModel/GuiBase2d.h"
#include "Util/UDim.h"
#include "util/SteppedInstance.h"
#include "V8DataModel/GuiLayerCollector.h"
#include "V8DataModel/ModelInstance.h"
#include "V8DataModel/PartInstance.h"
namespace RBX {
class PartInstance;
class ViewportBillboarder;
extern const char* const sAdornmentGui;
//A core window on which other windows are created
//Ugh: this component is also a "PartAdornment", but we can't easily derive from both Adornment and GuiBase2d, resolve later.
class BillboardGui
: public DescribedCreatable<BillboardGui, GuiLayerCollector, sAdornmentGui>
, public IStepped
{
private:
typedef DescribedCreatable<BillboardGui, GuiLayerCollector, sAdornmentGui> Super;
std::auto_ptr<ViewportBillboarder> viewportBillboarder;
public:
BillboardGui();
/////////////////////////////////////////////////////////////
// Instance
//
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ bool processMeAndDescendants() const {return false;}
const Instance* getAdornee() const { return adornee.lock().get(); }
Instance* getAdornee() { return adornee.lock().get(); }
void setAdornee(Instance* value);
Instance* getAdorneeDangerous() const { return adornee.lock().get(); }
const Vector3& getStudsOffset() const;
void setStudsOffset(const Vector3& value);
const Vector3& getExtentsOffset() const;
void setExtentsOffset(const Vector3& value);
const Vector2& getSizeOffset() const;
void setSizeOffset(const Vector2& value);
UDim2 getSize() const;
void setSize(UDim2 value);
bool getAlwaysOnTop() const;
void setAlwaysOnTop(bool value);
bool getActive() const { return active; }
void setActive(bool value);
bool getEnabled() const { return enabled; }
void setEnabled(bool value);
void setRenderFunction(boost::function<void(BillboardGui*, Adorn*)> func);
Instance* getPlayerToHideFrom() const { return playerToHideFrom.lock().get(); }
void setPlayerToHideFrom(Instance* value);
private:
boost::shared_ptr<Instance> getPart() const;
boost::function<void(BillboardGui*, Adorn*)> adornFunc;
// reflected state
Vector3 partExtentRelativeOffset;
Vector3 partStudsOffset;
Vector2 billboardSizeRelativeOffset;
UDim2 billboardSize;
bool alwaysOnTop;
bool enabled;
bool active;
// dynamic state
bool visibleAndValid;
CoordinateFrame projectionFrame;
Rect2D viewport;
// reflected state
boost::weak_ptr<Instance> playerToHideFrom;
boost::weak_ptr<Instance> adornee;
////////////////////////////////////////////////////////////////////////////////////
//
// Instance
/*override*/ void onAncestorChanged(const AncestorChanged& event);
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider) {
Super::onServiceProvider(oldProvider, newProvider);
onServiceProviderIStepped(oldProvider, newProvider);
}
////////////////////////////////////////////////////////////////////////////////////
//
// IAdornable
/*override*/ bool shouldRender3dSortedAdorn() const;
/*override*/ void render3dSortedAdorn(Adorn* adorn);
/*override*/ Vector3 render3dSortedPosition() const;
/*override*/ bool isVisible(const Rect2D& rect) const { return true; }
////////////////////////////////////////////////////////////////////////////////////
//
// GuiTarget
/*override*/ bool canProcessMeAndDescendants() const;
/*override*/ GuiResponse process(const shared_ptr<InputObject>& event);
// IStepped
virtual void onStepped(const Stepped& event);
void calcAdornPlacement(Instance* part, CoordinateFrame& cframe, Vector3& size) const;
};
}
+66
View File
@@ -0,0 +1,66 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "v8tree/Instance.h"
namespace RBX {
// Summary: A simple class that exposes a configurable function.
// Usage: It allows scripts to expose their functions
extern const char* const sBindableFunction;
class BindableFunction : public DescribedCreatable<BindableFunction, Instance, sBindableFunction>
{
struct Invocation
{
shared_ptr<const Reflection::Tuple> arguments;
boost::function<void(shared_ptr<const Reflection::Tuple>)> resumeFunction;
boost::function<void(std::string)> errorFunction;
};
typedef std::queue<Invocation> Queue;
Queue queue;
public:
BindableFunction():DescribedCreatable<BindableFunction, Instance, sBindableFunction>("Function") {}
void invoke(shared_ptr<const Reflection::Tuple> arguments, boost::function<void(shared_ptr<const Reflection::Tuple>)> resumeFunction, boost::function<void(std::string)> errorFunction);
typedef boost::function<void (shared_ptr<const Reflection::Tuple>, boost::function<void(shared_ptr<const Reflection::Tuple>)>, boost::function<void(std::string)>)> OnInvokeCallback;
OnInvokeCallback onInvoke;
void processQueue(const OnInvokeCallback& oldValue);
/*override*/ bool askSetParent(const Instance* instance) const;
};
#if 0
// Summary: A simple class that exposes a property
// Usage: It allows scripts to expose their properties
extern const char* const sPropertyInstance;
class PropertyInstance : public DescribedCreatable<PropertyInstance, Instance, sPropertyInstance>
{
public:
PropertyInstance():DescribedCreatable<PropertyInstance, Instance, sPropertyInstance>("Property") {}
rbx::signal<void(Reflection::Variant)> valueChanged;
boost::function<Reflection::Variant()> getCallback;
boost::function<void(Reflection::Variant)> setCallback;
Reflection::Variant getValue();
void setValue(const Reflection::Variant& value);
void fireValueChanged();
};
#endif
// Summary: A simple class that exposes a fire-able event.
// Usage: It allows scripts to expose their events
extern const char* const sBindableEvent;
class BindableEvent : public DescribedCreatable<BindableEvent, Instance, sBindableEvent>
{
public:
BindableEvent():DescribedCreatable<BindableEvent, Instance, sBindableEvent>("Event") {}
rbx::signal<void(shared_ptr<const Reflection::Tuple>)> event;
void fire(shared_ptr<const Reflection::Tuple> arguments);
/*override*/ bool askSetParent(const Instance* instance) const;
};
} // namespace RBX
+16
View File
@@ -0,0 +1,16 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "BevelMesh.h"
namespace RBX
{
extern const char* const sBlockMesh;
class BlockMesh
: public DescribedCreatable<BlockMesh, BevelMesh, sBlockMesh>
{
public:
BlockMesh(){}
};
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "v8datamodel/InputObject.h"
#include "v8datamodel/Lighting.h"
#include "PostEffect.h"
namespace RBX {
extern const char* const sBlurEffect;
class BlurEffect : public DescribedCreatable<BlurEffect, PostEffect, sBlurEffect, Reflection::ClassDescriptor::PERSISTENT>
{
private:
typedef DescribedCreatable<BlurEffect, PostEffect, sBlurEffect, Reflection::ClassDescriptor::PERSISTENT> Super;
public:
BlurEffect();
void setSize(int value);
int getSize() const { return std::min(56, std::max(0, Size)); }
bool isActive;
protected:
int Size;
};
}
@@ -0,0 +1,62 @@
/* Copyright 2014 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "Util/BinaryString.h"
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include "V8DataModel/FlyweightService.h"
#include <boost/unordered_map.hpp>
#include "Value.h"
namespace RBX
{
class PartOperation;
class CSGMesh;
extern const char *const sCSGDictionaryService;
class CSGDictionaryService
: public DescribedCreatable<CSGDictionaryService, FlyweightService, sCSGDictionaryService, Reflection::ClassDescriptor::PERSISTENT, Security::Roblox>
{
protected:
typedef DescribedCreatable<CSGDictionaryService, FlyweightService, sCSGDictionaryService, Reflection::ClassDescriptor::PERSISTENT, Security::Roblox> Super;
typedef boost::unordered_map<std::string, boost::shared_ptr<CSGMesh> > CSGMeshMap;
CSGMeshMap cachedBREPMeshMap;
CSGMeshMap cachedMeshMap;
void reparentChildData(shared_ptr<RBX::Instance> sharedInstance);
virtual void refreshRefCountUnderInstance(RBX::Instance* instance);
boost::shared_ptr<CSGMesh> insertMesh(const std::string key, const RBX::BinaryString& meshData);
boost::shared_ptr<CSGMesh> insertCachedMesh(const std::string key, const RBX::BinaryString& meshData);
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
public:
CSGDictionaryService();
void storeData(PartOperation& partOperation, bool forceIncrement = false);
void retrieveData(PartOperation& partOperation);
void storeAllDescendants(shared_ptr<RBX::Instance> instance);
void retrieveAllDescendants(shared_ptr<RBX::Instance> instance);
void reparentAllChildData();
void insertMesh(PartOperation& partOperation);
boost::shared_ptr<CSGMesh> getMesh(PartOperation& partOperation);
boost::shared_ptr<CSGMesh> getCachedMesh(PartOperation& partOperation);
void retrieveMeshData(PartOperation& partOperation);
void storePhysicsData(PartOperation& partOperation, bool forceIncrement = false);
void retrievePhysicsData(PartOperation& partOperation);
void onWorkspaceLoaded();
};
}
+127
View File
@@ -0,0 +1,127 @@
/* Copyright 2014 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "g3d/platform.h"
#include "g3d/g3dmath.h"
#include "G3D/Vector2.h"
#include "G3D/Vector3.h"
#include "G3D/Vector4.h"
#include "G3D/Color4uint8.h"
#include "G3D/Color3uint8.h"
#include "G3D/CoordinateFrame.h"
#include "rbx/Debug.h"
namespace RBX
{
class CSGVertex
{
public:
G3D::Vector3 pos;
G3D::Vector3 normal;
G3D::Color4uint8 color;
G3D::Color4uint8 extra; // red = uv generation type
G3D::Vector2 uv;
G3D::Vector2 uvStuds;
G3D::Vector2 uvDecal;
G3D::Vector3 tangent;
G3D::Vector4 edgeDistances;
enum UVGenerationType
{
NO_UV_GENERATION = 0,
UV_BOX_X,
UV_BOX_Y,
UV_BOX_Z,
UV_BOX_X_NEG,
UV_BOX_Y_NEG,
UV_BOX_Z_NEG
};
CSGVertex(){;}
G3D::Vector2 generateUv(const Vector3& pos) const;
void generateUv();
};
class CSGMesh
{
public:
CSGMesh();
virtual ~CSGMesh();
virtual CSGMesh* clone() const;
const std::vector<CSGVertex>& getVertices() const { return vertices; }
const std::vector<unsigned int>& getIndices() const { return indices; }
const std::vector<unsigned>& getIndexRemap(unsigned idx) const { RBXASSERT(idx < 6); return decalIndexRemap[idx]; }
const std::vector<unsigned>& getVertexRemap(unsigned idx) const { RBXASSERT(idx < 6); return decalVertexRemap[idx];}
std::string createHash(const std::string salt = "") const;
bool isBadMesh() const { return badMesh; }
virtual bool isValid() const { return true; }
void set(const std::vector<CSGVertex>& vertices, const std::vector<unsigned int>& indices);
void clearMesh();
virtual void translate( const G3D::Vector3& translation ) {}
virtual void applyCoordinateFrame(G3D::CoordinateFrame cFrame) {}
virtual void applyTranslation(const G3D::Vector3& trans) {}
virtual void applyColor(const G3D::Vector3& color) {}
virtual void applyScale(const G3D::Vector3& size) {}
virtual void triangulate() {}
virtual bool newTriangulate() { return true;}
virtual void weldMesh(bool positionOnly = false) {}
virtual void buildBRep() {}
virtual bool unionMesh(const CSGMesh* a, const CSGMesh* b) { return false; }
virtual bool intersectMesh(const CSGMesh* a, const CSGMesh* b) { return false; }
virtual bool subractMesh(const CSGMesh* a, const CSGMesh* b) { return false; }
bool isNotEmpty() const;
std::string toBinaryString() const;
std::string toBinaryStringForPhysics() const;
bool fromBinaryString(const std::string& str);
virtual std::string getBRepBinaryString() const { return ""; }
virtual void setBRepFromBinaryString(const std::string& str) {}
virtual size_t clusterVertices( float resolution ) { return 0; }
virtual bool makeHalfEdges( std::vector< int>& vertexEdges ) { return true; }
virtual G3D::Vector3 extentsCenter() { G3D::Vector3 v; return v; }
virtual G3D::Vector3 extentsSize() { G3D::Vector3 v; return v; }
void computeDecalRemap();
protected:
int version;
int brepVersion;
bool badMesh;
std::vector<CSGVertex> vertices;
std::vector<unsigned int> indices;
std::vector<unsigned> decalVertexRemap[6];
std::vector<unsigned> decalIndexRemap[6];
};
class CSGMeshFactory
{
public:
virtual CSGMesh* createMesh();
static CSGMeshFactory* singleton();
static void set(CSGMeshFactory* factory);
};
}
@@ -0,0 +1,89 @@
#pragma once
#include <vector>
#include "V8Tree/Service.h"
#include "v8datamodel/ContentProvider.h"
#include "util/ContentProviderJob.h"
#include "util/ControlledLRUCache.h"
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
typedef boost::unordered_set<std::string> Set;
namespace RBX {
extern const char* const sCacheableContentProvider;
class CacheableContentProvider
: public DescribedNonCreatable<CacheableContentProvider, Instance, sCacheableContentProvider, RBX::Reflection::ClassDescriptor::RUNTIME_LOCAL>
, public Service
, public HeartbeatInstance
{
typedef DescribedNonCreatable<CacheableContentProvider, Instance, sCacheableContentProvider, RBX::Reflection::ClassDescriptor::RUNTIME_LOCAL> Super;
protected:
class CachedItem
{
public:
AsyncHttpQueue::RequestResult requestResult;
shared_ptr<void> data;
public:
CachedItem(shared_ptr<void> data = shared_ptr<void>(), AsyncHttpQueue::RequestResult result = AsyncHttpQueue::Waiting)
: data(data), requestResult(result)
{}
~CachedItem()
{
data.reset();
}
friend class CacheableContentProvider;
};
shared_ptr<ContentProviderJob> contentJob;
rbx::atomic<int> pendingRequests;
bool immediateMode;
boost::scoped_ptr< ConcurrentControlledLRUCache<std::string, boost::shared_ptr<CachedItem> > > lruCache;
boost::mutex failedCacheMutex;
Set failedCache;
public:
CacheableContentProvider(CacheSizeEnforceMethod enforceMethod, unsigned long size);
virtual ~CacheableContentProvider();
void setCacheSize(int size);
void setImmediateMode();
bool isRequestQueueEmpty() { return pendingRequests == 0; }
bool clearContent();
bool hasContent(const ContentId& id);
boost::shared_ptr<void> requestContent(const ContentId& id, float priority, bool markUsed, AsyncHttpQueue::RequestResult& result);
boost::shared_ptr<void> blockingRequestContent(const ContentId& id, bool markUsed);
boost::shared_ptr<void> fetchContent(const ContentId& id);
bool isAssetFailed(const ContentId& id);
// HeartbeatInstance
/*override*/ void onHeartbeat(const Heartbeat& event);
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
protected:
static void LoadContentCallbackHelper(boost::weak_ptr<CacheableContentProvider> cacheableContentProvider, AsyncHttpQueue::RequestResult result, std::istream* filestream, shared_ptr<const std::string> data, std::string id);
void LoadContentCallback(AsyncHttpQueue::RequestResult result, std::istream* filestream, shared_ptr<const std::string> data, std::string id);
static TaskScheduler::StepResult ProcessTaskHelper(boost::weak_ptr<CacheableContentProvider> weakCcp, const std::string& id, shared_ptr<const std::string> data);
virtual TaskScheduler::StepResult ProcessTask(const std::string& id, shared_ptr<const std::string> data) = 0;
static void ErrorTaskHelper(boost::weak_ptr<CacheableContentProvider> weakCcp, const std::string& id);
virtual void ErrorTask(const std::string& id);
bool isAssetContent(ContentId id);
void markContentFailed(const std::string& id);
AsyncHttpQueue::RequestResult getContentStatus(const std::string& id);
virtual void updateContent(const std::string& id, boost::shared_ptr<CachedItem> cachedItem);
};
}
+322
View File
@@ -0,0 +1,322 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "Util/G3DCore.h"
#include "Util/HeartbeatInstance.h"
#include <vector>
#include "RbxG3D/Frustum.h"
namespace RBX {
class ICameraOwner;
class CameraSubject;
class ContactManager;
class Primitive;
class NavKeys;
class Extents;
class ModelInstance;
class PartInstance;
class HitTestFilter;
extern const char* const sCamera;
class Camera : public DescribedCreatable<Camera, Instance, sCamera, Reflection::ClassDescriptor::PERSISTENT_LOCAL>
, public HeartbeatInstance
{
public:
rbx::signal<void()> interpolationFinishedSignal;
rbx::signal<void(bool)> firstPersonTransitionSignal;
rbx::signal<void(CoordinateFrame)> cframeChangedSignal;
// Warning - these enums are part of the XML - only append
enum CameraType { FIXED_CAMERA = 0,
ATTACH_CAMERA = 1, // maintain fixed position and rotation w.r.t target coordinate frame
WATCH_CAMERA = 2, // rotate to keep target in view
TRACK_CAMERA = 3, // translate to keep target in view
FOLLOW_CAMERA = 4, // rotate and translate to keep target in view
CUSTOM_CAMERA = 5,
LOCKED_CAMERA = 6,
NUM_CAMERA_TYPE = 7};
typedef enum {ZOOM_IN_OR_OUT, ZOOM_OUT_ONLY} ZoomType;
enum CameraMode
{
CAMERAMODE_CLASSIC = 0,
CAMERAMODE_LOCKFIRSTPERSON = 1
};
enum CameraPanMode
{
CAMERAPANMODE_CLASSIC = 0,
CAMERAPANMODE_EDGEBUMP = 1,
};
static float distanceDefault() {return 36.0f;} // grids
static float distanceMin() {return 0.5f;} // down from 4.0
static float distanceMax() {return 1000.0f;}
static float distanceMaxCharacter() {return 400.0f;}
static float distanceMinOcclude() {return 4.0f;}
static double interpolationSpeed() {return 5.0f;} // studs per second
static bool legalCameraCoord(const CoordinateFrame& c);
static float CameraKeyMoveFactor;
static float CameraMouseWheelMoveFactor;
static float CameraShiftKeyMoveFactor;
Camera();
~Camera() {}
// Yuck - called by Window code
void step(double elapsedTime);
void stepSubject();
void pushCameraHistoryStack();
std::pair<CoordinateFrame,CoordinateFrame> popCameraHistoryStack(bool backward);
void getHeadingElevationDistance(float& heading, float& elevation, float& distance);
bool isCharacterCamera() const;
bool isFirstPersonCamera() const; // hack for now - this should be in CameraSubject?? discuss
bool isPartInFrustum(const PartInstance& part) const;
bool isPartVisibleFast(const PartInstance& part, const ContactManager& contactManager, const HitTestFilter* filter = NULL) const; // uses only one ray to do check (can have inaccurate results, but takes 1/4 the time)
bool isLockedToFirstPerson() const;
CameraSubject* getCameraSubject();
const CameraSubject* getConstCameraSubject() const;
Instance* getCameraSubjectInstanceDangerous() const; // for reflection only
void setCameraSubject(Instance* newSubject);
void setCameraLerpGoals(const CoordinateFrame& cameraCoordValue, const CoordinateFrame& cameraFocusValue);
const CoordinateFrame& getCameraFocus() const { return cameraFocus; }
void setCameraFocus(const CoordinateFrame& value); // sets camera focus and camera focus goal
void setCameraFocusWithoutPropertyChange(const CoordinateFrame& value);
void setCameraFocusOnly(const CoordinateFrame& value); // sets camera focus
void setCameraFocusOnlyWithoutPropertyChange(const CoordinateFrame& value);
void setCameraFocusAndMaintainFocus(const CoordinateFrame& value, bool maintainFocusOnPoint);
const CoordinateFrame& getCameraCoordinateFrame() const {return cameraCoord;}
void setCameraCoordinateFrame(const CoordinateFrame& value);
CoordinateFrame getRenderingCoordinateFrame() const;
CoordinateFrame getRenderingCoordinateFrameLua() { return getRenderingCoordinateFrame(); }
bool getHeadLocked() const { return headLocked; }
void setHeadLocked(bool value);
CameraType getCameraType() const {return cameraType;}
void setCameraType(CameraType value);
bool canZoom(bool inwards) const;
bool canTilt(int up) const;
// Cursor Control
void onMousePan(const Vector2& wrapMouseDelta);
void onMouseTrack(const Vector2& wrapMouseDelta);
// Zoom
bool zoom(float in);
bool setDistanceFromTarget(float newDistance);
bool setDistanceFromTarget(float newDistance, CoordinateFrame& newCameraPos, const CoordinateFrame& newCameraFocus);
bool zoomExtents(); // of the world
void zoomExtents(const ModelInstance* model, ZoomType zoomType);
void zoomExtents(const Extents& extents, ZoomType zoomType);
void lerpToExtents(const Extents& extents);
// Pan
void panRadians(float angle);
void panUnits(int units);
void panSpeedRadians(float tilt);
float getPanSpeed(void) { return panSpeed; }
// Tilt
bool tiltRadians(float up);
bool tiltUnits(int up);
void tiltSpeedRadians(float tilt);
float getTiltSpeed(void) { return tiltSpeed; }
//
void setCameraPanMode(Camera::CameraPanMode mode);
Camera::CameraPanMode getCameraPanMode() const { return cameraPanMode; }
// LookAt
void lookAt(const Vector3& point, bool lerpCamera);
void setImageServerViewNoLerp(const CoordinateFrame& modelCoord);
// Fly
void doFly(const NavKeys& nav, int steps);
// Camera History
void stepCameraHistoryForward();
void stepCameraHistoryBackward();
// Util
static float getNewZoomDistance(float currentDistance, float in);
bool hasClientPlayer() const;
// Clipping plane, *not* imaging plane. Returns a negative z-value.
float nearPlaneZ() const;
// Returns a negative z-value.
inline float farPlaneZ() const {
return -5e3f;
}
inline float getFieldOfView() const {
return fieldOfView;
}
inline float getFieldOfViewDegrees() const {
return G3D::toDegrees(fieldOfView);
}
void setFieldOfViewDegrees(float value);
inline float getRoll() const{
return roll;
}
void setRoll(float value);
float getRollSlow();
// Taken from RbxCamera, a derivative of the G3D Camera.
// Returns the image plane depth, <I>s'</I>, given the current field
// of view for film of dimensions width x height. See
// setImagePlaneDepth for a discussion of worldspace values width and height.
float getImagePlaneDepth() const;
// Returns the Camera space width of the viewport.
float getViewportWidth() const;
// Returns the Camera space height of the viewport.
float getViewportHeight() const;
// Taken from RbxCamera, a derivative of the G3D Camera.
// Projects a world space point onto a width x height screen. The
// returned coordinate uses pixmap addressing: x = right and y =
// down. The resulting z value is <I>rhw</I>.
// If the point is behind the camera, Vector3::inf() is returned.
Vector3 project(const Vector3& point) const;
shared_ptr<const Reflection::Tuple> projectLua(Vector3 point);
shared_ptr<const Reflection::Tuple> projectViewportLua(Vector3 point);
// Taken from RbxCamera, a derivative of the G3D Camera.
// Returns the world space ray passing through the center of pixel
// (x, y) on the image plane. The pixel x and y axes are opposite
// the 3D object space axes: (0,0) is the upper left corner of the screen.
// They are in viewport coordinates, not screen coordinates.
// Integer (x, y) values correspond to
// the upper left corners of pixels. If you want to cast rays
// through pixel centers, add 0.5 to x and y.
RbxRay worldRay(float x, float y, float depth = 0.0f) const;
RbxRay worldRayLua(float x, float y, float depth);
RbxRay worldRayViewportLua(float x, float y, float depth);
// Taken from RbxCamera, a derivative of the G3D Camera.
// Returns the world space view frustum, which is a truncated pyramid describing
// the volume of space seen by this camera.
void frustum(const float farPlaneZ, RBX::Frustum& fr) const;
RBX::Frustum frustum() const;
const CoordinateFrame& coordinateFrame() const;
Vector2int16 getViewport() const { return viewport; }
void setViewport(Vector2int16 newViewport);
// Calculates the dot product of camera direction and point. Useful for
// half space test or getting angle between the 2
float dot(const Vector3& point) const;
void beginCameraInterpolation(CoordinateFrame endPos, CoordinateFrame endFocus, float duration);
Vector4 projectPointToScreen(const Vector3& point) const;
private:
typedef DescribedCreatable<Camera, Instance, sCamera, Reflection::ClassDescriptor::PERSISTENT_LOCAL> Super;
enum CameraInterpolation
{
CAM_INTERPOLATION_CONSTANT_TIME,
CAM_INTERPOLATION_CONSTANT_SPEED,
CAM_INTERPOLATION_NONE,
};
void updateFocus();
bool isEditMode() const;
bool characterZoom(float in);
bool nonCharacterZoom(float in);
void tryZoomExtents(const Extents& extents);
float cameraToFocusDistance() const {
return (cameraCoord.translation - cameraFocus.translation).magnitude();
}
void setHeadingElevationDistance(float heading, float elevation, float distance);
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider) {
Super::onServiceProvider(oldProvider, newProvider);
onServiceProviderHeartbeatInstance(oldProvider, newProvider); // hooks up heartbeat
}
void fixedSpeedInterpolateCamera(double elapsedTime);
void zoomOut(CoordinateFrame& cameraPos, CoordinateFrame& cameraFocus, float currentFocusToCameraDistance);
Matrix4 getProjectionPerspective() const;
void stopInterpolation();
void signalInterpolationDone();
// HeartbeatInstance
/*override*/ void onHeartbeat(const Heartbeat& event);
CameraInterpolation camInterpolation;
CoordinateFrame cameraCoord; // Where is the camera
CoordinateFrame cameraFocus; // Looking at what?
CoordinateFrame cameraCoordGoal; // Where we want to be (used for camera transitions)
CoordinateFrame cameraFocusGoal; // Where we want to look (used for camera transitions)
CoordinateFrame cameraCoordPrev; // Where we used to be (used for camera interpolation)
CoordinateFrame cameraFocusPrev; // Where we used to look (used for camera interpolation)
G3D::Vector3 cameraUpDirPrev;
float interpolationDuration; // Time in seconds to interpolate position and focus; < 0 for constant speed interpolation
mutable float interpolationTime; // Time in seconds that we have been doing the current interpolation
bool headLocked;
CameraType cameraType;
shared_ptr<Instance> cameraSubject; // Guaranteed to be a CameraSubject
float fieldOfView;
float roll;
Vector2int16 viewport;
float panSpeed;
float tiltSpeed;
CameraPanMode cameraPanMode;
// The image plane depth corresponding to a vertical field of
// view, where the film size is 1x1.
float imagePlaneDepth;
bool hasFocalObject;
ICameraOwner* getCameraOwner();
std::vector< std::pair<CoordinateFrame,CoordinateFrame> > cameraHistoryStack;
int currentCameraHistoryPosition;
double lastHistoryPushTime;
};
} // namespace RBX
+136
View File
@@ -0,0 +1,136 @@
#pragma once
#include "V8Tree/Service.h"
#include "Util/Runstateowner.h"
#include "Voxel/Cell.h"
#include "Voxel/CellChangeListener.h"
#include "Util/SpatialRegion.h"
#include <queue>
#include "Voxel2/GridListener.h"
namespace RBX {
class DataModel;
class MegaClusterInstance;
extern const char* const sChangeHistoryService;
class ChangeHistoryService
: public DescribedCreatable<ChangeHistoryService, Instance, sChangeHistoryService, Reflection::ClassDescriptor::INTERNAL>
, public Service
, public Voxel::CellChangeListener
, public Voxel2::GridListener
{
private:
typedef DescribedCreatable<ChangeHistoryService, Instance, sChangeHistoryService, Reflection::ClassDescriptor::INTERNAL> Super;
DataModel* dataModel;
class Item;
class Waypoint;
shared_ptr<MegaClusterInstance> megaClusterInstance;
Waypoint* recording;
typedef std::list<Waypoint*> Waypoints; // must be a list and not a vector because we maintain iterators after reallocs
Waypoints waypoints;
Waypoints::iterator playWaypoint; // playing nextWaypoint is a "redo"
Waypoints::iterator unplayWaypoint; // unplaying unplayWaypoint is an "undo"
Waypoints::iterator runStartWaypoint; // unplaying up to runStartWaypoint is a "reset"
bool playing;
bool enabled;
int dataSize;
shared_ptr<RunService> runService;
shared_ptr<Instance> statsItem;
rbx::signals::scoped_connection itemAddedConnection;
rbx::signals::scoped_connection itemRemovedConnection;
rbx::signals::scoped_connection itemChangedConnection;
rbx::signals::scoped_connection runTransitionConnection;
public:
static const int minWaypoints = 3;
static const int maxWaypoints = 250;
static const int maxMemoryUsage = 250 * 1024 * 1024;
typedef enum {
Aggregate, // Don't allow waypoints while running. All changes are recorded and made part of the reset waypoint
Snapshot, // When recording waypoints while running, take a snapshot of positions and velocities
Hybrid // When recording waypoints while running, ignore unrelated position and velocity changes
} RuntimeUndoBehavior;
static RuntimeUndoBehavior runtimeUndoBehavior;
ChangeHistoryService();
~ChangeHistoryService();
static void requestWaypoint(const char* name, const Instance* context);
void resetBaseWaypoint();
void clearWaypoints();
void setEnabled(bool state);
bool isEnabled() const { return enabled; }
void requestWaypoint(const char* name);
void requestWaypoint2(std::string name) { requestWaypoint(name.c_str()); }
// TODO: rename play-->redo unplay-->undo???
bool getPlayWaypoint(std::string& name, int steps = 0) const;
bool getUnplayWaypoint(std::string& name, int steps = 0) const;
bool canPlay() const { std::string name; return getPlayWaypoint(name); }
bool canUnplay() const { std::string name; return getUnplayWaypoint(name); }
// returns a tuple: bool state, [string name]
shared_ptr<const Reflection::Tuple> canUnplay2();
shared_ptr<const Reflection::Tuple> canPlay2();
//std::string getPlayName() const { std::string name; getPlayWaypoint(name); return name; }
//std::string getUnplayName() const { std::string name; getUnplayWaypoint(name); return name; }
void play();
void playLua();
void unplay();
void unplayLua();
//to show progress dialog in studio
boost::function<void(boost::function<void()>, std::string)> withLongRunningOperation;
bool isResetEnabled() const;
void reset();
int getWaypointDataSize() const { return dataSize; }
int getWaypointCount() const { return waypoints.size(); }
rbx::signal<void()> waypointChangedSignal;
rbx::signal<void(std::string)> undoSignal;
rbx::signal<void(std::string)> redoSignal;
MegaClusterInstance* getTerrain() const { return megaClusterInstance.get(); }
protected:
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
private:
void attach();
void dettach();
void trimWaypoints();
void mergeFirstTwoWaypoints();
void computeDataSize();
virtual void onItemAdded(shared_ptr<RBX::Instance> item);
virtual void onItemRemoved(shared_ptr<RBX::Instance> item);
virtual void onItemChanged(shared_ptr<RBX::Instance> item, const Reflection::PropertyDescriptor* descriptor);
bool isRecordable(Instance* instance);
/*override*/ virtual void terrainCellChanged(const Voxel::CellChangeInfo& cell);
/*override*/ virtual void onTerrainRegionChanged(const Voxel2::Region& region);
void setCell(const SpatialRegion::Id& chunkPos, const Vector3int16& cellInChunk,
Voxel::Cell detail, Voxel::CellMaterial material);
typedef enum { Accept, Reject } CheckResult;
CheckResult checkSettingWaypoint();
void onRunTransition(RunTransition event);
void setWaypoint(const char* name);
void setRunWaypoint();
void reportMissedPhysicsChanges(shared_ptr<RBX::Instance> instance);
};
}
@@ -0,0 +1,148 @@
#pragma once
#include "V8DataModel/GlobalSettings.h"
#include "Util/BrickColor.h"
#include "V8DataModel/PartInstance.h"
#include "V8DataModel/IModelModifier.h"
#include "Util/TextureId.h"
namespace RBX {
class Humanoid;
extern const char* const sCharacterAppearance;
class RBXBaseClass CharacterAppearance
:public DescribedNonCreatable<CharacterAppearance, Instance, sCharacterAppearance>
,public IModelModifier
{
private:
typedef Instance Super;
public:
virtual void apply();
protected:
virtual void onAncestorChanged(const AncestorChanged& event);
virtual bool askSetParent(const Instance* instance) const;
private:
virtual void applyByMyself(Humanoid* humanoid) = 0;
};
class LegacyCharacterAppearance
: public CharacterAppearance
{
private:
typedef CharacterAppearance Super;
public:
// Hack: This apply() function is ugly, but necessary because
// this class changes properties of other objects (like
// Part colors and Decal images). However, to avoid
// crosstalk the apply function should only do something
// in the backend case.
/*override*/ void apply();
};
// Old-style T-shirts
extern const char *const sShirtGraphic;
class ShirtGraphic
: public DescribedCreatable<ShirtGraphic, LegacyCharacterAppearance, sShirtGraphic>
{
public:
TextureId graphic;
static Reflection::BoundProp<TextureId> prop_Graphic;
ShirtGraphic();
protected:
/*override*/ void applyByMyself(Humanoid* humanoid);
private:
void dataChanged(const Reflection::PropertyDescriptor&) {
CharacterAppearance::apply();
}
};
extern const char *const sClothing;
class Clothing
: public DescribedNonCreatable<Clothing, CharacterAppearance, sClothing>
{
friend class CharacterAppearance;
public:
TextureId outfit1;
TextureId outfit2;
static Reflection::BoundProp<TextureId> prop_outfit1;
static Reflection::BoundProp<TextureId> prop_outfit2;
Clothing();
virtual TextureId getTemplate() const { RBXASSERT(false); return NULL; }
protected:
/*override*/ void applyByMyself(Humanoid* humanoid);
void dataChanged(const Reflection::PropertyDescriptor&) {
CharacterAppearance::apply();
}
};
extern const char *const sPants;
class Pants
: public DescribedCreatable<Pants, Clothing, sPants>
{
public:
Pants();
static Reflection::PropDescriptor<Pants, TextureId> prop_PantsTemplate;
TextureId getTemplate() const { return outfit1; }
void setTemplate(TextureId value);
};
extern const char *const sShirt;
class Shirt
: public DescribedCreatable<Shirt, Clothing, sShirt>
{
public:
Shirt();
static Reflection::PropDescriptor<Shirt, TextureId> prop_ShirtTemplate;
TextureId getTemplate() const { return outfit2; }
void setTemplate(TextureId value);
};
extern const char *const sBodyColors;
class BodyColors
: public DescribedCreatable<BodyColors, LegacyCharacterAppearance, sBodyColors>
{
BrickColor headColor;
BrickColor leftArmColor;
BrickColor rightArmColor;
BrickColor torsoColor;
BrickColor leftLegColor;
BrickColor rightLegColor;
public:
static Reflection::BoundProp<BrickColor> prop_HeadColor;
static Reflection::BoundProp<BrickColor> prop_LeftArmColor;
static Reflection::BoundProp<BrickColor> prop_RightArmColor;
static Reflection::BoundProp<BrickColor> prop_TorsoColor;
static Reflection::BoundProp<BrickColor> prop_LeftLegColor;
static Reflection::BoundProp<BrickColor> prop_RightLegColor;
BodyColors();
private:
virtual void applyByMyself(Humanoid* humanoid);
void dataChanged(const Reflection::PropertyDescriptor&) {
CharacterAppearance::apply();
}
};
extern const char *const sSkin;
class Skin
: public DescribedCreatable<Skin, LegacyCharacterAppearance, sSkin>
{
BrickColor skinColor;
public:
static Reflection::BoundProp<BrickColor> prop_skinColor;
Skin();
private:
virtual void applyByMyself(Humanoid* humanoid);
void dataChanged(const Reflection::PropertyDescriptor&) {
CharacterAppearance::apply();
}
};
} // namespace
+53
View File
@@ -0,0 +1,53 @@
#pragma once
#include "Util/TextureId.h"
#include "Util/MeshId.h"
#include "CharacterAppearance.h"
namespace RBX {
class Humanoid;
extern const char *const sCharacterMesh;
class CharacterMesh
: public DescribedCreatable<CharacterMesh, CharacterAppearance, sCharacterMesh>
{
public:
enum BodyPart
{
HEAD = 0,
TORSO = 1,
LEFTARM = 2,
RIGHTARM = 3,
LEFTLEG = 4,
RIGHTLEG = 5
};
CharacterMesh();
BodyPart getBodyPart() const { return bodyPart; }
void setBodyPart(BodyPart value);
int baseTextureAssetId;
int overlayTextureAssetId;
int meshAssetId;
static Reflection::BoundProp<int> prop_baseTextureAssetId;
static Reflection::BoundProp<int> prop_overlayTextureAssetId;
static Reflection::BoundProp<int> prop_meshAssetId;
TextureId getBaseTextureId() const;
TextureId getOverlayTextureId() const;
MeshId getMeshId() const;
protected:
virtual void applyByMyself(Humanoid* humanoid);
/*override*/ void onPropertyChanged(const Reflection::PropertyDescriptor& descriptor);
private:
BodyPart bodyPart;
};
} // namespace
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include "V8Tree/Service.h"
#include "V8Tree/Instance.h"
namespace RBX {
class PartInstance;
extern const char *const sChatService ;
class ChatService
: public DescribedCreatable<ChatService, Instance, sChatService, Reflection::ClassDescriptor::INTERNAL>
, public Service
{
private:
void gotFilteredStringSuccess(std::string response, Network::Player* player, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void gotFilterStringError(std::string error, boost::function<void(std::string)> errorFunction);
public:
enum ChatColor
{
CHAT_BLUE,
CHAT_GREEN,
CHAT_RED
};
ChatService();
void chat(shared_ptr<Instance> instance, std::string message, ChatService::ChatColor chatColor);
void filterStringForPlayer(std::string stringToFilter, shared_ptr<Instance> playerToFilterFor, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
rbx::remote_signal<void(shared_ptr<Instance>, std::string, ChatService::ChatColor)> chattedSignal;
};
}
+60
View File
@@ -0,0 +1,60 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "GfxBase/IAdornable.h"
#include "V8DataModel/PartInstance.h"
#include "V8DataModel/ModelInstance.h"
namespace RBX {
namespace Network {
class Players;
class Player;
}
class PartInstance;
class ModelInstance;
extern const char* const sClickDetector;
class ClickDetector : public DescribedCreatable<ClickDetector, Instance, sClickDetector>
, public IAdornable
{
private:
int cycle;
float maxActivationDistance; // max distance a character can be from the button and still raise events
shared_ptr<Instance> lastHoverPart;
// IAdornable
/*override*/ bool shouldRender3dAdorn() const {return true;}
/*override*/ void render3dAdorn(Adorn* adorn);
public:
ClickDetector();
virtual ~ClickDetector() {}
void fireMouseClick(float distance, RBX::Network::Player* player);
void fireMouseHover(RBX::Network::Player* player);
void fireMouseHoverLeave(RBX::Network::Player* player);
static Reflection::BoundProp<float> propMaxActivationDistance;
shared_ptr<Instance> getLastHoverPart() { return lastHoverPart; }
bool updateLastHoverPart(shared_ptr<Instance> newHover, RBX::Network::Player* player);
rbx::remote_signal<void(shared_ptr<Instance>)> mouseClickSignal;
rbx::remote_signal<void(shared_ptr<Instance>)> mouseHoverSignal;
rbx::remote_signal<void(shared_ptr<Instance>)> mouseHoverLeaveSignal;
static int cycles() {return 30;}
float getMaxActivationDistance() {return maxActivationDistance;}
static bool isClickable(shared_ptr<PartInstance> part, float distanceToCharacter, bool raiseClickedEvent, RBX::Network::Player* player);
static bool isHovered(PartInstance *part, float distanceToCharacter, bool raiseHoveredEvent, RBX::Network::Player* player);
static void stopHover(shared_ptr<PartInstance> part, RBX::Network::Player* player);
/* override */ bool askSetParent(const Instance* parent) const {return (Instance::fastDynamicCast<PartInstance>(parent) != NULL) || (Instance::fastDynamicCast<ModelInstance>(parent) != NULL);}
/* override */ bool askAddChild(const Instance* instance) const {return true;}
};
} // namespace RBX
@@ -0,0 +1,37 @@
#pragma once
#include "V8Tree/Service.h"
#include <queue>
namespace RBX {
extern const char* const sCollectionService;
class CollectionService
: public DescribedNonCreatable<CollectionService, Instance, sCollectionService>
, public Service
{
public:
CollectionService();
rbx::signal<void(shared_ptr<Instance>)> itemAddedSignal;
rbx::signal<void(shared_ptr<Instance>)> itemRemovedSignal;
shared_ptr<const Instances> getCollection(std::string type);
shared_ptr<const Instances> getCollection(const Name& className);
template<class T>
shared_ptr<const Instances> getCollection()
{
return getCollection(T::classDescriptor());
}
void removeInstance(shared_ptr<Instance> instance);
void addInstance(shared_ptr<Instance> instance);
private:
// TODO: Lookup by const RBX::Name*
typedef std::map<std::string, shared_ptr<copy_on_write_ptr<Instances> > > CollectionMap;
CollectionMap collections;
};
}
@@ -0,0 +1,36 @@
#pragma once
#include "v8datamodel/InputObject.h"
#include "v8datamodel/Lighting.h"
#include "V8Tree/instance.h"
#include "PostEffect.h"
namespace RBX {
extern const char* const sColorCorrectionEffect;
class ColorCorrectionEffect : public DescribedCreatable<ColorCorrectionEffect, PostEffect, sColorCorrectionEffect, Reflection::ClassDescriptor::PERSISTENT>
{
private:
typedef DescribedCreatable<ColorCorrectionEffect, PostEffect, sColorCorrectionEffect, Reflection::ClassDescriptor::PERSISTENT> Super;
public:
ColorCorrectionEffect();
void setBrightness(int value);
int getBrightness() const { return Brightness; }
void setContrast(int value);
int getContrast() const { return Contrast; }
void setSaturation(int value);
int getSaturation() const { return Saturation; }
void setTintColor(Color3 value);
Color3 getTintColor() const { return TintColor; }
bool isActive;
protected:
int Brightness;
int Contrast;
int Saturation;
Color3 TintColor;
};
}
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include <vector>
#undef min
#undef max
namespace RBX {
class ColorSequenceKeypoint
{
public:
float time;
Color3 value;
float envelope;
ColorSequenceKeypoint(): time(0), value(0,0,0), envelope(0) {}
ColorSequenceKeypoint(float t, Color3 v, float e): time(t), value(v), envelope(e) {}
bool operator==(const ColorSequenceKeypoint& r) const;
};
class ColorSequence
{
public:
typedef ColorSequenceKeypoint Key;
enum { kMaxSize = 20 }; // max number of keypoints permitted
explicit ColorSequence(Color3 constant = Color3(1,1,1));
ColorSequence(Color3 a, Color3 b);
ColorSequence(const std::vector<Key>& keys, bool exceptions = false);
ColorSequence(const ColorSequence& cs);
const std::vector<Key>& getPoints() const { return m_data; }
Key start() const { return m_data.front(); }
Key end() const { return m_data.back(); }
void resample(G3D::Vector3* min, G3D::Vector3* max, int numPoints) const;
bool operator==(const ColorSequence& r) const;
static bool validate(const std::vector<Key>& keys, bool exceptions);
private:
std::vector<Key> m_data;
};
}
+735
View File
@@ -0,0 +1,735 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Verb.h"
#include "Util/RunStateOwner.h"
#include "Tool/ToolsArrow.h"
#include "v8datamodel/Workspace.h"
#include "PartOperation.h"
DYNAMIC_FASTFLAG(UseRemoveTypeIDTricks)
namespace RBX {
class PVInstance;
class Workspace;
class DataModel;
class Camera;
// Utility function
void AddChildToRoot(XmlElement* root, shared_ptr<Instance> wsi, const boost::function<bool(Instance*)>& isInScope, RBX::CreatorRole creatorRole);
void AddSelectionToRoot(XmlElement* root, Selection* sel, RBX::CreatorRole creatorRole);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// BASE COMMAND TYPES
//
class RunStateVerb :
public Verb
{
protected:
DataModel* dataModel;
ServiceClient<RunService> runService;
RunStateVerb(std::string name, DataModel* dataModel, bool blacklisted = false);
void playActionSound();
public:
virtual ~RunStateVerb();
};
// Edit commands are only enabled when the workspace is at Frame 0
// and when something is selected
class EditSelectionVerb
: public Verb
{
protected:
shared_ptr<Workspace> workspace;
ServiceClient<Selection> selection;
DataModel* dataModel;
EditSelectionVerb(std::string name, DataModel* dataModel);
EditSelectionVerb(VerbContainer* container, std::string name, DataModel* dataModel);
public:
virtual ~EditSelectionVerb();
virtual bool isEnabled() const;
};
// Toggles the value of a bool property
class BoolPropertyVerb
: public EditSelectionVerb
{
private:
const Name& propertyName;
protected:
BoolPropertyVerb(
const std::string& name,
DataModel* dataModel,
const char* propertyName );
/*override*/ void doIt(IDataState* dataState);
/*override*/ bool isChecked() const;
};
// Camera commands - always enabled
class CameraVerb : public Verb
{
protected:
Workspace* workspace;
Camera* getCamera();
const Camera* getCamera() const;
ServiceClient<Selection> selection;
public:
CameraVerb(std::string name, Workspace* _workspace);
virtual bool isEnabled() const {return true;}
virtual void doIt(IDataState* dataState);
};
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//
// EDIT MENU - descend from RunFrameZero commands
class DeleteBase : public EditSelectionVerb
{
private:
bool rewardHopper;
protected:
DeleteBase(VerbContainer* container, DataModel* dataModel, std::string name);
DeleteBase(DataModel* dataModel, std::string name, bool rewardHopper = false);
public:
virtual void doIt(IDataState* dataState);
};
class DeleteSelectionVerb : public DeleteBase
{
protected:
DeleteSelectionVerb(VerbContainer* container, DataModel* dataModel, std::string name)
: DeleteBase(container, dataModel, name) {}
public:
DeleteSelectionVerb(DataModel* dataModel)
: DeleteBase(dataModel, "Delete") {}
};
class PlayDeleteSelectionVerb : public DeleteBase
{
public:
PlayDeleteSelectionVerb(DataModel* dataModel)
: DeleteBase(dataModel, "PlayDelete", true) {}
};
class SelectAllCommand : public RunStateVerb
{
public:
SelectAllCommand(DataModel* dataModel) :
RunStateVerb("SelectAll", dataModel) {}
virtual void doIt(IDataState* dataState);
};
class SelectChildrenVerb : public EditSelectionVerb
{
private:
typedef EditSelectionVerb Super;
public:
SelectChildrenVerb(DataModel* dataModel);
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class SnapSelectionVerb : public EditSelectionVerb
{
private:
typedef EditSelectionVerb Super;
public:
SnapSelectionVerb(DataModel* dataModel);
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class UnlockAllVerb : public RunStateVerb
{
public:
UnlockAllVerb(DataModel* dataModel) :
RunStateVerb("UnlockAll", dataModel) {}
virtual void doIt(IDataState* dataState);
};
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// VIEW MENU
//
class CameraTiltUpCommand : public CameraVerb
{
public:
CameraTiltUpCommand(Workspace* workspace) : CameraVerb("CameraTiltUp", workspace) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class CameraTiltDownCommand : public CameraVerb
{
public:
CameraTiltDownCommand(Workspace* workspace) : CameraVerb("CameraTiltDown", workspace) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class CameraPanLeftCommand : public CameraVerb
{
public:
CameraPanLeftCommand(Workspace* workspace) : CameraVerb("CameraPanLeft", workspace) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class CameraPanRightCommand : public CameraVerb
{
public:
CameraPanRightCommand(Workspace* workspace) : CameraVerb("CameraPanRight", workspace) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class CameraZoomInCommand : public CameraVerb
{
public:
CameraZoomInCommand(Workspace* workspace) : CameraVerb("CameraZoomIn", workspace) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class CameraZoomOutCommand : public CameraVerb
{
public:
CameraZoomOutCommand(Workspace* workspace) : CameraVerb("CameraZoomOut", workspace) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class CameraZoomExtentsCommand : public CameraVerb
{
public:
CameraZoomExtentsCommand(Workspace* workspace);
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class CameraCenterCommand : public CameraVerb
{
public:
CameraCenterCommand(Workspace* workspace);
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class FirstPersonCommand : public Verb
{
private:
DataModel* dataModel;
public:
FirstPersonCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ void doIt(IDataState* dataState) {}
};
class ToggleViewMode : public Verb
{
private:
DataModel* dataModel;
public:
ToggleViewMode(RBX::DataModel* dm);
/*override*/ bool isChecked() const;
/*override*/ bool isEnabled() const;
/*override*/ bool isSelected() const;
/*override*/ void doIt(RBX::IDataState* dataState);
};
/////////////////////////////////////////////////////////////////////
class StatsCommand : public Verb
{
protected:
DataModel* dataModel;
public:
StatsCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ bool isChecked() const;
/*override*/ void doIt(IDataState* dataState);
};
class RenderStatsCommand : public Verb
{
protected:
DataModel* dataModel;
public:
RenderStatsCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ bool isChecked() const;
/*override*/ void doIt(IDataState* dataState);
};
class SummaryStatsCommand : public Verb
{
protected:
DataModel* dataModel;
public:
SummaryStatsCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ bool isChecked() const;
/*override*/ void doIt(IDataState* dataState);
};
class CustomStatsCommand : public Verb
{
protected:
DataModel* dataModel;
public:
CustomStatsCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ bool isChecked() const;
/*override*/ void doIt(IDataState* dataState);
};
class NetworkStatsCommand : public Verb
{
protected:
DataModel* dataModel;
public:
NetworkStatsCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ bool isChecked() const;
/*override*/ void doIt(IDataState* dataState);
};
class PhysicsStatsCommand : public Verb
{
protected:
DataModel* dataModel;
public:
PhysicsStatsCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ bool isChecked() const;
/*override*/ void doIt(IDataState* dataState);
};
class EngineStatsCommand : public Verb
{
private:
DataModel* dataModel;
public:
EngineStatsCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const {return true;}
/*override*/ void doIt(IDataState* dataState);
};
class JoinCommand : public Verb
{
protected:
DataModel* dataModel;
public:
JoinCommand(DataModel* dataModel);
/*override*/ bool isEnabled() const;
/*override*/ void doIt(IDataState* dataState);
};
class ChatMenuCommand : public Verb
{
private:
int menu1;
int menu2;
int menu3;
public:
ChatMenuCommand(DataModel* dataModel, int menu1, int menu2, int menu3);
/*override*/ void doIt(IDataState* dataState) {}
static std::string getChatString(int menu1, int menu2, int menu3);
};
class MouseCommand;
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//
// TOOL Launchers
template <class MouseCommandClass, class ParentClass = RunStateVerb>
class TToolVerb : public ParentClass
{
private:
bool toggle;
public:
TToolVerb(DataModel* dataModel, bool toggle = true, bool blacklisted = true) :
ParentClass(
MouseCommandClass::name().toString() + "Tool", // MouseCommand should be a RBX::Named<> descendant, or must implement a static name() function
dataModel,
blacklisted
),
toggle(toggle)
{}
bool sameType(MouseCommand* mouseCommand) const
{
if (DFFlag::UseRemoveTypeIDTricks)
{
return mouseCommand ? MouseCommandClass::name() == mouseCommand->getName() : false;
}
else
{
return mouseCommand ? typeid(MouseCommandClass) == typeid(*mouseCommand) : false;
}
}
void doIt(IDataState* dataState)
{
if (isChecked() && toggle) {
if (!MouseCommand::isAdvArrowToolEnabled())
ParentClass::dataModel->getWorkspace()->setNullMouseCommand(); // Toggle on / off if already on
else
ParentClass::dataModel->getWorkspace()->setDefaultMouseCommand(); // Toggle on / off if already on
}
else {
ParentClass::dataModel->getWorkspace()->setMouseCommand(newMouseCommand());
}
}
bool isChecked() const
{
return sameType(ParentClass::dataModel->getWorkspace()->getCurrentMouseCommand());
}
virtual shared_ptr<MouseCommand> newMouseCommand()
{
return Creatable<MouseCommand>::create<MouseCommandClass>(ParentClass::dataModel->getWorkspace());
}
};
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//
// FORMAT MENU
class AnchorVerb : public EditSelectionVerb
{
public:
AnchorVerb(DataModel* dataModel);
virtual void doIt(IDataState* dataState);
virtual bool isChecked() const;
private:
FilteredSelection<Instance>* m_selection;
};
class MaterialVerb : public EditSelectionVerb
{
public:
MaterialVerb(DataModel* dataModel, std::string name="MaterialVerb")
: EditSelectionVerb(name, dataModel) {}
virtual void doIt(IDataState* dataState);
static PartMaterial getCurrentMaterial() { return m_currentMaterial; }
static void setCurrentMaterial(PartMaterial val) { m_currentMaterial = val; }
static PartMaterial parseMaterial(const std::string materialString);
private:
static PartMaterial m_currentMaterial;
};
class ColorVerb : public EditSelectionVerb
{
public:
ColorVerb(DataModel* dataModel, std::string name="ColorVerb")
: EditSelectionVerb(name, dataModel) {}
virtual void doIt(IDataState* dataState);
static RBX::BrickColor getCurrentColor() { return m_currentColor; }
static void setCurrentColor(RBX::BrickColor val) { m_currentColor = val; }
private:
static RBX::BrickColor m_currentColor;
};
class TranslucentVerb : public BoolPropertyVerb
{
public:
TranslucentVerb(DataModel* dataModel) :
BoolPropertyVerb("TranslucentVerb", dataModel, "Transparent") {}
};
class CanCollideVerb : public BoolPropertyVerb
{
public:
CanCollideVerb(DataModel* dataModel) :
BoolPropertyVerb("CanCollideVerb", dataModel, "CanCollide") {}
};
class AllCanSelectCommand : public RunStateVerb
{
public:
AllCanSelectCommand(DataModel* dataModel) :
RunStateVerb("AllCanSelect", dataModel) {}
virtual void doIt(IDataState* dataState);
};
class CanNotSelectCommand : public EditSelectionVerb
{
public:
CanNotSelectCommand(DataModel* dataModel) :
EditSelectionVerb("CanNotSelect", dataModel) {}
virtual void doIt(IDataState* dataState);
};
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//
class MoveUpSelectionVerb : public EditSelectionVerb
{
private:
float moveUpHeight;
public:
MoveUpSelectionVerb(DataModel* dataModel, const std::string& name, float moveUpHeight)
: EditSelectionVerb(name, dataModel)
, moveUpHeight(moveUpHeight)
{}
/*override*/ void doIt(IDataState* dataState);
};
class MoveUpPlateVerb : public MoveUpSelectionVerb
{
public:
MoveUpPlateVerb(DataModel* dataModel)
: MoveUpSelectionVerb(dataModel, "SelectionUpPlate", 0.4f)
{}
};
class MoveUpBrickVerb : public MoveUpSelectionVerb
{
public:
MoveUpBrickVerb(DataModel* dataModel)
: MoveUpSelectionVerb(dataModel, "SelectionUpBrick", 1.2f)
{}
};
class MoveDownSelectionVerb : public EditSelectionVerb
{
public:
MoveDownSelectionVerb(DataModel* dataModel);
virtual void doIt(IDataState* dataState);
};
class RotateAxisCommand : public EditSelectionVerb
{
protected:
RotateAxisCommand(std::string name, DataModel* dataModel) : EditSelectionVerb(name, dataModel) {}
void rotateAboutAxis(const G3D::Matrix3& rotMatrix, const std::vector<PVInstance*>& selectedInstances);
virtual G3D::Matrix3 getRotationAxis() = 0;
public:
virtual void doIt(IDataState* dataState);
};
class RotateSelectionVerb : public RotateAxisCommand
{
public:
RotateSelectionVerb(DataModel* dataModel);
protected:
virtual G3D::Matrix3 getRotationAxis();
};
class TiltSelectionVerb : public RotateAxisCommand
{
public:
TiltSelectionVerb(DataModel* dataModel);
protected:
virtual G3D::Matrix3 getRotationAxis();
};
class CharacterCommand : public EditSelectionVerb
{
protected:
CharacterCommand(const std::string& name, DataModel* dataModel) :
EditSelectionVerb(name, dataModel) {}
public:
virtual bool isEnabled() const;
};
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//
// RUN MENU
//
class RunCommand : public RunStateVerb
{
public:
RunCommand(DataModel* dataModel) : RunStateVerb("Run", dataModel) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class StopCommand : public RunStateVerb
{
public:
StopCommand(DataModel* dataModel) : RunStateVerb("Stop", dataModel) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
class ResetCommand : public RunStateVerb
{
public:
ResetCommand(DataModel* dataModel) : RunStateVerb("Reset", dataModel) {}
virtual bool isEnabled() const;
virtual void doIt(IDataState* dataState);
};
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//
// Advanced Build Related
//
class TurnOnManualJointCreation : public Verb
{
private:
DataModel* dataModel;
public:
TurnOnManualJointCreation(DataModel* dataModel);
virtual bool isEnabled() const {return true;}
virtual bool isChecked() const {return (AdvArrowTool::advCreateJointsMode && AdvArrowTool::advManualJointMode);}
virtual void doIt(IDataState* dataState);
};
class SetDragGridToOne : public Verb
{
private:
DataModel* dataModel;
public:
SetDragGridToOne(DataModel* dataModel);
virtual bool isEnabled() const {return true;}
virtual bool isChecked() const {return AdvArrowTool::advGridMode == DRAG::ONE_STUD;}
virtual void doIt(IDataState* dataState) {AdvArrowTool::advGridMode = DRAG::ONE_STUD;}
};
class SetDragGridToOneFifth : public Verb
{
private:
DataModel* dataModel;
public:
SetDragGridToOneFifth(DataModel* dataModel);
virtual bool isEnabled() const {return true;}
virtual bool isChecked() const {return AdvArrowTool::advGridMode == DRAG::QUARTER_STUD;}
virtual void doIt(IDataState* dataState) {AdvArrowTool::advGridMode = DRAG::QUARTER_STUD;}
};
class SetDragGridToOff : public Verb
{
private:
DataModel* dataModel;
public:
SetDragGridToOff(DataModel* dataModel);
virtual bool isEnabled() const {return true;}
virtual bool isChecked() const {return AdvArrowTool::advGridMode == DRAG::OFF;}
virtual void doIt(IDataState* dataState) {AdvArrowTool::advGridMode = DRAG::OFF;}
};
class SetGridSizeToTwo : public Verb
{
private:
Workspace* workspace;
public:
SetGridSizeToTwo(DataModel* dataModel);
virtual bool isEnabled() const { return workspace->getShow3DGrid(); }
virtual bool isChecked() const { return (int)Workspace::gridSizeModifier == 2; }
virtual void doIt(IDataState* dataState) { Workspace::gridSizeModifier = 2.0f; }
};
class SetGridSizeToFour : public Verb
{
private:
Workspace* workspace;
public:
SetGridSizeToFour(DataModel* dataModel);
virtual bool isEnabled() const { return workspace->getShow3DGrid(); }
virtual bool isChecked() const { return (int)Workspace::gridSizeModifier == 4; }
virtual void doIt(IDataState* dataState) { Workspace::gridSizeModifier = 4.0f; }
};
class SetGridSizeToSixteen : public Verb
{
private:
Workspace* workspace;
public:
SetGridSizeToSixteen(DataModel* dataModel);
virtual bool isEnabled() const { return workspace->getShow3DGrid(); }
virtual bool isChecked() const { return (int)Workspace::gridSizeModifier == 16; }
virtual void doIt(IDataState* dataState) { Workspace::gridSizeModifier = 16.0f; }
};
class SetManualJointToWeak : public Verb
{
private:
DataModel* dataModel;
public:
SetManualJointToWeak(DataModel* dataModel);
virtual bool isEnabled() const {return false;}
virtual bool isChecked() const {return false;}
virtual void doIt(IDataState* dataState) {AdvArrowTool::advManualJointType = DRAG::WEAK_MANUAL_JOINT;}
};
class SetManualJointToStrong : public Verb
{
private:
DataModel* dataModel;
public:
SetManualJointToStrong(DataModel* dataModel);
virtual bool isEnabled() const {return AdvArrowTool::advManualJointMode;}
virtual bool isChecked() const {return AdvArrowTool::advManualJointType == DRAG::STRONG_MANUAL_JOINT;}
virtual void doIt(IDataState* dataState) {AdvArrowTool::advManualJointType = DRAG::STRONG_MANUAL_JOINT;}
};
class SetManualJointToInfinite : public Verb
{
private:
DataModel* dataModel;
public:
SetManualJointToInfinite(DataModel* dataModel);
virtual bool isEnabled() const {return false;}
virtual bool isChecked() const {return false;}
virtual void doIt(IDataState* dataState) {AdvArrowTool::advManualJointType = DRAG::INFINITE_MANUAL_JOINT;}
};
} // namespace
+140
View File
@@ -0,0 +1,140 @@
/* Copyright 2003-2006 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/DataModel.h"
#include "V8DataModel/Commands.h"
#include "V8DataModel/ToolsPart.h"
#include "V8DataModel/ToolsSurface.h"
#include "V8DataModel/ToolsModel.h"
#include "Tool/ToolsArrow.h"
#include "Tool/ResizeTool.h"
#include "Tool/HammerTool.h"
#include "Tool/GrabTool.h"
#include "Tool/CloneTool.h"
#include "Tool/NullTool.h"
#include "Tool/GameTool.h"
#include "Tool/AxisMoveTool.h"
#include "Tool/AxisRotateTool.h"
#include "Tool/MoveResizeJoinTool.h"
#include "Tool/AdvMoveTool.h"
#include "Tool/AdvRotateTool.h"
#include "V8DataModel/UndoRedo.h"
#include "V8DataModel/InputObject.h"
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include "Util/Runstateowner.h"
#include "Util/InsertMode.h"
class XmlElement;
namespace RBX {
class Fonts;
class GuiRoot;
class GuiItem;
class ContentProvider;
class TimeState;
class Hopper;
class PlayerHopper;
class StarterPackService;
class Adorn;
// Contain a set of verbs used by Roblox
class CommonVerbs
{
public:
CommonVerbs(DataModel* dataModel);
///////////////////////////////////////////////////////////////////////
//
// Play Mode Commands
PlayDeleteSelectionVerb playDeleteSelectionVerb;
// Edit Menu
DeleteSelectionVerb deleteSelectionVerb;
SelectAllCommand selectAllCommand;
SelectChildrenVerb selectChildrenVerb;
SnapSelectionVerb snapSelectionVerb;
UnlockAllVerb unlockAllVerb;
ColorVerb colorVerb;
MaterialVerb materialVerb;
// Format Menu
AnchorVerb anchorVerb;
TranslucentVerb translucentVerb;
CanCollideVerb canCollideVerb;
CanNotSelectCommand canNotSelectCommand;
AllCanSelectCommand allCanSelectCommand;
MoveUpPlateVerb moveUpPlateVerb;
MoveUpBrickVerb moveUpBrickVerb;
MoveDownSelectionVerb moveDownSelectionVerb;
RotateSelectionVerb rotateSelectionVerb;
TiltSelectionVerb tiltSelectionVerb;
// Run Menu
RunCommand runCommand;
StopCommand stopCommand;
ResetCommand resetCommand;
// Test Menu
FirstPersonCommand firstPersonCommand;
StatsCommand statsCommand;
RenderStatsCommand renderStatsCommand;
EngineStatsCommand engineStatsCommand;
NetworkStatsCommand networkStatsCommand;
PhysicsStatsCommand physicsStatsCommand;
SummaryStatsCommand summaryStatsCommand;
CustomStatsCommand customStatsCommand;
JoinCommand joinCommand;
// Adv Build Related
TurnOnManualJointCreation turnOnManualJointCreationVerb;
SetDragGridToOne setDragGridToOneVerb;
SetDragGridToOneFifth setDragGridToOneFifthVerb;
SetDragGridToOff setDragGridToOffVerb;
SetGridSizeToTwo setGridSizeToTwoVerb;
SetGridSizeToFour setGridSizeToFourVerb;
SetGridSizeToSixteen setGridSizeToSixteenVerb;
SetManualJointToWeak setManualJointToWeakVerb;
SetManualJointToStrong setManualJointToStrongVerb;
SetManualJointToInfinite setManualJointToInfiniteVerb;
// Tools
TToolVerb<AxisRotateTool> axisRotateToolVerb;
TToolVerb<AdvMoveTool> advMoveToolVerb;
TToolVerb<AdvRotateTool> advRotateToolVerb;
TToolVerb<AdvArrowTool> advArrowToolVerb;
TToolVerb<MoveResizeJoinTool> resizeToolVerb;
TToolVerb<FlatTool> flatToolVerb;
TToolVerb<GlueTool> glueToolVerb;
TToolVerb<WeldTool> weldToolVerb;
TToolVerb<StudsTool> studsToolVerb;
TToolVerb<InletTool> inletToolVerb;
TToolVerb<UniversalTool> universalToolVerb;
TToolVerb<HingeTool> hingeToolVerb;
TToolVerb<RightMotorTool> rightMotorToolVerb;
TToolVerb<LeftMotorTool> leftMotorToolVerb;
TToolVerb<OscillateMotorTool> oscillateMotorToolVerb;
TToolVerb<SmoothNoOutlinesTool> smoothNoOutlinesToolVerb;
TToolVerb<AnchorTool> anchorToolVerb;
TToolVerb<LockTool> lockToolVerb;
TToolVerb<FillTool> fillToolVerb;
TToolVerb<MaterialTool> materialToolVerb;
TToolVerb<DropperTool> dropperToolVerb;
// Runtime Tools
TToolVerb<GameTool> gameToolVerb;
TToolVerb<GrabTool> grabToolVerb;
TToolVerb<CloneTool> cloneToolVerb;
TToolVerb<HammerTool> hammerToolVerb;
};
} // namespace
+26
View File
@@ -0,0 +1,26 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
namespace RBX {
extern const char* const sConfiguration;
class Configuration
: public DescribedCreatable<Configuration, Instance, sConfiguration>
{
private:
typedef DescribedCreatable<Configuration, Instance, sConfiguration> Super;
public:
Configuration();
////////////////////////////////////////////////////////////////////////////////////
//
// Instance
/*override*/ bool askForbidChild(const Instance* instance) const;
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
};
}
+204
View File
@@ -0,0 +1,204 @@
#pragma once
#include "stdio.h"
#include "util/name.h"
#include <string>
#include <istream>
#include <memory>
#include <vector>
#include "rbx/boost.hpp"
#include "rbx/rbxTime.h"
#include "Util/contentid.h"
#include "Util/HeartbeatInstance.h"
#include "Util/ThreadPool.h"
#include "Util/AsyncHttpCache.h"
#include "Util/LRUCache.h"
#include "V8Tree/Service.h"
#include "rbx/Log.h"
#include "util/ProtectedString.h"
#include "boost/filesystem.hpp"
#include "boost/optional.hpp"
namespace RBX {
class AssetFetchMediator;
class Instance;
class Http;
extern const char* const sContentProvider;
class ContentProvider
: public DescribedNonCreatable<ContentProvider, Instance, sContentProvider, Reflection::ClassDescriptor::RUNTIME_LOCAL>
, public Service
, public HeartbeatInstance
{
private:
typedef DescribedNonCreatable<ContentProvider, Instance, sContentProvider, Reflection::ClassDescriptor::RUNTIME_LOCAL> Super;
public:
static Log *appLog;
static RBX::mutex *appLogLock;
static float PRIORITY_DEFAULT;
static float PRIORITY_MFC;
static float PRIORITY_SCRIPT;
static float PRIORITY_MESH;
static float PRIORITY_SOLIDMODEL;
static float PRIORITY_INSERT;
static float PRIORITY_CHARACTER;
static float PRIORITY_ANIMATION;
static float PRIORITY_TEXTURE;
static float PRIORITY_DECAL;
static float PRIORITY_SOUND;
static float PRIORITY_GUI;
static float PRIORITY_SKY;
private:
boost::shared_ptr<boost::thread> legacyContentCleanupThread;
boost::shared_ptr<boost::thread> contentCleanupThread;
static boost::filesystem::path assetFolderPath;
static boost::filesystem::path platformAssetFolderPath;
static std::string assetFolderString;
static std::string platformAssetFolderString;
static bool assetFolderAlreadyInit;
struct CachedContent
{
shared_ptr<const std::string> data;
shared_ptr<const std::string> filename;
CachedContent()
{}
CachedContent(shared_ptr<const std::string> filename)
:filename(filename)
{}
CachedContent(shared_ptr<const std::string> data, shared_ptr<const std::string> filename)
:data(data)
,filename(filename)
{}
};
boost::shared_ptr<AsyncHttpCache<CachedContent> > contentCache;
class PreloadAsyncRequest
{
public:
int outstanding;
int failed;
PreloadAsyncRequest()
:outstanding(0)
,failed(0)
{}
PreloadAsyncRequest(int requestCount)
:outstanding(requestCount)
,failed(0)
{}
};
public:
ContentProvider();
~ContentProvider();
static ContentId registerContent(std::istream& stream);
bool isUrlBad(RBX::ContentId id);
void blockingLoadInstances(ContentId id, std::vector<shared_ptr<Instance> >& instances);
bool isRequestQueueEmpty();
const std::string& getBaseUrl() const;
const std::string getApiBaseUrl() const;
const std::string getUnsecureApiBaseUrl() const;
static std::string getApiBaseUrl(const std::string& baseUrl);
static std::string getUnsecureApiBaseUrl(const std::string& baseUrl);
void setBaseUrl(std::string url);
void setThreadPool(int count);
void setCacheSize(int count);
void preloadContentWithCallback(RBX::ContentId id, float priority, boost::function<void (AsyncHttpQueue::RequestResult)> callback, AsyncHttpQueue::ResultJob jobType = AsyncHttpQueue::AsyncInline, const std::string& expectedType = "");
void preloadContent(RBX::ContentId id);
void preloadContentBlockingList(shared_ptr<const Reflection::ValueArray> idList, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
static boost::mutex preloadContentBlockingMutex;
void preloadContentBlockingListHelper(AsyncHttpQueue::RequestResult results, boost::function<void()> resumeFunction,
boost::function<void(std::string)> errorFunction, PreloadAsyncRequest *pRequest, ContentId id);
void preloadContentResultCallback(AsyncHttpQueue::RequestResult results, ContentId id);
void clearContent();
void invalidateCache(ContentId contentId);
// returns true if the content is available.
bool hasContent(const ContentId& id);
// returns non-NULL if the content is available. If not available, the provider does an asynchronous request of the content for later
shared_ptr<const std::string> requestContentString(const ContentId& id, float priority);
// Async request
void getContent(const RBX::ContentId& id, float priority, AsyncHttpQueue::RequestCallback callback, AsyncHttpQueue::ResultJob jobType = AsyncHttpQueue::AsyncInline, const std::string& expectedType = "");
void loadContent(const RBX::ContentId& id, float priority, boost::function<void (AsyncHttpQueue::RequestResult, shared_ptr<Instances>, shared_ptr<std::exception>)> callback, AsyncHttpQueue::ResultJob jobType=AsyncHttpQueue::AsyncInline);
void loadContentString(const RBX::ContentId& id, float priority, boost::function<void (AsyncHttpQueue::RequestResult, shared_ptr<const std::string>, shared_ptr<std::exception>)> callback, AsyncHttpQueue::ResultJob jobType=AsyncHttpQueue::AsyncInline);
// The following functions throw exceptions upon failure or return NULL
shared_ptr<const std::string> getContentString(ContentId id);
std::auto_ptr<std::istream> getContent(const ContentId& contentId, const std::string& expectedType = "");
std::string getFile(ContentId contentId);
static std::string getAssetFile(const char* filePath);
//throws an exception
static void verifyRequestedScriptSignature(const ProtectedString& source, const std::string& assetId, bool required);
static void verifyScriptSignature(const ProtectedString& source, bool required);
int getRequestQueueSize() const;
shared_ptr<const Reflection::ValueArray> getFailedUrls();
shared_ptr<const Reflection::ValueArray> getRequestQueueUrls();
shared_ptr<const Reflection::ValueArray> getRequestedUrls();
static void setAssetFolder(const char* path);
static std::string assetFolder();
static std::string platformAssetFolder();
static bool isUrl(const std::string& s);
static bool isHttpUrl(const std::string& s);
static std::string findAsset(RBX::ContentId contentId);
static Reflection::PropDescriptor<ContentProvider, std::string> desc_baseUrl;
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider) {
contentCache->resetStatsItem(newProvider);
Super::onServiceProvider(oldProvider, newProvider);
onServiceProviderHeartbeatInstance(oldProvider, newProvider); // hooks up heartbeat
}
/*implement*/ virtual void onHeartbeat(const Heartbeat& event);
void printContentNames() { contentCache->printContentNames(); }
void setAssetFetchMediator(AssetFetchMediator* afm);
private:
// FullAsyncRequest: all requests (including disk requests) can be asynchronous. disk requests are returned as memory streams, exactly like http responses.
typedef enum { NoHttpRequest, AsyncHttpRequest, SyncHttpRequest, FullAsyncRequest } RequestType;
bool clearFinishFlag;
AssetFetchMediator* afm;
std::string baseUrl;
bool isContentLoaded(ContentId id);
bool blockingLoadContent(ContentId id, CachedContent* result, const std::string& expectedType = "");
AsyncHttpQueue::RequestResult privateLoadContent(ContentId& id, RequestType httpRequestType, float priority, CachedContent* result, AsyncHttpQueue::RequestCallback* callback, AsyncHttpQueue::ResultJob jobType = AsyncHttpQueue::AsyncInline, const std::string& expectedType = "");
static std::string findHashFile(ContentId contentId);
static bool findLocalFile(const std::string& url, std::string* filename);
bool registerFile(const ContentId& id, CachedContent* item);
static bool isInSandbox(const boost::filesystem::path& path, const boost::filesystem::path& sandbox);
};
class AssetFetchMediator
{
public:
virtual boost::optional<std::string> findCachedAssetOrEmpty(const ContentId& contentId, int universeId) = 0;
};
}
@@ -0,0 +1,215 @@
/* Copyright 2003-2013 ROBLOX Corporation, All Rights Reserved */
//
// ContextActionService.h
// App
//
// Created by Ben Tkacheff on 1/17/13.
//
// This service is used to figure out what actions a local player can do (right now this is just for tools, but could expand to several functions)
#pragma once
#include "Util/TextureId.h"
#include "Util/UDim.h"
#include "gui/GuiEvent.h"
#include "V8Tree/Service.h"
#include "script/ThreadRef.h"
namespace RBX {
namespace Network
{
class Player;
}
class ModelInstance;
class Tool;
class GuiButton;
struct BoundFunctionData
{
std::string title;
std::string description;
std::string image;
UDim2 position;
bool hasTouchButton;
shared_ptr<const Reflection::Tuple> inputTypes;
boost::function<void(shared_ptr<Reflection::Tuple>)> luaFunction;
weak_ptr<InputObject> lastInput;
BoundFunctionData()
: image("")
, inputTypes()
, title("")
, description("")
, position()
, hasTouchButton(false)
{ }
BoundFunctionData(shared_ptr<const Reflection::Tuple> newInputTypes)
: inputTypes(newInputTypes)
, image("")
, title("")
, description("")
, position()
, hasTouchButton(false)
{ }
BoundFunctionData(shared_ptr<const Reflection::Tuple> newInputTypes, boost::function<void(shared_ptr<Reflection::Tuple>)> newFunction, bool touchButton)
: inputTypes(newInputTypes)
, image("")
, title("")
, description("")
, position()
, luaFunction(newFunction)
, hasTouchButton(touchButton)
{ }
BoundFunctionData(boost::function<void(shared_ptr<Reflection::Tuple>)> newFunction, bool touchButton)
: inputTypes()
, image("")
, title("")
, description("")
, position()
, luaFunction(newFunction)
, hasTouchButton(touchButton)
{ }
friend bool operator==(const BoundFunctionData& lhs, const BoundFunctionData& rhs)
{
if (lhs.inputTypes && rhs.inputTypes)
{
return (lhs.inputTypes.get() == rhs.inputTypes.get()) && (lhs.image == rhs.image) && (lhs.title == rhs.title)
&& (lhs.description == rhs.description) && (lhs.position == rhs.position) && (lhs.hasTouchButton == rhs.hasTouchButton);
}
return (lhs.image == rhs.image) && (lhs.title == rhs.title) && (lhs.description == rhs.description)
&& (lhs.position == rhs.position) && (lhs.hasTouchButton == rhs.hasTouchButton);
}
};
typedef boost::unordered_map<std::string, BoundFunctionData> FunctionMap;
typedef std::vector<std::pair<std::string,BoundFunctionData> > FunctionVector;
typedef std::pair<boost::function<void(shared_ptr<Instance>)>, boost::function<void(std::string)> > FunctionPair;
typedef boost::unordered_map<std::string, FunctionPair> FunctionPairMap;
typedef enum
{
CHARACTER_FORWARD = 0,
CHARACTER_BACKWARD = 1,
CHARACTER_LEFT = 2,
CHARACTER_RIGHT = 3,
CHARACTER_JUMP = 4
} PlayerActionType;
extern const char* const sContextActionService;
class ContextActionService : public DescribedNonCreatable<ContextActionService, Instance, sContextActionService>
, public Service
{
public:
ContextActionService();
rbx::signal<void(shared_ptr<Instance>)> equippedToolSignal;
rbx::signal<void(shared_ptr<Instance>)> unequippedToolSignal;
rbx::signal<void(std::string, std::string, shared_ptr<const Reflection::ValueTable>)> boundActionChangedSignal;
rbx::signal<void(std::string, bool, shared_ptr<const Reflection::ValueTable>)> boundActionAddedSignal;
rbx::signal<void(std::string, shared_ptr<const Reflection::ValueTable>)> boundActionRemovedSignal;
rbx::signal<void(std::string)> getActionButtonSignal;
rbx::signal<void(std::string, shared_ptr<Instance>)> actionButtonFoundSignal;
std::string getCurrentLocalToolIcon();
void bindCoreActionForInputTypes(const std::string actionName, Lua::WeakFunctionRef functionToBind, bool createTouchButton, shared_ptr<const Reflection::Tuple> hotkeys);
void unbindCoreAction(const std::string actionName);
void bindActionForInputTypes(const std::string actionName, Lua::WeakFunctionRef functionToBind, bool createTouchButton, shared_ptr<const Reflection::Tuple> hotkeys);
void unbindAction(const std::string actionName);
void unbindAll();
void bindActivate(InputObject::UserInputType inputType, KeyCode keyCode);
void unbindActivate(InputObject::UserInputType inputType, KeyCode keyCode);
void setTitleForAction(const std::string actionName, std::string title);
void setDescForAction(const std::string actionName, std::string description);
void setImageForAction(const std::string actionName, std::string image);
void setPositionForAction(const std::string actionName, UDim2 position);
void getButton(const std::string actionName, boost::function<void(shared_ptr<Instance>)> resumeFunction, boost::function<void(std::string)> errorFunction);
shared_ptr<const Reflection::ValueTable> getBoundCoreActionData(const std::string actionName);
shared_ptr<const Reflection::ValueTable> getBoundActionData(const std::string actionName);
shared_ptr<const Reflection::ValueTable> getAllBoundActionData();
void fireActionButtonFoundSignal(const std::string actionName, shared_ptr<Instance> actionButton);
//////////////////////////////////////////////////////////////
//
// Instance
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
//////////////////////////////////////////////////////////////
//
// Proccessing of input
//
GuiResponse processCoreBindings(const shared_ptr<InputObject>& inputObject);
GuiResponse processDevBindings(const shared_ptr<InputObject>& inputObject, bool menuIsOpen);
void callFunction(boost::function<void(shared_ptr<Reflection::Tuple>)> luaFunction, const std::string actionName, const InputObject::UserInputState state, const shared_ptr<Instance> inputObject);
void callFunction(const std::string actionName, const InputObject::UserInputState state, const shared_ptr<Instance> inputObject);
protected:
rbx::signals::scoped_connection characterChildAddConnection;
rbx::signals::scoped_connection characterChildRemoveConnection;
rbx::signals::scoped_connection localPlayerAddConnection;
private:
typedef DescribedNonCreatable<ContextActionService, Instance, sContextActionService> Super;
// these are used for user context binds
FunctionMap functionMap;
FunctionVector functionVector;
// these are used for ROBLOX context binds (For ROBLOX menu, etc.)
FunctionMap coreFunctionMap;
FunctionVector coreFunctionVector;
FunctionPairMap yieldFunctionMap;
// used for binding activate (used to simulate mouse clicks on different inputs
std::string activateGuid;
boost::unordered_map<InputObject*, float> lastZPositionsForActivate;
Tool* getCurrentLocalTool();
Tool* isTool(shared_ptr<Instance> instance);
void checkForToolRemoval(shared_ptr<Instance> removedChildOfCharacter);
void checkForNewTool(shared_ptr<Instance> newChildOfCharacter);
void disconnectAllCharacterConnections();
void localCharacterAdded(shared_ptr<Instance> character);
void setupLocalCharacterConnections(ModelInstance* character);
void checkForLocalPlayer(shared_ptr<Instance> newPlayer);
void setupLocalPlayerConnections(RBX::Network::Player* localPlayer);
void bindActionInternal(const std::string actionName, Lua::WeakFunctionRef functionToBind, bool createTouchButton, shared_ptr<const Reflection::Tuple> hotkeys, FunctionMap& funcMap, FunctionVector& funcVector);
FunctionMap::iterator findAction(const std::string actionName);
GuiResponse tryProcess(shared_ptr<InputObject> inputObject, FunctionVector& funcVector, bool menuIsOpen);
void processActivateAction(const shared_ptr<InputObject>& inputObject);
void fireBoundActionChangedSignal(FunctionMap::iterator iter, const std::string& changeName);
void checkForInputOverride(const Reflection::Variant& newInputType, const FunctionVector& funcVector);
};
}
@@ -0,0 +1,23 @@
#pragma once
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
namespace RBX
{
extern const char* const sCookiesService;
class CookiesService
: public DescribedNonCreatable<CookiesService, Instance, sCookiesService>
, public Service
{
private:
typedef DescribedNonCreatable<CookiesService, Instance, sCookiesService> Super;
std::string path;
public:
CookiesService();
void SetValue(std::string key, std::string value);
std::string GetValue(std::string key);
void DeleteValue(std::string key);
};
}
@@ -0,0 +1,30 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/PartInstance.h"
#include "V8DataModel/BasicPartInstance.h"
#include "reflection/reflection.h"
#ifdef _PRISM_PYRAMID_
namespace RBX {
extern const char* const sCornerWedge;
class CornerWedgeInstance
: public DescribedCreatable<CornerWedgeInstance, PartInstance, sCornerWedge>
{
public:
CornerWedgeInstance();
~CornerWedgeInstance();
/*override*/ virtual PartType getPartType() const { return CORNERWEDGE_PART; }
};
} // namespace
#endif // _PRISM_PYRAMID_
+150
View File
@@ -0,0 +1,150 @@
#pragma once
#include "rbx/signal.h"
#include "V8DataModel/CustomEventReceiver.h"
#include "V8DataModel/PartInstance.h"
#include "V8DataModel/ModelInstance.h"
#include "V8DataModel/CollectionService.h"
#include "V8Tree/Instance.h"
namespace RBX {
extern const char* const sCustomEvent;
class CustomEvent : public DescribedCreatable<CustomEvent, Instance, sCustomEvent> {
private:
typedef DescribedCreatable<CustomEvent, Instance, sCustomEvent> Super;
typedef std::list<weak_ptr<CustomEventReceiver> > ReceiverList;
// prevent copy and assign: this class does sensitive pointer
// management, which would be complicated by allowing copies/assigns.
CustomEvent(const CustomEvent& other);
CustomEvent& operator=(const CustomEvent& other);
ReceiverList receivers;
float currentValue;
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider)
{
if(oldProvider)
oldProvider->create<CollectionService>()->removeInstance(shared_from(this));
Super::onServiceProvider(oldProvider, newProvider);
if(newProvider) {
newProvider->create<CollectionService>()->addInstance(shared_from(this));
} else {
ReceiverList copy = receivers;
for (ReceiverList::iterator itr = copy.begin();
itr != copy.end();
++itr) {
shared_ptr<CustomEventReceiver> receiver = itr->lock();
if (receiver) {
receiver->setSource(NULL);
}
}
}
}
public:
CustomEvent()
:Super(sCustomEvent),
currentValue(0)
{}
// The persisted current value is just for storage -- it is set from the
// SetValue callback, and setPersistedCurrentValue _WILL_NOT_ cause
// receivers to get a value update.
static Reflection::PropDescriptor<CustomEvent, float> prop_PersistedCurrentValue;
static Reflection::BoundFuncDesc<CustomEvent, void(float)> func_SetValue;
static Reflection::BoundFuncDesc<CustomEvent, shared_ptr<const Instances>() > func_GetAttachedReceivers;
static Reflection::EventDesc<CustomEvent, void(shared_ptr<Instance>)> event_ReceiverConnected;
static Reflection::EventDesc<CustomEvent, void(shared_ptr<Instance>)> event_ReceiverDisconnected;
// signals are public for testing only
rbx::signal<void(shared_ptr<Instance>)> receiverConnected;
rbx::signal<void(shared_ptr<Instance>)> receiverDisconnected;
/*override*/ virtual bool askSetParent(const Instance* instance) const {
return Instance::fastDynamicCast<PartInstance>(instance) != NULL;
}
/*override*/ virtual bool askForbidChild(const Instance* instance) const {
return true;
}
float getPersistedCurrentValue() const {
return currentValue;
}
// This method is intended for serialization only, it should not be involved
// with triggering valueChanged events on receivers.
void setPersistedCurrentValue(float newValue) {
currentValue = G3D::clamp(newValue, 0 , 1);
}
void setCurrentValue(float newValue) {
currentValue = G3D::clamp(newValue, 0, 1);
raiseChanged(prop_PersistedCurrentValue);
for (ReceiverList::iterator itr = receivers.begin();
itr != receivers.end();
++itr) {
shared_ptr<CustomEventReceiver> receiver = itr->lock();
if (receiver && receiver->getCurrentValue() != currentValue) {
receiver->sourceValueChanged(currentValue);
}
}
}
shared_ptr<const Instances> getAttachedReceivers() {
shared_ptr<Instances> result(new Instances);
for (ReceiverList::iterator itr = receivers.begin();
itr != receivers.end();
++itr) {
shared_ptr<CustomEventReceiver> receiver = itr->lock();
if (receiver) {
result->push_back(receiver);
}
}
return result;
}
void addReceiver(CustomEventReceiver* receiver) {
bool found = false;
for (ReceiverList::iterator itr = receivers.begin();
itr != receivers.end() && !found;
++itr) {
shared_ptr<CustomEventReceiver> list_receiver = itr->lock();
if (list_receiver.get() == receiver) {
found = true;
}
}
if (!found) {
receivers.push_back(weak_ptr<CustomEventReceiver>(shared_from(receiver)));
// send event only after internal state has been updated
receiverConnected(shared_from(receiver));
}
}
void removeReceiver(CustomEventReceiver* receiver) {
ReceiverList::iterator foundIterator;
bool found = false;
for (ReceiverList::iterator itr = receivers.begin();
itr != receivers.end() && !found;
++itr) {
shared_ptr<CustomEventReceiver> list_receiver = itr->lock();
if (list_receiver.get() == receiver) {
foundIterator = itr;
found = true;
}
}
if (found) {
receivers.erase(foundIterator);
// send event only after internal state has been updated
receiverDisconnected(shared_from(receiver));
}
}
};
} // namespace
@@ -0,0 +1,79 @@
#pragma once
#include "rbx/signal.h"
#include "V8DataModel/PartInstance.h"
#include "V8DataModel/ModelInstance.h"
#include "V8Tree/Instance.h"
namespace RBX {
class CustomEvent;
extern const char* const sCustomEventReceiver;
class CustomEventReceiver
: public DescribedCreatable<CustomEventReceiver, Instance, sCustomEventReceiver> {
private:
typedef DescribedCreatable<CustomEventReceiver, Instance, sCustomEventReceiver> Super;
// prevent copy and assign: this class does sensitive pointer
// management, which would be complicated by allowing copies/assigns.
CustomEventReceiver(const CustomEventReceiver& other);
CustomEventReceiver& operator=(const CustomEventReceiver& other);
weak_ptr<CustomEvent> sourceEvent;
rbx::signals::scoped_connection sourceValueChangedConnection;
float lastReceivedValue;
public:
// public for interoperation with CustomEvent
rbx::signal<void(float)> sourceValueChanged;
// connection signals public for testing
rbx::signal<void(shared_ptr<Instance>)> eventConnected;
rbx::signal<void(shared_ptr<Instance>)> eventDisconnected;
CustomEventReceiver()
:Super(sCustomEventReceiver),
lastReceivedValue(0)
{
sourceValueChangedConnection = sourceValueChanged.connect(
boost::bind(&CustomEventReceiver::setCurrentValue, this, _1));
}
static Reflection::RefPropDescriptor<CustomEventReceiver, Instance> prop_Source;
static Reflection::EventDesc<CustomEventReceiver, void(float)> event_SourceValueChanged;
static Reflection::BoundFuncDesc<CustomEventReceiver, float()> func_GetCurrentValue;
static Reflection::EventDesc<CustomEventReceiver, void(shared_ptr<Instance>)> event_EventConnected;
static Reflection::EventDesc<CustomEventReceiver, void(shared_ptr<Instance>)> event_EventDisconnected;
/*override*/ bool askSetParent(const Instance* instance) const {
return Instance::fastDynamicCast<PartInstance>(instance) != NULL;
}
/*override*/ bool askForbidChild(const Instance* instance) const {
return true;
}
// needs to be forward declared because it depends on CustomEvent
/*override*/// virtual void onAncestorChanged(const AncestorChanged& event);
// should only be used for serialization
Instance* const getSource() const {
return (Instance*) sourceEvent.lock().get();
}
// should only be used for serialization
void setSource(Instance* sourceEvent);
void setCurrentValue(float newValue) {
RBXASSERT(newValue != lastReceivedValue);
lastReceivedValue = newValue;
}
float getCurrentValue() {
return lastReceivedValue;
}
protected:
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
};
}
@@ -0,0 +1,128 @@
#pragma once
#include "V8Tree/Instance.h"
#include "V8DataModel/Effect.h"
#include "V8DataModel/PartInstance.h"
#include "util/TextureId.h"
#include "v8dataModel/NumberSequence.h"
#include "v8datamodel/ColorSequence.h"
#include "v8datamodel/NumberRange.h"
namespace RBX
{
extern const char* const sParticleEmitter;
class CustomParticleEmitter : public DescribedCreatable<CustomParticleEmitter, Instance, sParticleEmitter>, public Effect
{
typedef DescribedCreatable<CustomParticleEmitter, Instance, sParticleEmitter> Base;
public:
CustomParticleEmitter();
virtual ~CustomParticleEmitter();
static Reflection::PropDescriptor<CustomParticleEmitter, TextureId> prop_texture;
static Reflection::PropDescriptor<CustomParticleEmitter, ColorSequence> prop_color;
static Reflection::PropDescriptor<CustomParticleEmitter, NumberSequence> prop_transp;
static Reflection::PropDescriptor<CustomParticleEmitter, NumberSequence> prop_size;
static Reflection::PropDescriptor<CustomParticleEmitter, bool> prop_enabled;
static Reflection::PropDescriptor<CustomParticleEmitter, float> prop_lightEmission;
static Reflection::PropDescriptor<CustomParticleEmitter, float> prop_rate;
static Reflection::PropDescriptor<CustomParticleEmitter, NumberRange> prop_speed;
static Reflection::PropDescriptor<CustomParticleEmitter, float> prop_spread;
static Reflection::PropDescriptor<CustomParticleEmitter, NumberRange> prop_rotation;
static Reflection::PropDescriptor<CustomParticleEmitter, NumberRange> prop_rotSpeed;
static Reflection::PropDescriptor<CustomParticleEmitter, NumberRange> prop_lifetime;
static Reflection::PropDescriptor<CustomParticleEmitter, Vector3> prop_accel;
static Reflection::PropDescriptor<CustomParticleEmitter, float> prop_zOffset;
static Reflection::PropDescriptor<CustomParticleEmitter, float> prop_velocityInheritance;
static Reflection::PropDescriptor<CustomParticleEmitter, float> prop_dampening;
static Reflection::PropDescriptor<CustomParticleEmitter, bool> prop_lockedToLocalSpace;
static Reflection::EnumPropDescriptor<CustomParticleEmitter, NormalId> prop_emissionDirection;
static Reflection::RemoteEventDesc<CustomParticleEmitter, void(int)> event_onEmitRequested;
static Reflection::BoundFuncDesc<CustomParticleEmitter, void(int)> desc_burst;
bool getEnabled() const { return enabled; }
float getLightEmission() const { return lightEmission; }
float getRate() const { return rate; }
const NumberRange& getSpeed() const { return speed; }
float getSpread() const { return spread; }
const NumberRange& getRotation() const { return rotation; }
const NumberRange& getRotSpeed() const { return rotSpeed; }
const NumberRange& getLifetime() const { return lifetime; }
const Vector3& getAccel() const { return accel; }
float getZOffset() const { return zOffset; }
void setEnabled(bool v);
void setLightEmission(float v);
void setRate(float v);
void setSpeed(const NumberRange& v);
void setSpread(float v);
void setRotation(const NumberRange& v);
void setRotSpeed(const NumberRange& v);
void setLifetime(const NumberRange& v);
void setAccel(const Vector3& v);
void setZOffset(float v);
rbx::remote_signal<void(int)> onEmitRequested;
const TextureId& getTexture() const;
void setTexture(const TextureId& id);
const NumberSequence& getTransparency() const;
void setTransparency( const NumberSequence& v );
const ColorSequence& getColor() const;
void setColor(const ColorSequence& val);
const NumberSequence& getSize() const;
void setSize(const NumberSequence& val);
float getVelocityInheritance() const { return velocityInheritance; }
void setVelocityInheritance(float value);
float getDampening() const { return dampening; }
void setDampening(float value);
bool getLockedToLocalSpace() const { return lockedToLocalSpace; }
void setLockedToLocalSpace(bool value);
void requestBurst(int value);
NormalId getEmissionDirection() const { return emissionDirection; }
void setEmissionDirection(NormalId value);
private:
TextureId texture;
ColorSequence color;
NumberSequence transparency;
NumberSequence size;
bool enabled;
float lightEmission;
float rate;
NumberRange speed;
float spread;
NumberRange rotation;
NumberRange rotSpeed;
NumberRange lifetime;
Vector3 accel;
float zOffset;
float velocityInheritance;
float dampening;
bool lockedToLocalSpace;
NormalId emissionDirection;
virtual bool askSetParent(const Instance* parent) const {return Instance::fastDynamicCast<PartInstance>(parent) != NULL;}
virtual bool askAddChild(const Instance* instance) const {return false;}
virtual void onAncestorChanged(const AncestorChanged& event);
};
}
+16
View File
@@ -0,0 +1,16 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "BevelMesh.h"
namespace RBX
{
extern const char* const sCylinderMesh;
class CylinderMesh
: public DescribedCreatable<CylinderMesh, BevelMesh, sCylinderMesh>
{
public:
CylinderMesh(){}
};
}
+724
View File
@@ -0,0 +1,724 @@
/* Copyright 2003-2006 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "gui/GUI.h"
#include "V8DataModel/DataModelJob.h"
#include "V8DataModel/PhysicsInstructions.h"
#include "V8DataModel/GuiBuilder.h"
#include "v8datamodel/Game.h"
#include "V8DataModel/InputObject.h"
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include "Util/GameMode.h"
#include "Util/Runstateowner.h"
#include "Util/InsertMode.h"
#include "Util/Region2.h"
#include "Util/IMetric.h"
#include "Util/HeapValue.h"
#include "Security/FuzzyTokens.h"
#include <boost/array.hpp>
#include <boost/optional.hpp>
#include <boost/unordered_set.hpp>
class XmlElement;
namespace RBX {
class Fonts;
class GuiRoot;
class GuiItem;
class ContentProvider;
class Hopper;
class PlayerHopper;
class StarterPackService;
class StarterGuiService;
class StarterPlayerService;
class CoreGuiService;
class Workspace;
class Adorn;
class Region2;
class UserInputService;
class ContextActionService;
class GuiObject;
extern const char *const sDataModel;
static inline void robloxScriptModifiedCheck(RBX::Security::Permissions perm)
{
#ifndef RBX_STUDIO_BUILD
RBX::Security::Context::current().requirePermission(RBX::Security::RobloxScript);
if (perm != RBX::Security::RobloxScript)
{
throw std::runtime_error("");
}
#endif
}
class DataModel
: public IMetric
, public IDataState
, public VerbContainer
, public Diagnostics::Countable<DataModel>
, public DataModelArbiter
, public DescribedNonCreatable<DataModel, ServiceProvider, sDataModel>
{
public:
enum CreatorType
{
CREATOR_USER = 0,
CREATOR_GROUP = 1
};
//genre == GENRE_ALL || (allowedGenres & (1 << (genre-1))) != 0;
enum Genre
{
GENRE_ALL = 0,
GENRE_TOWN_AND_CITY = 1,
GENRE_FANTASY = 2,
GENRE_SCI_FI = 3,
GENRE_NINJA = 4,
GENRE_SCARY = 5,
GENRE_PIRATE = 6,
GENRE_ADVENTURE = 7,
GENRE_SPORTS = 8,
GENRE_FUNNY = 9,
GENRE_WILD_WEST = 10,
GENRE_WAR = 11,
GENRE_SKATE_PARK = 12,
GENRE_TUTORIAL = 13,
};
enum GearGenreSetting
{
GEAR_GENRE_ALL = 0,
GEAR_GENRE_MATCH = 1,
};
//(allowedGearTypes & (1 << gearType)) != 0;
enum GearType
{
GEAR_TYPE_MELEE_WEAPONS = 0,
GEAR_TYPE_RANGED_WEAPONS = 1,
GEAR_TYPE_EXPLOSIVES = 2,
GEAR_TYPE_POWER_UPS = 3,
GEAR_TYPE_NAVIGATION_ENHANCERS = 4,
GEAR_TYPE_MUSICAL_INSTRUMENTS = 5,
GEAR_TYPE_SOCIAL_ITEMS = 6,
GEAR_TYPE_BUILDING_TOOLS = 7,
GEAR_TYPE_PERSONAL_TRANSPORT = 8,
};
enum RequestShutdownResult
{
CLOSE_NOT_HANDLED = 0,
CLOSE_REQUEST_HANDLED = 1,
CLOSE_LOCAL_SAVE = 2,
CLOSE_NO_SAVE_NEEDED = 3,
};
void postCreate();
static rbx::atomic<int> count;
std::auto_ptr<RBX::Verb> lockVerb;
rbx::signal<void()> screenshotSignal;
rbx::signal<void(const std::string &)> screenshotReadySignal;
rbx::signal<void(bool)> screenshotUploadSignal;
rbx::signal<void(bool)> graphicsQualityShortcutSignal;
rbx::signal<void()> allowedGearTypeChanged;
rbx::signal<void(const shared_ptr<InputObject>& event)> InputObjectProcessed;
rbx::signal<void()> workspaceLoadedSignal;
rbx::signal<void()> gameLoadedSignal;
Genre getGenre() const { return genre; }
void setGenre(Genre genre);
GearGenreSetting getGearGenreSetting() const { return gearGenreSetting; }
void setGear(GearGenreSetting gearGenreSetting, int allowedGearTypes);
void setVIPServerId(std::string value);
std::string getVIPServerId() const;
void setVIPServerOwnerId(int value);
int getVIPServerOwnerId() const;
void setRenderGuisActive(bool value) { renderGuisActive = value; }
bool isGearTypeAllowed(GearType gearType);
static void setLoaderFunction(boost::function<void(RBX::DataModel*)> loader) { loaderFunc = loader; }
void loadPlugins();
struct MouseStats
{
RunningAverageTimeInterval<> osMouseMove;
RunningAverageTimeInterval<> mouseMove;
MouseStats()
:osMouseMove(0.5)
,mouseMove(0.5)
{
}
};
MouseStats mouseStats;
bool getSharedSuppressNavKeys() const { return (game ? game->getSuppressNavKeys() : suppressNavKeys); }
void setGame(RBX::Game* newGame) { game = newGame; }
bool getIsShuttingDown() { return isShuttingDown; }
void setIsShuttingDown(bool value) { isShuttingDown = value; }
private:
typedef DescribedNonCreatable<DataModel, ServiceProvider, sDataModel> Super;
ThrottlingHelper savePlaceThrottle;
// TODO: turn some of these into non-essential Services? Or at least, see if we can
// get rid of the direct references here...
shared_ptr<CoreGuiService> coreGuiService;
shared_ptr<ContextActionService> contextActionService;
shared_ptr<StarterPackService> starterPackService;
shared_ptr<StarterGuiService> starterGuiService;
shared_ptr<StarterPlayerService> starterPlayerService;
shared_ptr<RunService> runService;
shared_ptr<UserInputService> userInputService;
shared_ptr<Workspace> workspace;
shared_ptr<GuiRoot> guiRoot;
bool forceArrowCursor;
virtual GuiResponse processAccelerators(const shared_ptr<InputObject>& event);
virtual GuiResponse processCameraCommands(const shared_ptr<InputObject>& event);
std::string uiMessage; // short term hack - will improve
int drawId; // flag to debug extra draws
IMetric* tempMetric; // for output in ctrl-F1 message - only used during render call
IMetric* networkMetric; // for output in ctrl-F1 message - only used during render call
volatile bool dirty; // For IDataState
bool isInitialized; // Block gui events when closing - per crash reports on 12/05/07
bool isContentLoaded;
volatile bool isShuttingDown;
boost::mutex hackFlagSetMutex;
boost::unordered_set<unsigned int> hackFlagSet;
PhysicsInstructions physicsInstructions;
int numPartInstances;
int numInstances;
int shutdownRequestedCount;
int physicsStepID;
int totalWorldSteps;
bool isGameLoaded;
bool forceR15;
bool canRequestUniverseInfo;
bool universeDataRequested;
void requestGameStartInfo();
bool isPersonalServer;
bool networkStatsWindowsOn;
bool isRobloxApp;
bool renderGuisActive;
RBX::Game* game;
Time dataModelInitTime;
TextureProxyBaseRef renderCursor;
void initializeContents(bool startHeartbeat);
void doDataModelStep(float timeInterval);
bool updatePhysicsInstructions(Network::GameMode gameMode);
bool onlyJobsLeftForThisArbiterAreGenericJobs();
static boost::function<void(RBX::DataModel*)> loaderFunc;
bool areCoreScriptsLoaded;
std::auto_ptr<std::istream> loadAssetIdIntoStream(int assetID);
public:
static bool BlockingDataModelShutdown;
static bool isXboxApp;
static unsigned int perfStats; // another bitmask used to record detected hacks
std::string jobId;
static unsigned int sendStats; // legacy bitmask used to record detected hacks
std::string getJobId() const { return jobId; };
Time getDataModelInitTime() const { return dataModelInitTime; }
static std::string hash; // set to the hash of the client exe
//-----------------------------------
// Concurrency violation detection
// TODO: Merge with readwrite_concurrency_catcher class
class scoped_write_request
{
DataModel* const dataModel;
public:
// Place this code around tasks that write to a DataModel
scoped_write_request(Instance* context);
~scoped_write_request();
};
class scoped_read_request
{
DataModel* const dataModel;
public:
// Place this code around tasks that read a DataModel
scoped_read_request(Instance* context);
~scoped_read_request();
};
class scoped_write_transfer
{
DataModel* const dataModel;
unsigned int oldWritingThread;
public:
// Place this code around tasks that write to a DataModel and expect some other task to hold the write lock for them
scoped_write_transfer(Instance* context);
~scoped_write_transfer();
};
friend class scoped_write_request;
friend class scoped_read_request;
volatile long write_requested;
volatile long read_requested;
volatile DWORD writeRequestingThread;
bool currentThreadHasWriteLock() const;
static bool currentThreadHasWriteLock(Instance* context);
void setNetworkStatsWindowsOn(bool val) { networkStatsWindowsOn = val; }
friend class Game;
//
//-----------------------------------
// It is important for addHackFlag to be inlined for security reasons.
// If this function is not inlined, it provides a single point of attack.
// Also inlining the code (along with VMProtect) provides more obscurity.
#ifdef WIN32
__forceinline
#else
inline
#endif
void addHackFlag(unsigned int flag) {
boost::mutex::scoped_lock l(hackFlagSetMutex);
hackFlagSet.insert(flag);
sendStats |= flag;
}
#ifdef WIN32
__forceinline
#else
inline
#endif
void removeHackFlag(unsigned int flag) {
boost::mutex::scoped_lock l(hackFlagSetMutex);
hackFlagSet.erase(flag);
sendStats &= ~flag;
}
#ifdef WIN32
__forceinline
#else
inline
#endif
bool isHackFlagSet(unsigned int flag) {
boost::mutex::scoped_lock l(hackFlagSetMutex);
return hackFlagSet.find(flag) != hackFlagSet.end() || (sendStats & flag);
}
unsigned int allHackFlagsOredTogether();
weak_ptr<GuiObject> getMouseOverInteractable() const { return mouseOverInteractable; }
bool getMouseOverGui() const { return mouseOverGui; }
void processWorkspaceEvent(const shared_ptr<InputObject>& event);
bool isClosed() const { return !isInitialized; }
void setSuppressNavKeys(bool value) { suppressNavKeys = value; }
static bool throttleAt30Fps; // for debugging/benchmarking - default is false;
// This event is fired anytime anything in the DataModel changes
rbx::signal<void(shared_ptr<Instance>, const Reflection::PropertyDescriptor*)> itemChangedSignal;
void clearContents(bool resettingSimulation);
void setInitialScreenSize(RBX::Vector2 newScreenSize);
// submits a task to be executed in a thread-safe manner
typedef boost::function<void(DataModel*)> Task;
void submitTask(Task task, DataModelJob::TaskType taskType);
shared_ptr<const Reflection::ValueArray> getJobsInfo();
void setCreatorID(int creatorID, CreatorType creatorType);
int getCreatorID() const { return creatorID; }
CreatorType getCreatorType() const { return creatorType; }
int getPlaceID() const { return placeID; }
int getPlaceIDOrZeroInStudio();
void setPlaceID(int placeID, bool robloxPlace);
void setGameInstanceID(std::string gameInstanceID) { this->gameInstanceID = gameInstanceID; }
std::string getGameInstanceID() { return this->gameInstanceID; }
int getUniverseId() { return universeId; }
void setUniverseId(int uId);
bool isStudio() const { return runningInStudio; }
void setIsStudio(bool runningInStudio);
bool getIsXboxApp() const { return isXboxApp; }
void setIsXboxApp(bool value);
bool isRunMode() const { return isStudioRunMode; }
void setIsRunMode(bool value);
int getPlaceVersion() const { return placeVersion; }
void setPlaceVersion(int placeVersion);
bool getIsPersonalServer() const { return isPersonalServer; }
void setIsPersonalServer(bool value) { isPersonalServer = value; }
bool getIsGameLoaded() { return isGameLoaded; }
void setIsGameLoaded(bool value)
{
isGameLoaded = value;
if(isGameLoaded)
gameLoadedSignal();
}
void gameLoaded();
bool getForceR15() const { return forceR15; }
void setForceR15(bool v);
boost::promise<void> universeDataLoaded;
bool getUniverseDataRequested() const { return universeDataRequested; }
void clearUniverseDataRequested() { universeDataRequested = false; }
void setCanRequestUniverseInfo(bool value);
void loadCoreScripts(const std::string &altStarterScript = "");
int getNumPartInstances() const { return numPartInstances; }
int getNumInstance() const { return numInstances; }
void checkFetchExperimentalFeatures();
bool canSaveLocal() const;
void saveToRoblox(boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void completeShutdown(bool saveLocal);
boost::function<bool()> requestShutdownCallback;
typedef boost::function<void(Reflection::AsyncCallbackDescriptor::ResumeFunction, Reflection::AsyncCallbackDescriptor::ErrorFunction)> CloseCallback;
CloseCallback onCloseCallback;
void onCloseCallbackChanged(const CloseCallback&);
//Returns true if the shutdown is being handled by Lua, false to use the System Level Prompts
RequestShutdownResult requestShutdown(bool useLuaShutdownForSave=true);
// for perf stats reporting:
// width of window to measure. Set to zero to turn off and release memory.
void setJobsExtendedStatsWindow(double seconds);
shared_ptr<const Reflection::ValueArray> getJobsExtendedStats();
double getJobTimePeakFraction(std::string jobname, double greaterThan);
double getJobIntervalPeakFraction(std::string jobname, double greaterThan);
class GenericJob;
class LegacyLock : boost::noncopyable
{
struct Implementation;
boost::scoped_ptr<Implementation> const implementation;
public:
static int mainThreadId;
class Impersonator : boost::noncopyable
{
// Use this class to override a Lock. This must only be used
// when you know that a different thread is delegating the lock
// to you.
// TODO: For added safety we could write a stack-based Delegator
// object that would be constructed at the source thread. The
// Delegator would issue a token to be used by the thread that
// uses the Impersonator
public:
Impersonator(shared_ptr<DataModel> dataModel, DataModelJob::TaskType taskType);
~Impersonator();
private:
DataModel::GenericJob* previousJob;
};
LegacyLock(shared_ptr<DataModel> dataModel, DataModelJob::TaskType taskType);
LegacyLock(DataModel* dataModel, DataModelJob::TaskType taskType);
~LegacyLock();
static bool hasLegacyLock(DataModel* dataModel);
};
// Please call these to construct and release a datamodel
static shared_ptr<DataModel> createDataModel(bool startHeartbeat, RBX::Verb* lockVerb, bool shouldShowLoadingScreen);
static void closeDataModel(shared_ptr<DataModel> dataModel);
~DataModel();
DataModel(RBX::Verb* lockVerb);
static DataModel* get(Instance* context) ;
static const DataModel* get(const Instance* context) ;
void loadGame(int assetID);
void loadWorld(int assetID);
void loadContent(ContentId contentId);
void processAfterLoad();
rbx::signal<void()> saveFinishedSignal;
class SerializationException : public std::runtime_error
{
public:
SerializationException(const std::string& response)
: std::runtime_error(response) {}
};
void save(ContentId contentId);
static bool canSave(const RBX::Instance* instance);
bool getRemoteBuildMode();
void setRemoteBuildMode(bool remoteBuildMode);
void setServerSaveUrl(std::string url);
void serverSave();
bool serverSavePlace(const SaveFilter saveFilter, boost::function<void(bool)> resumeFunction = NULL, boost::function<void(std::string)> errorFunction = NULL);
shared_ptr<std::stringstream> serializeDataModel(const Instance::SaveFilter saveFilter = Instance::SAVE_ALL);
virtual void savePlaceAsync(const SaveFilter saveFilter, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
void httpGetAsync(std::string url, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void httpPostAsync(std::string url, std::string data, std::string optionalContentType, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
std::string httpGet(std::string url, bool synchronous);
std::string httpPost(std::string url, std::string data, bool synchronous, std::string optionalContentType);
void reportMeasurement(std::string id, std::string key1, std::string value1, std::string key2, std::string value2);
void luaReportGoogleAnalytics(std::string category, std::string action, std::string label, int value);
void close();
#if defined(RBX_STUDIO_BUILD) || defined(RBX_RCC_SECURITY) || defined(RBX_TEST_BUILD)
shared_ptr<const Instances> fetchAsset(ContentId contentId);
#endif
void raiseClose();
static void TakeScreenshotTask(weak_ptr<RBX::DataModel> weakDataModel);
static void ScreenshotReadyTask(weak_ptr<RBX::DataModel> weakDataModel, const std::string &filename);
// true: finished, false: started
static void ScreenshotUploadTask(weak_ptr<RBX::DataModel> weakDataModel, bool finished);
static void ShowMessage(weak_ptr<RBX::DataModel> weakDataModel, int slot, const std::string &message, double duration);
void setScreenshotSEOInfo(std::string str);
void setVideoSEOInfo(std::string str);
std::string getScreenshotSEOInfo();
std::string getVideoSEOInfo() { return videoSEOInfo; }
bool isScreenshotSEOInfoSet() { return screenshotSEOInfo != ""; }
bool isVideoSEOInfoSet() { return videoSEOInfo != ""; }
void addCustomStat(std::string name, std::string value);
void removeCustomStat(std::string str);
void writeStatsSettings();
///////////////////////////////////////////////////////////////////////
//
// Command Processing
int numChatOptions() {return 4;} // To Do - make this some kind of dynamic loading
void startCoreScripts(bool buildInGameGui, const std::string &altStarterScript = "");
void setGuiTargetInstance(shared_ptr<Instance> newTargetInstance) {guiTargetInstance = newTargetInstance;}
bool processInputObject(shared_ptr<InputObject> event);
GuiRoot* getGuiRoot() {return guiRoot.get();}
void setForceArrowCursor(bool value) { forceArrowCursor = value;}
///////////////////////////////////////////////////////////////////////
// IDataState
virtual void setDirty(bool dirty) { this->dirty = dirty; }
// Thread-safe:
virtual bool isDirty() const { return dirty; }
virtual std::string arbiterName() { return this->getName(); }
////////////////////////////////////////////////////////////////////////////////////
//
// Workspace Stuff / Running Stuff
//
Workspace* getWorkspace() const {return workspace.get();}
float physicsStep(float timeInterval, double dt, double dutyDt, int numThreads);
void renderStep(float timeIntervalSeconds);
////////////////////////////////////////////////////////////////////////////////////
//
// DataModelArbiter
//
/*implement*/ int getNumPlayers() const;
///////////////////////////////////////////////////////////////////////////
//
// timing state
//
double getGameTime() const; // i.e. game time
double getSmoothFps() const;
///////////////////////////////////////////////////////////////////////////
//
// IMetric
//
//
/*override*/ virtual std::string getMetric(const std::string& metric) const;
/*override*/ virtual double getMetricValue(const std::string& metric) const;
std::string getUpdatedMessageBoxText();
void setNetworkMetric(IMetric* metric);
///////////////////////////////////////////////////////////////////////////
//
// Rendering
//
virtual void renderPass2d(Adorn* adorn, IMetric* graphicsMetric);
void renderPass3dAdorn(Adorn* adorn);
void setUiMessage(std::string message);
void clearUiMessage();
void setUiMessageBrickCount();
void toggleToolsOff();
virtual void renderMouse(Adorn* adorn);
ContentId getRenderMouseCursor();
void computeGuiInset(Adorn* adorn);
void renderPlayerGui(Adorn* adorn);
void renderGuiRoot(Adorn* adorn);
static void HttpHelper(std::string* response, std::exception* exception, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
GuiBuilder getGuiBuilder() { return guiBuilder; }
TaskScheduler::Arbiter* getSyncronizationArbiter();
bool uploadPlace(const std::string& uploadUrl, const SaveFilter saveFilter, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
GuiResponse processPlayerGui(const shared_ptr<InputObject>& event);
static void processHttpRequestResponseOnLock(DataModel *dataModel, std::string* response, std::exception* exception, boost::function<void(shared_ptr<std::string>,shared_ptr<std::exception> exception)> onLockAcquired);
protected:
static void doDataModelSetup(shared_ptr<DataModel> dataModel, bool startHeartbeat, bool shouldShowLoadingScreen);
void internalSave(ContentId contentId);
void internalSaveAsync(ContentId contentId, boost::function<void(bool)> resumeFunction);
/////////////////////////////////////////////////////////////////////
//
// Instance overrides
/*override*/ bool askAddChild(const Instance* instance) const;
/*override*/ void onChildAdded(Instance* child);
/*override*/ void onChildChanged(Instance* instance, const PropertyChanged& event);
/*override*/ void onDescendantAdded(Instance* instance);
/*override*/ void onDescendantRemoving(const shared_ptr<Instance>& instance);
void onRunTransition(RunTransition event);
bool processEvent(const shared_ptr<InputObject>& event);
GuiResponse processProfilerEvent(const shared_ptr<InputObject>& event);
weak_ptr<Instance> guiTargetInstance;
bool mouseOverGui;
weak_ptr<GuiObject> mouseOverInteractable;
bool getSuppressNavKeys() const { return suppressNavKeys; }
private:
rbx::signals::scoped_connection unbindResourceSignal;
void onUnbindResourceSignal();
bool suppressNavKeys;
static std::string doHttpGet(const std::string& url);
static void doHttpGet(const std::string& url, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
static std::string doHttpPost(const std::string& url, const std::string& data, const std::string& contentType);
static void doHttpPost(const std::string& url, const std::string& data, const std::string& contentType, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
static void doCloseDataModel(shared_ptr<DataModel> dataModel);
void AsyncUploadPlaceResponseHandler(std::string* response, std::exception* exception, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
bool uploadPlaceReturn(const bool succeeded, const std::string error, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
bool canRenderMouse();
GuiResponse processDevGamepadEvent(const shared_ptr<InputObject>& event);
GuiResponse processCoreGamepadEvent(const shared_ptr<InputObject>& event);
GuiResponse processGuiTarget(const shared_ptr<InputObject>& event);
typedef boost::array<shared_ptr<GenericJob>, DataModelJob::TaskTypeMax> GenericJobs;
RBX::mutex genericJobsLock;
GenericJobs genericJobs;
RBX::mutex debugLock;
shared_ptr<GenericJob> tryGetGenericJob(DataModelJob::TaskType type);
shared_ptr<GenericJob> getGenericJob(DataModelJob::TaskType type);
std::map<std::string,int> dataModelReportingData;
void traverseDataModelReporting(shared_ptr<Instance> child);
Instance* getLightingDeprecated() const;
static Reflection::RefPropDescriptor<DataModel, Instance> prop_lighting;
bool remoteBuildMode;
std::string serverSaveUrl;
std::string screenshotSEOInfo;
std::string videoSEOInfo;
HeapValue<int> placeID;
std::string gameInstanceID;
int universeId;
bool runningInStudio;
bool isStudioRunMode;
bool checkedExperimentalFeatures;
int placeVersion;
HeapValue<int> creatorID;
CreatorType creatorType;
Genre genre;
GearGenreSetting gearGenreSetting;
unsigned allowedGearTypes;
std::string vipServerId;
int vipServerOwnerId;
GuiBuilder guiBuilder;
};
} // namespace
+73
View File
@@ -0,0 +1,73 @@
/* Copyright 2003-2006 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "rbx/TaskScheduler.Job.h"
LOGGROUP(DataModelJobs)
namespace RBX {
class DataModelArbiter;
class DataModelJob : public TaskScheduler::Job
{
public:
typedef enum {
Read = 0, // general read-only access to the DataModel
Write, // general read-writes access to the DataModel
Render,
Physics,
DataOut,
PhysicsOut,
PhysicsOutSort,
DataIn,
PhysicsIn,
RaknetPeer,
None,
TaskTypeMax
}
TaskType;
static const int TaskTypeCount = TaskTypeMax;
TaskType taskType;
virtual TaskScheduler::StepResult step(const Stats& stats);
protected:
virtual TaskScheduler::StepResult stepDataModelJob(const Stats& stats) = 0;
virtual double updateStepsRequiredForCyclicExecutive(float stepDt, float desiredHz, float maxStepsPerCycle, float maxStepsAccumulated);
double stepsAccumulated;
const bool isPerPlayer;
unsigned long long profilingToken;
DataModelJob(const char* name, TaskType taskType, bool isPerPlayer, shared_ptr<DataModelArbiter> arbiter, Time::Interval stepBudget);
/*implement*/ double getPriorityFactor();
};
class DataModelArbiter : public SimpleThrottlingArbiter
{
public:
typedef enum
{
Serial = 0,
Safe,
Logical,
Empirical
}
ConcurrencyModel;
static const int ConcurrencyModelCount = 4;
static ConcurrencyModel concurrencyModel;
DataModelArbiter();
virtual ~DataModelArbiter();
virtual bool areExclusive(TaskScheduler::Job* job1, TaskScheduler::Job* job2);
virtual int getNumPlayers() const = 0;
bool areExclusive(DataModelJob::TaskType task1, DataModelJob::TaskType task2);
virtual void preStep(TaskScheduler::Job* job);
virtual void postStep(TaskScheduler::Job* job);
private:
bool lookup[ConcurrencyModelCount][DataModelJob::TaskTypeCount][DataModelJob::TaskTypeCount];
};
} // namespace
+55
View File
@@ -0,0 +1,55 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "Util/G3DCore.h"
namespace RBX
{
extern const char *const sDataModelMesh;
class DataModelMesh
: public DescribedNonCreatable<DataModelMesh, Instance, sDataModelMesh>
{
public:
// Do not change these integer values, they correlate to the enum on the RBXViewNew side
enum LODType
{
LOW_LOD = 0,
MEDIUM_LOD = 1,
HIGH_LOD = 2
};
protected:
Vector3 scale;
Vector3 vertColor;
Vector3 offset;
LODType LODx;
LODType LODy;
public:
DataModelMesh();
LODType getLevelOfDetailX() const {return LODx; }
void setLevelOfDetailX(LODType val);
LODType getLevelOfDetailY() const {return LODy; }
void setLevelOfDetailY(LODType val);
const G3D::Vector3& getScale() const {return scale;}
void setScale(const G3D::Vector3& value);
const G3D::Vector3 &getVertColor() const {return vertColor;}
void setVertColor(const G3D::Vector3& value);
float getAlpha() const;
const G3D::Vector3& getOffset() const {return offset;}
void setOffset(const G3D::Vector3& value);
protected:
bool askSetParent(const Instance* instance) const;
};
}
+174
View File
@@ -0,0 +1,174 @@
#pragma once
#include "Reflection/Reflection.h"
#include "script/ThreadRef.h"
#include "V8Tree/Instance.h"
#include "rbx/RunningAverage.h"
#include "v8datamodel/DataStoreService.h"
#include "util/LuaWebService.h"
#include "signal.h"
#include <deque>
namespace RBX {
extern const char* const sGlobalDataStore;
class DataStore
:public DescribedNonCreatable<DataStore, Instance, sGlobalDataStore, Reflection::ClassDescriptor::RUNTIME_LOCAL>
{
typedef DescribedNonCreatable<DataStore, Instance, sGlobalDataStore, Reflection::ClassDescriptor::RUNTIME_LOCAL> Super;
class CachedRecord
{
private:
Reflection::Variant variant;
std::string serialized;
Time accessTimeStamp;
public:
CachedRecord(){};
const Reflection::Variant& getVariant(bool touch = true);
const std::string& getSerialized() { return serialized; }
const Time& getTime() { return accessTimeStamp; }
void update(const Reflection::Variant& variant, const std::string& serialized);
};
struct EventSlot
{
Lua::WeakFunctionRef callback;
EventSlot(Lua::WeakFunctionRef);
void fire(Reflection::Variant value);
};
bool isLegacy;
typedef std::map<std::string, CachedRecord> CachedKeys;
CachedKeys cachedKeys;
typedef std::map<std::string, shared_ptr<rbx::signal<void(Reflection::Variant)> > > OnUpdateKeys;
OnUpdateKeys onUpdateKeys;
typedef std::map<std::string,Time> KeyTimestamps;
KeyTimestamps lastSetByKey;
enum RefetchState
{
RefetchOnUpdateKeys,
RefetchCachedKeys,
RefetchDone
};
RefetchState refetchState;
std::string nextKeyToRefetch;
bool backendProcessing;
std::string constructPostDataForKey(const std::string& key, unsigned index = 0);
std::string constructGetUrl();
std::string constructSetUrl(const std::string& key, unsigned valueLength);
std::string constructSetIfUrl(const std::string& key, unsigned valueLength, unsigned expectedValueLength);
std::string constructIncrementUrl(const std::string& key, int delta);
void processSet(std::string key, std::string* response, std::exception* exception, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
void processFetchSingleKey(std::string* response, std::exception* exception, std::string key, bool expectSubKey, boost::function<void()> callback, boost::function<void(std::string)> errorFunction);
void lockAcquiredProcessFetchSingleKey(shared_ptr<std::string> response, shared_ptr<std::exception> exception, std::string key, bool expectSubKey, boost::function<void()> callback, boost::function<void(std::string)> errorFunction);
bool updateCachedKey(const std::string& key, const Reflection::Variant& value);
void createFetchNewKeyRequest(const std::string& key, boost::function<void()> callback, boost::function<void(std::string)> errorFunction, DataStoreService::HttpRequest& request);
// Has to be const reference to Lua::WeakFunctionRef so boost::bind won't copy it to pass by value
// Lua::WeakFunctionRef needs access to Lua state to copy, so can't be done safely in http threadpool
void processSetIf(std::string key, shared_ptr<Lua::WeakFunctionRef> transform, std::string* response, std::exception* exception, boost::function<void(shared_ptr<const Reflection::Tuple>)> resumeFunction, boost::function<void(std::string)> errorFunction);
void lockAcquiredProcessSetIf(std::string key, shared_ptr<Lua::WeakFunctionRef> transform, shared_ptr<std::string> response, shared_ptr<std::exception> exception, boost::function<void(shared_ptr<const Reflection::Tuple>)> resumeFunction, boost::function<void(std::string)> errorFunction);
void runTransformFunction(std::string key, const shared_ptr<Lua::WeakFunctionRef> transform,
boost::function<void(shared_ptr<const Reflection::Tuple>)> resumeFunction,
boost::function<void(std::string)> errorFunction);
void processFetchCachedKeys(std::string* response, std::exception* exception);
void lockAcquiredProcessFetchCachedKeys(shared_ptr<std::string> response, shared_ptr<std::exception> exception);
bool checkAccess(const std::string& key, boost::function<void(std::string)>* errorFunction);
bool checkStudioApiAccess(boost::function<void(std::string)> errorFunction);
static std::string serializeVariant(const Reflection::Variant& variant, bool* hasNonJsonType);
static bool deserializeVariant(const std::string& webValue, Reflection::Variant& result);
void sendBatchGet(std::stringstream& keysList);
void accumulateKeyToFetch(const std::string& key, std::stringstream& keysList, int& counter);
protected:
std::string serviceUrl;
std::string name, scope;
std::string scopeUrlEncodedIfNeeded, nameUrlEncodedIfNeeded;
virtual bool checkValueIsAllowed(const Reflection::Variant&) { return true; };
virtual const char* getDataStoreTypeString() { return "standard"; }
virtual bool queueOrExecuteSet(DataStoreService::HttpRequest& request);
std::string urlEncodeIfNeeded(const std::string& input);
public:
DataStore(const std::string& name, const std::string& scope, bool legacy);
static const char* urlApiPath() { return "persistence"; }
void getAsync(std::string key, boost::function<void(Reflection::Variant)> resumeFunction, boost::function<void(std::string)> errorFunction);
void updateAsync(std::string key, Lua::WeakFunctionRef transformFunc, boost::function<void(shared_ptr<const Reflection::Tuple>)> resumeFunction, boost::function<void(std::string)> errorFunction);
void setAsync(std::string key, Reflection::Variant value, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
void incrementAsync(std::string key, int delta, boost::function<void(Reflection::Variant)> resumeFunction, boost::function<void(std::string)> errorFunction);
rbx::signals::connection onUpdate(std::string key, Lua::WeakFunctionRef callback);
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
void refetchCachedKeys(int* budget);
void resetRefetch();
bool isKeyThrottled(const std::string& key, Time timestamp);
void setKeySetTimestamp(const std::string& key, Time timestamp);
DataStoreService* getParentDataStoreService();
private:
void runResumeFunction(std::string key, boost::function<void(Reflection::Variant)> resumeFunction);
};
extern const char* const sOrderedDataStore;
class OrderedDataStore :
public DescribedNonCreatable<OrderedDataStore, DataStore, sOrderedDataStore, Reflection::ClassDescriptor::RUNTIME_LOCAL>
{
typedef DescribedNonCreatable<DataStore, DataStore, sOrderedDataStore, Reflection::ClassDescriptor::RUNTIME_LOCAL> Super;
std::string constructGetSortedUrl(bool isAscending, int pagesize, const double* minValue, const double* maxValue);
protected:
virtual bool checkValueIsAllowed(const Reflection::Variant& v);
virtual const char* getDataStoreTypeString() { return "sorted"; }
virtual bool queueOrExecuteSet(DataStoreService::HttpRequest& request);
public:
OrderedDataStore(const std::string& name, const std::string& scope);
void getSortedAsync(bool isAscending, int pagesize, Reflection::Variant minValue, Reflection::Variant maxValue,
boost::function<void(shared_ptr<Instance>) > resumeFunction, boost::function<void(std::string)> errorFunction);
};
extern const char* const sDataStorePages;
class DataStorePages :
public DescribedNonCreatable<DataStorePages, Pages, sDataStorePages, Reflection::ClassDescriptor::RUNTIME_LOCAL>
{
weak_ptr<OrderedDataStore> ds;
std::string requestUrl;
std::string exclusiveStartKey;
void processFetch(std::string* response, std::exception* exception, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
void lockAcquiredProcessFetch(shared_ptr<std::string> response, shared_ptr<std::exception> exception, boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
public:
DataStorePages(weak_ptr<OrderedDataStore> ds, const std::string& requestUrl);
void fetchNextChunk(boost::function<void()> resumeFunction, boost::function<void(std::string)> errorFunction);
};
}
+115
View File
@@ -0,0 +1,115 @@
#pragma once
#include "Reflection/Reflection.h"
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include "util/DoubleEndedVector.h"
namespace RBX {
class DataStore;
class DataStoreJob;
struct UnsignedIntegerCountAverage
{
public:
UnsignedIntegerCountAverage()
{
count = 0;
average = 0;
};
unsigned int count;
unsigned int average;
void incrementValueAverage(unsigned int value)
{
if (count == 0)
{
count = 1;
average = value;
}
else
{
average -= (average / count);
average += (value / count);
count = count + 1;
}
}
};
extern const char* const sDataStoreService;
class DataStoreService
:public DescribedCreatable<DataStoreService, Instance, sDataStoreService, Reflection::ClassDescriptor::INTERNAL_LOCAL>
,public Service
{
public:
struct HttpRequest
{
std::string key;
std::string url;
std::string postData;
boost::function<void(std::string*, std::exception*)> handler;
shared_ptr<DataStore> owner;
void execute(DataStoreService* dataStoreService);
bool isKeyThrottled(Time timestamp);
enum RequestType { GET_ASYNC = 5, UPDATE_ASYNC = 6, SET_ASYNC = 7, INCREMENT_ASYNC = 8, GET_SORTED_ASYNC_PAGE = 9 };
RequestType requestType;
boost::posix_time::ptime requestStartTime;
};
private:
typedef DescribedCreatable<DataStoreService, Instance, sDataStoreService, Reflection::ClassDescriptor::INTERNAL_LOCAL> Super;
typedef std::pair<std::string,std::string> StringPair;
typedef std::map<StringPair, shared_ptr<DataStore> > DataStores;
DataStores dataStores, orderedDataStores;
shared_ptr<Instance> getDataStoreInternal(std::string name, std::string scope, bool legacy, bool ordered);
shared_ptr<DataStore> legacyDataStore;
bool disableUrlEncoding;
shared_ptr<DataStoreJob> dataStoreJob;
bool backendProcessing;
BudgetedThrottlingHelper throttleCounterGets, throttleCounterGetSorteds, throttleCounterSets, throttleCounterOrderedSets;
std::list<HttpRequest> throttledGets, throttledGetSorteds, throttledSets, throttledOrderedSets; // New requests go to back, executes from the front
bool queueOrExecuteRequest(HttpRequest& request, std::list<HttpRequest>& queue, BudgetedThrottlingHelper& helper);
void executeThrottledRequests(std::list<HttpRequest>& queue, BudgetedThrottlingHelper& helper);
int getPlayerNum();
boost::mutex analyticsReportMutex;
UnsignedIntegerCountAverage msReadSuccessAverageRequestTime;
UnsignedIntegerCountAverage msErrorAverageRequestTime;
UnsignedIntegerCountAverage msWriteAverageRequestTime;
UnsignedIntegerCountAverage msUpdateAverageRequestTime;
UnsignedIntegerCountAverage msBatchAverageRequestTime;
unsigned int readSuccessCachedCount;
boost::posix_time::ptime lastAnalyticsReportTime;
public:
DataStoreService();
shared_ptr<Instance> getGlobalDataStore();
shared_ptr<Instance> getDataStore(std::string name, std::string scope);
shared_ptr<Instance> getOrderedDataStore(std::string name, std::string scope);
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
void refetchCachedKeys();
void addThrottlingBudgets(float timeDeltaMinutes);
void executeThrottledRequests();
static bool queueOrExecuteGet(DataStore* source, HttpRequest& request);
static bool queueOrExecuteGetSorted(DataStore* source, HttpRequest& request);
static bool queueOrExecuteSet(DataStore* source, HttpRequest& request);
static bool queueOrExecuteOrderedSet(DataStore* source, HttpRequest& request);
bool isUrlEncodingDisabled() const { return disableUrlEncoding; }
void setUrlEncodingDisabled(bool disabled);
void reportCachedRequestGet();
void reportAnalytics();
void onRequestFinishReport(DataStoreService::HttpRequest* request, bool isError, std::string errorMessage);
};
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include "V8Tree/Service.h"
#include <queue>
namespace RBX {
class TimerService;
extern const char* const sDebrisService;
class DebrisService
: public DescribedNonCreatable<DebrisService, Instance, sDebrisService>
, public Service
{
private:
typedef DescribedNonCreatable<DebrisService, Instance, sDebrisService> Super;
std::queue<weak_ptr<Instance> > queue;
int maxItems;
bool legacyMaxItems;
shared_ptr<TimerService> timer;
public:
DebrisService();
void addItem(shared_ptr<Instance> item, double lifetime);
void setMaxItems(int value);
int getMaxItems() const { return maxItems; }
void setLegacyMaxItems(bool);
protected:
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
private:
void cleanup();
};
}
+162
View File
@@ -0,0 +1,162 @@
#pragma once
#include "V8DataModel/GlobalSettings.h"
#include "V8DataModel/DataModelJob.h"
#include "V8World/World.h"
namespace RBX {
// A generic mechanism for displaying stats (like 3D FPS, network traffic, etc.)
extern const char *const sDebugSettings;
class DebugSettings
: public GlobalAdvancedSettingsItem<DebugSettings, sDebugSettings>
{
private:
bool stackTracingEnabled;
float pixelShaderModel;
float vertexShaderModel;
bool reportExtendedMachineConfiguration;
public:
bool soundWarnings;
bool fmodProfiling;
bool enableProfiling;
typedef enum { DontReport, Prompt, Report } ErrorReporting;
ErrorReporting errorReporting;
static std::string robloxVersion;
static std::string robloxProductName;
DebugSettings();
static Reflection::BoundProp<bool> prop_stackTracingEnabled;
static Reflection::BoundProp<bool> prop_reportExtendedMachineConfiguration;
static Reflection::BoundProp<bool> prop_ioEnabled;
bool getStackTracingEnabled() const { return stackTracingEnabled; }
int getLuaRamLimit() const;
void setLuaRamLimit(int value);
int getBlockMeshMapCount() const;
bool blockingRemove;
void setBlockingRemove(bool value) { blockingRemove = value; }
void noOpt() {}
// "Errors"
bool getIsProfilingEnabled() const;
void setIsProfilingEnabled(bool value);
double getProfilingWindow() const;
void setProfilingWindow(double value);
ErrorReporting getErrorReporting() const { return errorReporting; }
void setErrorReporting(ErrorReporting value);
bool getReportExtendedMachineConfiguration() const { return reportExtendedMachineConfiguration; };
Time::SampleMethod getTickCountPreciseOverride() const
{
return Time::preciseOverride;
}
void setTickCountPreciseOverride(Time::SampleMethod value)
{
Time::preciseOverride = value;
}
float getVertexShaderModel() const;
float getPixelShaderModel() const;
void setVertexShaderModel(float);
void setPixelShaderModel(float);
int videoMemory() const; // Mbytes
int cpuSpeed() const; // MHz
int cpuCount() const;
std::string systemProductName() const;
std::string getRobloxVersion() const { RBXASSERT(!robloxVersion.empty()); return robloxVersion; }
std::string getRobloxProductName() const { RBXASSERT(!robloxProductName.empty()); return robloxProductName; }
std::string osVer() const;
int osPlatformId() const;
std::string osPlatform() const;
std::string deviceName() const;
bool osIs64Bit() const;
std::string gfxcard() const;
std::string cpu() const;
std::string simd() const;
int totalPhysicalMemory() const;
int availablePhysicalMemory() const;
std::string resolution() const;
// perf counters
int nameDatabaseSize() const { return (int) RBX::Name::size(); }
int nameDatabaseBytes() const { return (int) RBX::Name::approximateMemoryUsage(); }
double processCores() const;
double getElapsedTime() const;
int totalProcessorTime() const;
int processorTime() const;
int privateBytes() const;
int privateWorkingSetBytes() const;
int GetVirtualBytes() const;
int GetPageFileBytes() const;
int GetPageFaultsPerSecond() const;
long instanceCount() const { return Diagnostics::Countable<Instance>::getCount(); }
long getPlayerCount() const;
long getDataModelCount() const;
long jobCount() const { return Diagnostics::Countable<TaskScheduler::Job>::getCount(); }
long getCdnSuccessCount() const;
long getCdnFailureCount() const;
long getAlternateCdnSuccessCount() const;
long getAlternateCdnFailureCount() const;
double getLastCdnFailureTimeSpan() const;
long getRobloxSuccessCount() const;
long getRobloxFalureCount() const;
double getRobloxResponce() const;
double getCdnRespoce() const;
shared_ptr<const Reflection::Tuple> resetCdnFailureCounts();
};
extern const char *const sTaskSchedulerSettings;
class TaskSchedulerSettings
: public GlobalAdvancedSettingsItem<TaskSchedulerSettings, sTaskSchedulerSettings>
{
TaskScheduler::ThreadPoolConfig threadPoolConfig;
public:
TaskSchedulerSettings();
void addDummyJob(bool exclusive, double fps);
unsigned int threadPoolSize() const { return TaskScheduler::singleton().threadPoolSize(); }
double threadAffinity() const { return TaskScheduler::singleton().threadAffinity(); }
double numSleepingJobs() const { return TaskScheduler::singleton().numSleepingJobs(); }
double numWaitingJobs() const { return TaskScheduler::singleton().numWaitingJobs(); }
double numRunningJobs() const { return TaskScheduler::singleton().numRunningJobs(); }
double schedulerRate() const { return TaskScheduler::singleton().schedulerRate(); }
double schedulerDutyCyclePerThread() const { return TaskScheduler::singleton().getSchedulerDutyCyclePerThread(); }
bool getIsArbiterThrottled() const { return SimpleThrottlingArbiter::isThrottlingEnabled; }
void setIsArbiterThrottled(bool value);
double getThrottledJobSleepTime() const { return TaskScheduler::Job::throttledSleepTime; }
void setThrottledJobSleepTime(double value);
TaskScheduler::PriorityMethod getPriorityMethod() const { return TaskScheduler::priorityMethod; }
void setPriorityMethod(TaskScheduler::PriorityMethod value);
TaskScheduler::Job::SleepAdjustMethod getSleepAdjustMethod() const { return TaskScheduler::Job::sleepAdjustMethod; }
void setSleepAdjustMethod(TaskScheduler::Job::SleepAdjustMethod value);
TaskScheduler::ThreadPoolConfig getThreadPoolConfig() const;
void setThreadPoolConfig(TaskScheduler::ThreadPoolConfig value);
void setThreadShare(double timeSlice, int divisor);
DataModelArbiter::ConcurrencyModel getConcurrencyModel() const { return DataModelArbiter::concurrencyModel; }
void setConcurrencyModel(DataModelArbiter::ConcurrencyModel value);
};
} // namespace
+64
View File
@@ -0,0 +1,64 @@
#pragma once
#include "V8dataModel/FaceInstance.h"
#include "V8Tree/instance.h"
#include "Util/TextureId.h"
namespace RBX {
extern const char* const sDecal;
class Decal : public DescribedCreatable<Decal, FaceInstance, sDecal>
{
TextureId texture;
float specular;
float shiny;
float transparency;
float localTransparencyModifier;
public:
Decal(void);
static const Reflection::PropDescriptor<Decal, TextureId> prop_Texture;
const TextureId& getTexture() const { return texture; }
void setTexture(TextureId value);
static const Reflection::PropDescriptor<Decal, float> prop_Specular;
float getSpecular() const { return specular; }
void setSpecular(float value);
static const Reflection::PropDescriptor<Decal, float> prop_Shiny;
float getShiny() const { return shiny; }
void setShiny(float value);
static const Reflection::PropDescriptor<Decal, float> prop_Transparency;
float getTransparencyUi() const;
float getTransparency() const { return transparency; }
void setTransparency(float value);
static const Reflection::PropDescriptor<Decal, float> prop_LocalTransparencyModifier;
float getLocalTransparencyModifier() const { return localTransparencyModifier; }
void setLocalTransparencyModifier(float value);
};
extern const char* const sDecalTexture;
class DecalTexture : public DescribedCreatable<DecalTexture, Decal, sDecalTexture>
{
G3D::Vector2 studsPerTile;
public:
DecalTexture(void);
const G3D::Vector2& getStudsPerTile() {
return studsPerTile;
}
static const Reflection::PropDescriptor<DecalTexture, float> prop_StudsPerTileU;
float getStudsPerTileU() const { return studsPerTile.x; }
void setStudsPerTileU(float value);
static const Reflection::PropDescriptor<DecalTexture, float> prop_StudsPerTileV;
float getStudsPerTileV() const { return studsPerTile.y; }
void setStudsPerTileV(float value);
};
}
+36
View File
@@ -0,0 +1,36 @@
/* Copyright 2003-2010 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
namespace RBX {
extern const char* const sDialogChoice;
class DialogChoice
: public DescribedCreatable<DialogChoice, Instance, sDialogChoice>
{
private:
std::string userDialog;
std::string responseDialog;
std::string goodbyeDialog;
rbx::signal<void(shared_ptr<Instance>)> selected;
public:
DialogChoice();
std::string getUserDialog() const { return userDialog; }
void setUserDialog(std::string value);
std::string getResponseDialog() const { return responseDialog; }
void setResponseDialog(std::string value);
std::string getGoodbyeDialog() const { return goodbyeDialog; }
void setGoodbyeDialog(std::string value);
///////////////////////////////////////////////////////////////////////////
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
};
}
+76
View File
@@ -0,0 +1,76 @@
/* Copyright 2003-2010 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
namespace RBX {
extern const char* const sDialogRoot;
class DialogRoot
: public DescribedCreatable<DialogRoot, Instance, sDialogRoot>
{
public:
enum DialogPurpose
{
QUEST_PURPOSE,
HELP_PURPOSE,
SHOP_PURPOSE
};
enum DialogTone
{
NEUTRAL_TONE,
FRIENDLY_TONE,
ENEMY_TONE
};
private:
typedef DescribedCreatable<DialogRoot, Instance, sDialogRoot> Super;
bool publicChat;
bool inUse;
float conversationDistance;
std::string initialPrompt;
std::string goodbyeDialog;
DialogPurpose dialogPurpose;
DialogTone dialogTone;
rbx::signal<void(shared_ptr<Instance>)> dialogChoice;
public:
DialogRoot();
~DialogRoot();
DialogPurpose getDialogPurpose() const { return dialogPurpose; }
void setDialogPurpose(DialogPurpose value);
DialogTone getDialogTone() const { return dialogTone; }
void setDialogTone(DialogTone value);
bool getPublicChat() const { return publicChat; }
void setPublicChat(bool value);
bool getInUse() const { return inUse; }
void setInUse(bool value);
float getConversationDistance() const { return conversationDistance; }
void setConversationDistance(float value);
std::string getInitialPrompt() const { return initialPrompt; }
void setInitialPrompt(std::string value);
std::string getGoodbyeDialog() const { return goodbyeDialog; }
void setGoodbyeDialog(std::string value);
void signalDialogChoice(shared_ptr<Instance> player, shared_ptr<Instance> dialogChoice);
rbx::remote_signal<void(shared_ptr<Instance>, shared_ptr<Instance>)> dialogChoiceSelected;
////////////////////////////////////////////////////////////////////////////////////
//
// Instance
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
/*override*/ bool askSetParent(const Instance* instance) const;
};
}
+20
View File
@@ -0,0 +1,20 @@
/* Copyright 2003-2008 ROBLOX Corporation, All Rights Reserved */
#include "Reflection/Reflection.h"
#pragma once
// Common base class for graphical effect "nuggets"
namespace RBX {
class Effect
{
public:
Effect();
virtual ~Effect();
};
} // namespace
+245
View File
@@ -0,0 +1,245 @@
#pragma once
#include "rbx/signal.h"
#include "reflection/type.h"
#include "Reflection/reflection.h"
#include "Reflection/Event.h"
/*
This code lets you specify a remote event that is only fired remotely if somebody listens to it.
There is one problem with this: Count properties aren't reliable in our replication scheme.
It might work if only the server increments and decrements the counter. Also, the counter
probably won't be decremented if a client incremented it and then disconnects.
*/
namespace RBX
{
template <typename Parent, typename Signature>
class EventReplicatorBase
{
protected:
Reflection::BoundProp<int>& connectionCount;
Parent* instance;
Reflection::RemoteEventDesc<Parent,Signature>& remoteEvent;
rbx::signal<void()>& connectionSignal;
rbx::signals::connection listenerConnection;
void listenerConnectionAdded()
{
//RBX::StandardOut::singleton()->printf(RBX::MESSAGE_INFO,
// " Connection incremented to %s",
// connectionCount.name.c_str()
// );
connectionCount.setValue(instance, std::max(connectionCount.getValue(instance) + 1, 1));
}
rbx::signals::connection signalConnection;
virtual void connectSignalListener(){}
public:
EventReplicatorBase(rbx::signal<void()>& connectionSignal,
Reflection::RemoteEventDesc<Parent,Signature>& remoteEvent,
Reflection::BoundProp<int>& connectionCount)
: connectionSignal(connectionSignal)
, remoteEvent(remoteEvent)
, connectionCount(connectionCount)
, instance(NULL)
{
}
~EventReplicatorBase()
{
if(listenerConnection.connected()){
listenerConnection.disconnect();
}
if(signalConnection.connected()){
signalConnection.disconnect();
}
}
void setInstance(Parent* instance)
{
this->instance = instance;
}
void setListenerMode(bool alreadyConnected)
{
if(!listenerConnection.connected()){
//Only one EventReplicator should be working on each signal, if not we'll run into trouble
RBXASSERT(connectionSignal.empty());
listenerConnection = connectionSignal.connect(boost::bind(&EventReplicatorBase::listenerConnectionAdded, this));
if(alreadyConnected){
listenerConnectionAdded();
}
}
}
void onPropertyChanged(const Reflection::PropertyDescriptor& descriptor)
{
if(!listenerConnection.connected()){
if(descriptor.name == connectionCount.name){
//Someone on the other side is listening now, so we need to set up a connection
if(connectionCount.getValue(instance) > 0){
if(!signalConnection.connected()){
//RBX::StandardOut::singleton()->printf(RBX::MESSAGE_INFO,
// " Connection received to %s",
// connectionCount.name.c_str()
//);
connectSignalListener();
}
}
else{
if(signalConnection.connected()){
//RBX::StandardOut::singleton()->printf(RBX::MESSAGE_INFO,
// " Disconnection received to %s",
// connectionCount.name.c_str()
//);
signalConnection.disconnect();
}
}
}
}
}
};
template<int arity, class Parent, typename Signature>
class EventReplicatorImpl;
template<class Parent, typename Signature>
class EventReplicatorImpl<0, Parent, Signature> : public EventReplicatorBase<Parent, Signature>
{
public:
EventReplicatorImpl(rbx::signal<void()>& connectionSignal,
Reflection::RemoteEventDesc<Parent,Signature>& remoteEvent,
Reflection::BoundProp<int>& connectionCount)
: EventReplicatorBase<Parent, Signature>(connectionSignal,remoteEvent,connectionCount)
{
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 0);
}
protected:
void signalProducedIncremented()
{
this->remoteEvent.replicateEvent(this->instance);
}
/*implement*/ void connectSignalListener()
{
this->signalConnection = this->remoteEvent.getSignalPtr(this->instance)->connect(boost::bind(&EventReplicatorImpl::signalProducedIncremented, this));
}
};
template<class Parent, typename Signature>
class EventReplicatorImpl<1, Parent, Signature> : public EventReplicatorBase<Parent, Signature>
{
public:
EventReplicatorImpl(rbx::signal<void()>& connectionSignal,
Reflection::RemoteEventDesc<Parent,Signature>& remoteEvent,
Reflection::BoundProp<int>& connectionCount)
: EventReplicatorBase<Parent, Signature>(connectionSignal,remoteEvent,connectionCount)
{
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 1);
}
protected:
void signalProducedIncremented(typename boost::function_traits<Signature>::arg1_type arg1)
{
this->remoteEvent.replicateEvent(this->instance, arg1);
}
/*implement*/ void connectSignalListener()
{
this->signalConnection = this->remoteEvent.getSignalPtr(this->instance)->connect(boost::bind(
&EventReplicatorImpl<1,Parent,Signature>::signalProducedIncremented, this, _1));
}
};
template<class Parent, typename Signature>
class EventReplicatorImpl<2, Parent, Signature> : public EventReplicatorBase<Parent, Signature>
{
public:
EventReplicatorImpl(rbx::signal<void()>& connectionSignal,
Reflection::RemoteEventDesc<Parent,Signature>& remoteEvent,
Reflection::BoundProp<int>& connectionCount)
: EventReplicatorBase<Parent, Signature>(connectionSignal,remoteEvent,connectionCount)
{
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 2);
}
protected:
void signalProducedIncremented(typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2)
{
this->remoteEvent.replicateEvent(this->instance, arg1, arg2);
}
/*implement*/ void connectSignalListener()
{
this->signalConnection = this->remoteEvent.getSignalPtr(this->instance)->connect(boost::bind(
&EventReplicatorImpl<2,Parent,Signature>::signalProducedIncremented, this, _1, _2));
}
};
template<class Parent, typename Signature>
class EventReplicatorImpl<3, Parent, Signature> : public EventReplicatorBase<Parent, Signature>
{
public:
EventReplicatorImpl(rbx::signal<void()>& connectionSignal,
Reflection::RemoteEventDesc<Parent,Signature>& remoteEvent,
Reflection::BoundProp<int>& connectionCount)
: EventReplicatorBase<Parent, Signature>(connectionSignal,remoteEvent,connectionCount)
{
BOOST_STATIC_ASSERT(boost::function_traits<Signature>::arity == 3);
}
protected:
void signalProducedIncremented(typename boost::function_traits<Signature>::arg1_type arg1, typename boost::function_traits<Signature>::arg2_type arg2, typename boost::function_traits<Signature>::arg3_type arg3)
{
this->remoteEvent.replicateEvent(this->instance, arg1, arg2, arg3);
}
/*implement*/ void connectSignalListener()
{
this->signalConnection = this->remoteEvent.getSignalPtr(this->instance)->connect(boost::bind(
&EventReplicatorImpl<3,Parent,Signature>::signalProducedIncremented, this, _1, _2, _3));
}
};
// Final entry class for EventReplicators
template<class Parent, typename Signature>
class EventReplicator : public EventReplicatorImpl<boost::function_traits<Signature>::arity, Parent, Signature>
{
public:
EventReplicator(rbx::signal<void()>& connectionSignal,
Reflection::RemoteEventDesc<Parent,Signature>& remoteEvent,
Reflection::BoundProp<int>& connectionCount)
: EventReplicatorImpl<boost::function_traits<Signature>::arity,Parent,Signature>(connectionSignal,remoteEvent,connectionCount)
{}
};
}
#define CHELPER2(a,b) a##b
#define CHELPER3(a,b,c) a##b##c
#define DECLARE_EVENT_REPLICATOR_SIG(Parent,eventName,signature)\
int CHELPER3(var,eventName,ConnectionCount);\
static Reflection::BoundProp<int> CHELPER3(prop_,eventName,ConnectionCount);\
RBX::EventReplicator<Parent,signature> CHELPER2(eventReplicator,eventName);
#define category_EventReplicator "EventReplicator"
#define IMPLEMENT_EVENT_REPLICATOR(Parent,eventDesc,eventText,eventName)\
Reflection::BoundProp<int> Parent::CHELPER3(prop_,eventName,ConnectionCount)(eventText "ConnectionCount", category_EventReplicator, &Parent::CHELPER3(var,eventName,ConnectionCount), RBX::Reflection::PropertyDescriptor::REPLICATE_ONLY);
#define CONSTRUCT_EVENT_REPLICATOR(Parent,remoteSignalName,eventDesc,eventName)\
CHELPER2(eventReplicator,eventName)(remoteSignalName.connectionSignal,eventDesc,CHELPER3(prop_,eventName,ConnectionCount))\
, CHELPER3(var,eventName,ConnectionCount)(0)
#define CONNECT_EVENT_REPLICATOR(eventName)\
CHELPER2(eventReplicator,eventName).setInstance(this)
+92
View File
@@ -0,0 +1,92 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "Util/SteppedInstance.h"
#include "Util/RunStateOwner.h"
#include "Util/G3DCore.h"
#include "GfxBase/IAdornable.h"
#include "V8DataModel/Effect.h"
namespace RBX {
class Workspace;
class Primitive;
class PartInstance;
class MegaClusterInstance;
extern const char* const sExplosion;
class Explosion : public DescribedCreatable<Explosion, Instance, sExplosion>
, public IAdornable // this is only here for G3D
, public IStepped
, public Diagnostics::Countable<Explosion>
, public Effect
{
private:
typedef DescribedCreatable<Explosion, Instance, sExplosion> Super;
Vector3 position;
float blastRadius;
float blastPressure; // RBX Force / RBX^2 approximately
float destroyJointRadiusPercent;
float renderTime() const {return 0.10f;} // seconds
float killRadius() const;
float blastMaxObjectRadius() const; // biggest object that can be blasted
float killMaxObjectRadius() const; // biggest object that can be killed
void doKill();
void doBlast(MegaClusterInstance* terrain, const std::vector<shared_ptr<PartInstance> >& parts);
void signalBlast(const std::vector<shared_ptr<PartInstance> >& parts);
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider) {
Super::onServiceProvider(oldProvider, newProvider);
onServiceProviderIStepped(oldProvider, newProvider);
}
// IAdornable
/*override*/ bool shouldRender3dAdorn() const {return true;}
/*override*/ void render3dAdorn(Adorn* adorn);
// IStepped
/*override*/ void onStepped(const Stepped& event);
public:
enum ExplosionType
{
NO_EFFECT,
NO_DEBRIS,
WITH_DEBRIS
};
ExplosionType explosionType;
ExplosionType getExplosionType() const { return explosionType; }
void setExplosionType(ExplosionType value);
float visualRadius() const;
Explosion();
virtual ~Explosion();
rbx::signal<void(shared_ptr<Instance>, float)> hitSignal;
static Reflection::BoundProp<Vector3> propPosition;
static Reflection::BoundProp<float> propBlastPressure;
// C++ only - use for internal tools
void setVisualOnly() {
propBlastPressure.setValue(this, 0.0f);
}
void setBlastRadius(float _blastRadius);
float getBlastRadius() const {return blastRadius;}
const Vector3& getPosition() const { return position; }
void setDestroyJoints(float _destroyJointRadiusPercent);
float getDestroyJoints() const {return destroyJointRadiusPercent;}
};
} // namespace RBX
@@ -0,0 +1,42 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/PartInstance.h"
namespace RBX {
extern const char* const sExtrudedPart;
class ExtrudedPartInstance
: public DescribedCreatable<ExtrudedPartInstance, PartInstance, sExtrudedPart>
{
private:
typedef DescribedCreatable<ExtrudedPartInstance, PartInstance, sExtrudedPart> Super;
public:
ExtrudedPartInstance();
~ExtrudedPartInstance();
enum VisualTrussStyle
{
FULL_ALTERNATING_CROSS_BEAM = 0, //classic style
BRIDGE_STYLE_CROSS_BEAM,
NO_CROSS_BEAM,
//OnlyInternalCrossBeam
};
static const Reflection::EnumPropDescriptor<ExtrudedPartInstance, VisualTrussStyle> prop_styleXml;
/*override*/ virtual PartType getPartType() const { return TRUSS_PART; }
/*override*/ virtual const Vector3& getMinimumUiSize() const;
/*override*/ virtual Faces getResizeHandleMask() const;
/*override*/ virtual int getResizeIncrement() const;
/*override*/ virtual void setPartSizeXml(const Vector3& rbxSize);
void setVisualTrussStyle(VisualTrussStyle value);
VisualTrussStyle getVisualTrussStyle() const { return visualTrussStyle; }
private:
VisualTrussStyle visualTrussStyle;
};
} // namespace
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include "V8Tree/Instance.h"
#include "Util/NormalId.h"
#include "GfxBase/IAdornable.h"
namespace RBX {
// An instance that is designed to "attach" itself to a face of its parent PartInstance
extern const char* const sFaceInstance;
class FaceInstance
: public Reflection::Described<FaceInstance, sFaceInstance, Instance>
, public IAdornable
{
private:
typedef Reflection::Described<FaceInstance, sFaceInstance, Instance> Super;
NormalId face;
//Instance
/*override*/ bool askSetParent(const Instance* instance) const;
//IAdornable
/*override*/ void render3dSelect(Adorn* adorn, SelectState selectState);
public:
FaceInstance(void);
static const Reflection::EnumPropDescriptor<FaceInstance, NormalId > prop_Face;
NormalId getFace() const { return face; }
void setFace(RBX::NormalId value);
};
}
+64
View File
@@ -0,0 +1,64 @@
#pragma once
#include "V8DataModel/GlobalSettings.h"
#include "SimpleJSON.h"
#include "util/Statistics.h"
#define CLIENT_APP_SETTINGS_STRING "ClientAppSettings"
#define CLIENT_SETTINGS_API_KEY "D6925E56-BFB9-4908-AAA2-A5B1EC4B2D79"
namespace RBX
{
extern const char* const sFastLogSettings;
GlobalAdvancedSettings::Item& FastLogSettingsInstance();
class FastLogJSON : public SimpleJSON
{
public:
virtual void ProcessVariable(const std::string& valueName, const std::string& valueData, FastVarType fastVarType);
virtual bool DefaultHandler(const std::string& valueName, const std::string& valueData);
};
class ClientAppSettings : public RBX::FastLogJSON
{
private:
static ClientAppSettings m_ClientAppSettings;
public:
//static ClientAppSettings();
static void Initialize();
static ClientAppSettings& singleton();
START_DATA_MAP(ClientAppSettings);
DECLARE_DATA_BOOL(AllowVideoPreRoll);
DECLARE_DATA_INT(VideoPreRollWaitTimeSeconds);
DECLARE_DATA_BOOL(CaptureQTStudioCountersEnabled);
DECLARE_DATA_BOOL(CaptureMFCStudioCountersEnabled);
DECLARE_DATA_INT(CaptureCountersIntervalInMinutes);
DECLARE_DATA_INT(CaptureSlowCountersIntervalInSeconds);
DECLARE_DATA_STRING(StartPageUrl);
DECLARE_DATA_STRING(PublishedProjectsPageUrl);
DECLARE_DATA_INT(PublishedProjectsPageWidth);
DECLARE_DATA_INT(PublishedProjectsPageHeight);
DECLARE_DATA_BOOL(WebDocAddressBarEnabled);
DECLARE_DATA_INT(AxisAdornmentGrabSize);
DECLARE_DATA_STRING(PrizeAwarderURL);
DECLARE_DATA_STRING(PrizeAssetIDs);
DECLARE_DATA_INT(MinNumberScriptExecutionsToGetPrize);
DECLARE_DATA_INT(MinPartsForOptDragging);
DECLARE_DATA_STRING(GoogleAnalyticsAccountPropertyID);
DECLARE_DATA_STRING(GoogleAnalyticsAccountPropertyIDPlayer);
DECLARE_DATA_INT(GoogleAnalyticsThreadPoolMaxScheduleSize);
DECLARE_DATA_INT(GoogleAnalyticsLoadPlayer);
DECLARE_DATA_INT(GoogleAnalyticsLoadStudio);
DECLARE_DATA_BOOL(GoogleAnalyticsInitFix);
DECLARE_DATA_INT(HttpUseCurlPercentageMacClient);
DECLARE_DATA_INT(HttpUseCurlPercentageMacStudio);
DECLARE_DATA_INT(HttpUseCurlPercentageWinClient);
DECLARE_DATA_INT(HttpUseCurlPercentageWinStudio);
END_DATA_MAP();
};
}
+138
View File
@@ -0,0 +1,138 @@
/* Copyright 2003-2006 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "V8DataModel/JointInstance.h"
#include "GfxBase/IAdornable.h"
#include "Util/NormalId.h"
namespace RBX {
class PartInstance;
class MotorJoint;
extern const char *const sFeature;
class Feature
: public DescribedNonCreatable<Feature, Instance, sFeature>
, public IAdornable
{
public: // ouch - for properties
enum TopBottom {TOP, CENTER_TB, BOTTOM};
enum LeftRight {LEFT, CENTER_LR, RIGHT};
enum InOut {EDGE, INSET, CENTER_IO};
typedef NormalId FaceId;
FaceId faceId;
TopBottom topBottom;
LeftRight leftRight;
InOut inOut;
private:
// Instance
/*override*/ bool askSetParent(const Instance* instance) const {return true;}
// IAdornable
/*override*/ bool shouldRender3dAdorn() const {return true;}
/*override*/ void render3dSelect(Adorn* adorn, SelectState selectState);
protected:
bool getRenderCoord(CoordinateFrame& c) const;
enum InOutZ {Z_IN, Z_OUT};
virtual InOutZ getCoordOrientation() const {return Z_OUT;}
public:
Feature();
~Feature();
FaceId getFaceId() const {return faceId;}
void setFaceId(NormalId value);
TopBottom getTopBottom() const {return topBottom;}
void setTopBottom(TopBottom value);
LeftRight getLeftRight() const {return leftRight;}
void setLeftRight(LeftRight value);
InOut getInOut() const {return inOut;}
void setInOut(InOut value);
CoordinateFrame computeLocalCoordinateFrame() const;
};
extern const char *const sMotorFeature;
class MotorFeature
: public DescribedCreatable<MotorFeature, Feature, sMotorFeature>
{
private:
// Feature
/*override*/ void otherFeatureChanged() {}
// IAdornable
/*override*/ void render3dAdorn(Adorn* adorn);
public:
MotorFeature();
static bool canJoin(Instance* i0, Instance* i1);
static void join(Instance* i0, Instance* i1);
};
extern const char *const sHole;
class Hole
: public DescribedCreatable<Hole, Feature, sHole>
{
private:
// IAdornable
/*override*/ void render3dAdorn(Adorn* adorn);
// Feature
/*override*/ InOutZ getCoordOrientation() const {return Z_IN;}
public:
Hole();
};
extern const char *const sVelocityMotor;
class VelocityMotor
: public DescribedCreatable<VelocityMotor, JointInstance, sVelocityMotor>
{
private:
typedef DescribedCreatable<VelocityMotor, JointInstance, sVelocityMotor> Super;
MotorJoint* motorJoint();
const MotorJoint* motorJoint() const;
shared_ptr<Hole> hole;
rbx::signals::scoped_connection holeAncestorChanged;
void onEvent_HoleAncestorChanged();
void setPart(int i, Feature* feature);
/*override*/ bool askSetParent(const Instance* instance) const {return true;}
/*override*/ void onAncestorChanged(const AncestorChanged& event);
public:
VelocityMotor();
~VelocityMotor();
Hole* getHole() const;
void setHole(Hole* value);
float getMaxVelocity() const;
void setMaxVelocity(float value);
float getDesiredAngle() const;
void setDesiredAngle(float value);
float getCurrentAngle() const;
void setCurrentAngle(float value);
};
} // namespace
+31
View File
@@ -0,0 +1,31 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "DataModelMesh.h"
#include "Util/MeshId.h"
#include "Util/TextureId.h"
namespace RBX
{
extern const char* const sFileMesh;
class FileMesh
: public DescribedCreatable<FileMesh, DataModelMesh, sFileMesh>
{
protected :
TextureId textureId;
MeshId meshId;
public:
FileMesh();
const MeshId& getMeshId() const {return meshId;}
const TextureId& getTextureId() const {return textureId;}
// These are made virtual because SpecialMesh automatically changes the enum type if this is called
virtual void setMeshId(const MeshId& value);
virtual void setTextureId(const TextureId& value);
};
}
+130
View File
@@ -0,0 +1,130 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "Util/G3DCore.h"
#include "Util/HitTestFilter.h"
#include "rbx/boost.hpp"
namespace RBX {
class Instance;
class Primitive;
class Humanoid;
class ModelInstance;
class PVInstance;
class PartInstance;
typedef std::vector<shared_ptr<Instance> > Instances;
/////////////////////////////////////////////////////////////
class Unlocked : public HitTestFilter
{
public:
static bool unlocked(const Primitive* testMe);
/*override*/ Result filterResult(const Primitive* testMe) const
{
return unlocked(testMe) ? HitTestFilter::INCLUDE_PRIM : HitTestFilter::STOP_TEST;
}
};
/////////////////////////////////////////////////////////////
//
// exclude the user character from the hit test
class PartByLocalCharacter : public HitTestFilter
{
protected:
shared_ptr<ModelInstance> character;
shared_ptr<PartInstance> head;
public:
PartByLocalCharacter(Instance* root);
/*override*/ Result filterResult(const Primitive* testMe) const;
};
/////////////////////////////////////////////////////////////
//
class UnlockedPartByLocalCharacter : public PartByLocalCharacter
{
public:
UnlockedPartByLocalCharacter(Instance* root) : PartByLocalCharacter(root) {}
/*override*/ Result filterResult(const Primitive* testMe) const;
};
class FilterInvisibleNonColliding : public HitTestFilter
{
public:
FilterInvisibleNonColliding();
/*override*/ Result filterResult(const Primitive* testMe) const;
};
class FilterDescendents : public HitTestFilter
{
protected:
shared_ptr<Instance> inst;
public:
FilterDescendents(shared_ptr<Instance> i);
/*override*/ Result filterResult(const Primitive* testMe) const;
};
class FilterDescendentsList : public HitTestFilter
{
protected:
const Instances* instances;
public:
FilterDescendentsList(const Instances* i);
/*override*/ Result filterResult(const Primitive* testMe) const;
};
class MergedFilter : public HitTestFilter
{
protected:
const HitTestFilter* aFilter;
const HitTestFilter* bFilter;
public:
MergedFilter(const HitTestFilter *a, const HitTestFilter* b);
/*override*/ Result filterResult(const Primitive* testMe) const;
};
//////////////////////////////
class FilterCharacterOcclusion : public HitTestFilter
{
private:
float headHeight;
public:
FilterCharacterOcclusion(float headHeight);
/*override*/ Result filterResult(const Primitive* testMe) const;
};
//////////////////////////////
class FilterHumanoidParts : public HitTestFilter
{
public:
/*override*/ Result filterResult(const Primitive* testMe) const;
};
//////////////////////////////
class FilterHumanoidNameOcclusion : public HitTestFilter
{
protected:
shared_ptr<Humanoid> inst;
public:
FilterHumanoidNameOcclusion(shared_ptr<Humanoid> i);
/*override*/ Result filterResult(const Primitive* testMe) const;
};
/// Filter for checking if Prim is in same assembly.
class FilterSameAssembly : public HitTestFilter
{
protected:
shared_ptr<PartInstance> assemblyPart;
public:
FilterSameAssembly(shared_ptr<PartInstance> part)
{
assemblyPart = part;
};
/*override*/ Result filterResult(const Primitive* testMe) const;
};
} // namespace RBX
+57
View File
@@ -0,0 +1,57 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "V8DataModel/Effect.h"
#include "V8DataModel/PartInstance.h"
namespace RBX
{
extern const char* const sFire;
class Fire : public DescribedCreatable<Fire, Instance, sFire>
, public Effect
{
private:
bool enabled;
Color3 color;
Color3 secondaryColor;
float size;
float heat;
static const float MaxHeat;
static const float MaxSize;
public:
Fire();
virtual ~Fire();
static Reflection::BoundProp<bool> prop_Enabled;
bool getEnabled() const { return enabled; }
void onChangedEnabled(const Reflection::PropertyDescriptor&);
void setColor(Color3 Color);
Color3 getColor() const {return color;}
void setSecondaryColor(Color3 secondaryColor);
Color3 getSecondaryColor() const {return secondaryColor;}
void setSizeUi(float);
void setSize(float);
float getSizeRaw() const {return size;}
float getClampedSize() const;
void setHeatUi(float);
void setHeat(float);
float getHeatRaw() const {return heat;}
float getClampedHeat() const;
static float getMaxSize() {return MaxSize;}
protected:
bool askSetParent(const Instance* parent) const {return Instance::fastDynamicCast<PartInstance>(parent) != NULL;}
bool askAddChild(const Instance* instance) const {return true;}
};
} // namespace RBX
+45
View File
@@ -0,0 +1,45 @@
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "V8DataModel/Tool.h"
#include "Util/BrickColor.h"
#include "V8DataModel/PartInstance.h"
namespace RBX {
extern const char *const sFlag;
class FlagStand;
class TimerService;
namespace Network { class Player; }
class Flag
: public DescribedCreatable<Flag, Tool, sFlag>
{
private:
typedef DescribedCreatable<Flag, Tool, sFlag> Super;
rbx::signals::scoped_connection_logged flagTouched;
void onEvent_flagTouched(shared_ptr<Instance> other);
protected:
/*override*/
virtual bool canUnequip() {return false;} // The flag cannot be unequipped
virtual bool canBePickedUpByPlayer(Network::Player *p); // The flag cannot be picked up by a member of the same team as the flag.
public:
BrickColor teamColor;
BrickColor getTeamColor() const;
void setTeamColor(BrickColor color);
void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
FlagStand* getJoinedStand();
Flag();
~Flag();
};
} // namespace
+86
View File
@@ -0,0 +1,86 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/BasicPartInstance.h"
#include "G3D/Vector3.h"
#include "v8tree/service.h"
#include "V8DataModel/JointInstance.h"
#include "Util/SteppedInstance.h"
#include "Util/BrickColor.h"
#include <vector>
namespace RBX {
extern const char* const sFlagStand;
class Flag;
class Stepped;
class FlagStand
: public DescribedCreatable<FlagStand, BasicPartInstance, sFlagStand>
{
private:
typedef DescribedCreatable<FlagStand, BasicPartInstance, sFlagStand> Super;
rbx::signals::scoped_connection_logged standTouched;
void onEvent_standTouched(shared_ptr<Instance> other);
shared_ptr<Flag> watchingFlag;
shared_ptr<Flag> clonedReplacementFlag;
void affixFlagToRandomEmptyStand(Flag* flag);
public:
FlagStand();
rbx::signal<void(shared_ptr<Instance>)> flagCapturedSignal;
void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
void onStepped();
void affixFlag(Flag *flag);
Flag *getJoinedFlag();
BrickColor teamColor;
BrickColor getTeamColor() const;
void setTeamColor(BrickColor color);
};
extern const char *const sFlagStandService;
class FlagStandService
: public DescribedNonCreatable<FlagStandService, Instance, sFlagStandService>
, public IStepped
, public Service
{
private:
typedef DescribedNonCreatable<FlagStandService, Instance, sFlagStandService> Super;
std::list<FlagStand *> flagStands;
///////////////////////////////////////////////////////////////////////////
// Instance
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider) {
Super::onServiceProvider(oldProvider, newProvider);
onServiceProviderIStepped(oldProvider, newProvider);
}
// Istepped
/*override*/ void onStepped(const Stepped& event);
FlagStand *findRandomEmptyStandForFlag(Flag *f);
public:
FlagStandService();
~FlagStandService();
void affixFlagToRandomEmptyStand(Flag* flag);
FlagStand *FindStandWithFlag(Flag *f);
void RegisterFlagStand(FlagStand *fs);
void UnregisterFlagStand(FlagStand *fs);
};
} // namespace
+77
View File
@@ -0,0 +1,77 @@
#pragma once
#include "reflection/reflection.h"
#include "util/TextureId.h"
#include "V8DataModel/GuiBase3d.h"
namespace RBX {
class ContactManager;
class PartInstance;
class Workspace;
extern const char* const sFloorWire;
class FloorWire
: public DescribedCreatable<FloorWire, GuiBase3d, sFloorWire> {
private:
typedef Reflection::RefPropDescriptor<FloorWire, PartInstance> PartProp;
static const float kMinDistanceFromBlocks;
static const int kMaxSegments;
static PartProp prop_From;
static PartProp prop_To;
static Reflection::PropDescriptor<FloorWire, TextureId> prop_Texture;
static Reflection::PropDescriptor<FloorWire, Vector2> prop_TextureSize;
static Reflection::PropDescriptor<FloorWire, float> prop_Velocity;
static Reflection::PropDescriptor<FloorWire, float> prop_StudsBetweenTextures;
static Reflection::PropDescriptor<FloorWire, float> prop_CycleOffset;
static Reflection::PropDescriptor<FloorWire, float> prop_WireRadius;
public:
FloorWire();
void setFrom(PartInstance* value);
PartInstance* getFrom() const;
void setTo(PartInstance* value);
PartInstance* getTo() const;
void setTexture(TextureId value);
TextureId getTexture() const;
void setTextureSize(Vector2 value);
Vector2 getTextureSize() const;
void setVelocity(float velocity);
float getVelocity() const;
void setStudsBetweenTextures(float spacing);
float getStudsBetweenTextures() const;
void setCycleOffset(float cycleOffset);
float getCycleOffset() const;
void setWireRadius(float wireRadius);
float getWireRadius() const;
// IAdornable
/*override*/ void render3dAdorn(Adorn* adorn);
protected:
void setPartInstance(weak_ptr<PartInstance>& data,
PartInstance* newValue, const PartProp& prop);
static void computeSurfacePosition(const shared_ptr<PartInstance>& part,
const RbxRay& ray, Vector3* out);
bool incrementalBuildSegments(const Workspace* workspace,
const ContactManager* contactManager, const Vector3& dest,
bool moveInX, std::vector<Vector3>* out);
void buildTrailSegments(const Workspace* workspace,
const shared_ptr<PartInstance>& from,
const shared_ptr<PartInstance>& to,
std::vector<Vector3>* out);
void drawSegments(const Workspace* workspace, const Camera* camera,
const std::vector<Vector3>& segments, Adorn* adorn);
weak_ptr<PartInstance> from;
weak_ptr<PartInstance> to;
TextureId texture;
Vector2 textureSize;
float velocity;
float studsBetweenTextures;
float cycleOffset;
float wireRadius;
};
}
@@ -0,0 +1,82 @@
/* Copyright 2014 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "Util/BinaryString.h"
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include <boost/unordered_map.hpp>
#include "Value.h"
namespace RBX
{
class InstanceStringData
{
public:
InstanceStringData(weak_ptr<BinaryStringValue> str)
: ref(str)
, count(1)
{}
InstanceStringData(weak_ptr<BinaryStringValue> str, int refCount)
: ref(str)
, count(refCount)
{}
weak_ptr<BinaryStringValue> ref;
int count;
};
extern const char *const sFlyweightService;
class FlyweightService
: public DescribedCreatable<FlyweightService, Instance, sFlyweightService, Reflection::ClassDescriptor::PERSISTENT, Security::Roblox>
, public Service
{
protected:
typedef DescribedCreatable<FlyweightService, Instance, sFlyweightService, Reflection::ClassDescriptor::PERSISTENT, Security::Roblox> Super;
typedef boost::unordered_map<std::string, InstanceStringData> FlyweightInstanceMap;
FlyweightInstanceMap instanceMap;
rbx::signals::scoped_connection stringChildAddedSignal;
rbx::signals::scoped_connection stringChildRemovedSignal;
virtual void onChildAdded(shared_ptr<RBX::Instance> childInstance);
void storeStringData(BinaryString& str, bool forceIncrement, const std::string& name);
void retrieveStringData(BinaryString& str);
void incrementStringRefCounter(const BinaryString& str);
std::string getLocalKeyHash(const std::string& str);
std::string getLocalKeyHash(const BinaryString& str);
virtual void refreshRefCountUnderInstance(RBX::Instance* instance) {}
void cleanChildren();
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
bool isChildData(shared_ptr<RBX::Instance> childData);
public:
FlyweightService();
void clean();
virtual void refreshRefCount();
static std::string createHashKey(const std::string& str);
static std::string getHashKey(const std::string& str);
static bool isHashKey(const std::string& str);
std::string dataType(std::string str);
const BinaryString peekAtData(const BinaryString& str);
void removeStringData(const BinaryString& str);
void printMapSizes();
};
}
+25
View File
@@ -0,0 +1,25 @@
/* Copyright 2003-2014 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
namespace RBX {
extern const char* const sFolder;
class Folder
: public DescribedCreatable<Folder, Instance, sFolder>
{
private:
typedef DescribedCreatable<Folder, Instance, sFolder> Super;
public:
Folder();
////////////////////////////////////////////////////////////////////////////////////
//
// Instance
/*override*/ bool askAddChild(const Instance* instance) const;
/*override*/ bool askForbidChild(const Instance* instance) const;
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ bool askForbidParent(const Instance* instance) const;
};
}
+43
View File
@@ -0,0 +1,43 @@
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "Util/RunStateOwner.h"
#include "GfxBase/IAdornable.h"
#include "V8DataModel/Effect.h"
namespace RBX {
class PartInstance;
static const float largeSize = 1.1f;
extern const char* const sForceField;
class ForceField : public DescribedCreatable<ForceField, Instance, sForceField>
, public IAdornable
, public Effect
{
private:
//typedef DescribedCreatable<ForceField, Instance, sForceField> Super;
Time startTime;
int cycle;
int invertCycle;
shared_ptr<Instance> torso;
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
// IAdornable
/*override*/ bool shouldRender3dAdorn() const {return true;}
/*override*/ void render3dAdorn(Adorn* adorn);
public:
ForceField();
virtual ~ForceField() {}
static bool partInForceField(PartInstance* part);
static int cycles() {return 60;}
};
} // namespace RBX
+46
View File
@@ -0,0 +1,46 @@
#pragma once
#include "V8DataModel/GuiObject.h"
namespace RBX
{
extern const char* const sFrame;
class Frame
: public DescribedCreatable<Frame, GuiObject, sFrame>
{
private:
typedef DescribedCreatable<Frame, GuiObject, sFrame> Super;
public:
enum Style
{
CUSTOM_STYLE = 0,
BLUE_CHAT_STYLE = 1,
ROBLOX_SQUARE_STYLE = 2,
ROBLOX_ROUND_STYLE = 3,
GREEN_CHAT_STYLE = 4,
RED_CHAT_STYLE = 5,
ROBLOX_DROPSHADOW_STYLE = 6,
};
Frame();
Style getStyle() const { return style; }
void setStyle(Style style);
////////////////////////////////////////////////////////////////////////////////////
//
// IAdornable
/*override*/ void render2d(Adorn* adorn);
/////////////////////////////////////////////////////////////
// GuiBase2d
//
/*override*/ Rect2D getChildRect2D() const;
private:
Style style;
GuiDrawImage image;
};
}
+102
View File
@@ -0,0 +1,102 @@
#pragma once
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
namespace RBX {
extern const char* const sFriendService;
class FriendService
: public DescribedCreatable<FriendService, Instance, sFriendService, Reflection::ClassDescriptor::INTERNAL>
, public Service
{
private:
typedef DescribedCreatable<FriendService, Instance, sFriendService, Reflection::ClassDescriptor::INTERNAL> Super;
public:
enum FriendEventType
{
ISSUE_REQUEST,
REVOKE_REQUEST,
ACCEPT_REQUEST,
DENY_REQUEST
};
enum FriendStatus
{
FRIEND_STATUS_UNKNOWN = 0,
FRIEND_STATUS_NOT_FRIEND = 1,
FRIEND_STATUS_FRIEND = 2,
FRIEND_STATUS_FRIEND_REQUEST_SENT = 3,
FRIEND_STATUS_FRIEND_REQUEST_RECEIVED = 4,
};
FriendService();
void setCreateFriendRequestUrl(std::string);
void setDeleteFriendRequestUrl(std::string);
void setMakeFriendUrl(std::string);
void setBreakFriendUrl(std::string);
void setGetFriendsUrl(std::string);
FriendStatus getFriendStatus(int playerId, int otherPlayerId) const;
void setEnable(bool value);
bool getEnable() const { return enable;}
void playerAdded(int userId);
void playerRemoving(int userId);
void issueFriendRequestOrMakeFriendship(int userId, int otherUserId);
void rejectFriendRequestOrBreakFriendship(int userId, int otherUserId);
// Instance
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
//Should be private
rbx::remote_signal<void(int, int, FriendEventType)> friendEventReplicatingSignal;
rbx::remote_signal<void(int, int, FriendStatus)> friendStatusReplicatingSignal;
void getFriendsOnline(int maxFriends, boost::function<void(shared_ptr<const Reflection::ValueArray>)> resumeFunction, boost::function<void(std::string)> errorFunction);
void setFriendsOnlineUrl(std::string url);
private:
void friendStatusReplicationChanged(int playerId, int otherPlayerId, FriendStatus status);
rbx::signals::scoped_connection friendStatusConnection;
void friendEventReplicationChanged(int playerId, int otherPlayerId, FriendEventType status);
rbx::signals::scoped_connection friendEventConnection;
std::string getBulkFriendsUrl;
std::string breakFriendUrl;
std::string makeFriendUrl;
std::string deleteFriendRequestUrl;
std::string createFriendRequestUrl;
std::string friendsOnlineUrl;
void storeAndReplicateFriendStatus(int userId, int otherUserId, FriendStatus friendStatus);
//friendStatusTable[smallUserId][bigUserId] = Status
typedef std::map<int, FriendStatus> FriendStatusInternalMap;
typedef std::map<int, FriendStatusInternalMap > FriendStatusMap;
FriendStatusMap friendStatusTable;
typedef std::set<std::pair<int, int> > FriendRequestSet;
FriendRequestSet friendRequestSet;
std::set<int> players;
template<typename ResultType>
void dispatchRequest(const std::string&, boost::function<void(ResultType)> resumeFunction, boost::function<void(std::string)> errorFunction);
bool enable;
void processServiceSuccess(int maxFriends, std::string result, boost::function<void(shared_ptr<const Reflection::ValueArray>)> resumeFunction,
boost::function<void(std::string)> errorFunction);
void processServiceError(std::string error, boost::function<void(std::string)> errorFunction);
static void ProcessBulkFriendResponse(weak_ptr<FriendService> weakFriendService, int userId, std::set<int> userIdsRequested, std::string* response, std::exception* error);
static void StoreFriendsHelper(weak_ptr<FriendService> weakFriendService, int userId, shared_ptr<FriendStatusInternalMap> friends);
};
}
+208
View File
@@ -0,0 +1,208 @@
#pragma once
#include "V8DataModel/GlobalSettings.h"
#include "V8DataModel/GameSettings.h"
namespace RBX
{
extern const char *const sGameBasicSettings;
class GameBasicSettings
: public GlobalBasicSettingsItem<GameBasicSettings, sGameBasicSettings>
{
typedef GlobalBasicSettingsItem<GameBasicSettings, sGameBasicSettings> Super;
public:
enum ControlMode {CONTROL_CLASSIC = 0, CONTROL_MOUSELOCK = 1, CONTROL_HYBRID = 2, CONTROL_CAMLOCK = 3, CONTROL_MOUSEPAN = 4};
enum RenderQualitySetting {QUALITY_AUTO = 0, QUALITY_1 = 1, QUALITY_2 = 2, QUALITY_3 = 3, QUALITY_4 = 4, QUALITY_5 = 5, QUALITY_6 = 6, QUALITY_7 = 7, QUALITY_8 = 8, QUALITY_9 = 9, QUALITY_10 = 10};
enum CameraMode {CAMERA_MODE_DEFAULT = 0, CAMERA_MODE_CLASSIC = 1, CAMERA_MODE_FOLLOW = 2};
enum TouchCameraMovementMode {
TOUCH_CAMERA_MOVEMENT_MODE_DEFAULT = 0,
TOUCH_CAMERA_MOVEMENT_MODE_CLASSIC = 1,
TOUCH_CAMERA_MOVEMENT_MODE_FOLLOW = 2 };
enum ComputerCameraMovementMode {
COMPUTER_CAMERA_MOVEMENT_MODE_DEFAULT = 0,
COMPUTER_CAMERA_MOVEMENT_MODE_CLASSIC = 1,
COMPUTER_CAMERA_MOVEMENT_MODE_FOLLOW = 2};
enum TouchMovementMode {
TOUCH_MOVEMENT_MODE_DEFAULT = 0,
TOUCH_MOVEMENT_MODE_THUMBSTICK = 1,
TOUCH_MOVEMENT_MODE_DPAD = 2,
TOUCH_MOVEMENT_MODE_THUMBPAD = 3,
TOUCH_MOVEMENT_MODE_CLICK_TO_MOVE = 4 };
enum ComputerMovementMode {
COMPUTER_MOVEMENT_MODE_DEFAULT = 0,
COMPUTER_MOVEMENT_MODE_KBD_MOUSE = 1,
COMPUTER_MOVEMENT_MODE_CLICK_TO_MOVE = 2};
enum YearSettings {
Year2016 = 0,
Year2015 = 1,
Year2014 = 2,
Year2013 = 3
};
enum RotationType {
ROTATION_TYPE_MOVEMENT_RELATIVE = 0,
ROTATION_TYPE_CAMERA_RELATIVE = 1};
static Reflection::PropDescriptor<GameBasicSettings, float> prop_masterVolume;
GameBasicSettings();
ControlMode getControlMode() const { return controlMode; }
void setControlMode(ControlMode setting);
CameraMode getCameraMode() const { return cameraMode; }
GameBasicSettings::CameraMode getCameraModeWithDefault() const;
void setCameraMode(CameraMode setting);
TouchCameraMovementMode getTouchCameraMovementMode() const { return touchCameraMovementMode; }
void setTouchCameraMovementMode(TouchCameraMovementMode setting);
bool getTouchCameraMovementModeModified() const { return touchCameraMovementModeModified; }
void setTouchCameraMovementModeModified(bool setting);
ComputerCameraMovementMode getComputerCameraMovementMode() const { return computerCameraMovementMode; }
void setComputerCameraMovementMode(ComputerCameraMovementMode setting);
bool getComputerCameraMovementModeModified() const { return computerCameraMovementModeModified; }
void setComputerCameraMovementModeModified(bool setting);
YearSettings getCurrentYear() const { return currentYear; }
void setYear(YearSettings setting);
TouchMovementMode getTouchMovementMode() const { return touchMoveMode; }
void setTouchMovementMode(TouchMovementMode setting);
bool getTouchMovementModeModified() const { return touchMoveModeModeModified; }
void setTouchMovementModeModified(bool setting);
ComputerMovementMode getComputerMovementMode() const { return computerMoveMode; }
void setComputerMovementMode(ComputerMovementMode setting);
bool getComputerMovementModeModified() const { return computerMoveModeModeModified; }
void setComputerMovementModeModified(bool setting);
RotationType getRotationType() const;
void setRotationType(RotationType setting);
void setMouseLock(bool isLocked);
bool isMouseLocked() const { return mouseLocked; }
void setCanMousePan(bool canPan) { canMousePan = canPan; }
bool getCanMousePan() { return canMousePan; }
void setFreeLook(bool canLook) { freeLook = canLook; }
bool getFreeLook() { return freeLook; }
bool inClassicMode() { return controlMode == CONTROL_CLASSIC; }
bool inMouseLockMode() { return controlMode == CONTROL_MOUSELOCK; }
bool inHybridMode() { return controlMode == CONTROL_HYBRID; }
bool inCamlockMode() { return controlMode == CONTROL_CAMLOCK; }
bool inMousepanMode() { return controlMode == CONTROL_MOUSEPAN; }
bool mouseLockedInMouseLockMode() { return inMouseLockMode() && isMouseLocked(); }
bool camLockedInCamLockMode() { return inCamlockMode() && !getFreeLook(); }
bool getTutorialState(std::string tutorialId);
void setTutorialState(std::string tutorialId, bool value);
std::string getCompletedTutorials() const;
void setCompletedTutorials(std::string value);
GameSettings::UploadSetting getUploadVideoSetting() const { return uploadVideos; }
void setUploadVideoSetting(GameSettings::UploadSetting setting);
GameSettings::UploadSetting getPostImageSetting() const { return uploadScreenshots; }
void setPostImageSetting(GameSettings::UploadSetting setting);
RenderQualitySetting getRenderQuality() const { return renderQualitySetting; }
void setRenderQuality(RenderQualitySetting value);
bool getAllTutorialsDisabled() const { return allTutorialsDisabled; }
void setAllTutorialsDisabled(bool value);
bool getFullScreenConst() const { return fullscreen; }
bool getFullScreen() { return fullscreen; }
void setFullScreen(bool value)
{
if(value != fullscreen)
{
fullscreen = value;
fullscreenChangedSignal(value);
}
}
Vector2 getStartScreenPos() const { return startScreenPos; }
void setStartScreenPos(Vector2 value);
Vector2 getStartScreenSize() const { return startScreenSize; }
void setStartScreenSize(Vector2 value);
bool getStartMaximized() const { return startMaximized; }
void setStartMaximized(bool value);
float getMasterVolume() const { return masterVolume; }
void setMasterVolume(float value);
float getMouseSensitivity() const;
void setMouseSensitivity(float value);
bool inStudioMode() { return studio; }
void setStudioMode(bool value)
{
if(value != studio)
{
studioModeChangedSignal(value);
studio = value;
}
}
bool getUsedHideHudShortcut() const { return usedHideHudShortcut; }
void setUsedHideHudShortcut(bool value) { usedHideHudShortcut = value; }
std::string getGoogleAnalyticsClientId() const;
void setGoogleAnalyticsClientId(const std::string& id);
/*override*/ void reset();
/*override*/ void verifySetParent(const Instance* instance) const;
void recordSettingsInGA(bool touchEnabled) const;
rbx::signal<void(bool)> fullscreenChangedSignal;
rbx::signal<void(bool)> studioModeChangedSignal;
private:
ControlMode controlMode;
RenderQualitySetting renderQualitySetting;
YearSettings currentYear;
CameraMode cameraMode;
TouchCameraMovementMode touchCameraMovementMode;
bool touchCameraMovementModeModified;
ComputerCameraMovementMode computerCameraMovementMode;
bool computerCameraMovementModeModified;
TouchMovementMode touchMoveMode;
bool touchMoveModeModeModified;
ComputerMovementMode computerMoveMode;
bool computerMoveModeModeModified;
RotationType rotationType;
bool mouseLocked;
bool canMousePan;
bool freeLook;
GameSettings::UploadSetting uploadVideos;
GameSettings::UploadSetting uploadScreenshots;
bool usedHideHudShortcut;
bool fullscreen;
bool studio;
Vector2 startScreenPos;
Vector2 startScreenSize;
bool startMaximized;
float masterVolume;
float mouseSensitivity;
std::map<std::string, bool> tutorialState;
bool allTutorialsDisabled;
std::string googleAnalyticsClientId;
};
}
+65
View File
@@ -0,0 +1,65 @@
#pragma once
#include "boost/scoped_ptr.hpp"
#include "boost/shared_ptr.hpp"
#include "boost/noncopyable.hpp"
#include "rbx/signal.h"
#include <vector>
#include <string>
#include "security/SecurityContext.h"
namespace RBX {
class Verb;
class CommonVerbs;
class DataModel;
class GameConfigurer;
// Encapsulates the creation of a DataModel used by client apps
class Game : boost::noncopyable
{
protected:
Game(Verb* lockVerb, const char* baseUrl, bool shouldShowLoadingScreen = false);
bool hasShutdown;
shared_ptr<GameConfigurer> gameConfigurer;
boost::shared_ptr<DataModel> dataModel;
public:
static void globalInit(bool isStudio);
static void globalExit();
std::vector<Verb*> verbs;
boost::shared_ptr<CommonVerbs> commonVerbs;
boost::shared_ptr<DataModel> getDataModel() const { return dataModel; }
void shutdown();
virtual ~Game(void);
void setupDataModel(const std::string& baseUrl);
bool getSuppressNavKeys();
void configurePlayer(RBX::Security::Identities identity, const std::string& params, int launchMode = -1, const char* vrDevice = 0);
private:
void doClearVerbs();
void clearVerbs(bool needsLock = true);
};
class SecurePlayerGame : public Game
{
public:
SecurePlayerGame(Verb* lockVerb, const char* baseUrl, bool shouldShowLoadingScreen = true);
};
class UnsecuredStudioGame : public Game
{
public:
UnsecuredStudioGame(Verb* lockVerb, const char* baseUrl, bool isNetworked = false, bool showLoadingScreen = false);
};
} // namespace RBX
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
namespace RBX {
extern const char* const sGamePassService;
class GamePassService
: public DescribedNonCreatable<GamePassService, Instance, sGamePassService>
, public Service
{
public:
GamePassService();
void setPlayerHasPassUrl(std::string);
void playerHasPass(shared_ptr<Instance> playerInstance, int gamePassId, boost::function<void(bool)> resumeFunction, boost::function<void(std::string)> errorFunction);
private:
template<typename ResultType>
void dispatchRequest(const std::string& url, boost::function<void(ResultType)> resumeFunction, boost::function<void(std::string)> errorFunction);
std::string playerHasPassUrl;
};
}
+50
View File
@@ -0,0 +1,50 @@
#pragma once
#include "V8DataModel/GlobalSettings.h"
namespace RBX
{
extern const char *const sGameSettings;
class GameSettings
: public GlobalAdvancedSettingsItem<GameSettings, sGameSettings>
{
public:
enum ChatMode { CHAT_AUTO = 0, CHAT_CLASSIC= 1, CHAT_BUBBLE= 2, CHAT_BOTH= 3 } ;
GameSettings();
int chatHistory;
int reportAbuseChatHistory;
int chatScrollLength;
bool soundEnabled;
bool softwareSound;
bool collisionSoundEnabled;
float collisionSoundVolume;
int maxCollisionSounds;
int bubbleChatMaxBubbles;
float bubbleChatLifetime;
float overscanPX;
float overscanPY;
rbx::signal<void(bool)> videoRecordingSignal;
typedef enum { LOW_RES = 0, MEDIUM_RES, HIGH_RES } VideoQuality;
typedef enum { NEVER = 0, ASK, ALWAYS } UploadSetting;
VideoQuality getVideoQualitySetting() const { return videoQuality; }
void setVideoQualitySetting(VideoQuality value);
GameSettings::UploadSetting getPostImageSetting() const;
void setPostImageSetting(GameSettings::UploadSetting setting);
bool hardwareMouse;
bool videoCaptureEnabled;
private:
VideoQuality videoQuality;
};
}
+93
View File
@@ -0,0 +1,93 @@
//
// GamepadService.h
// App
//
// Created by Ben Tkacheff on 1/21/15.
//
//
#pragma once
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#define RBX_MAX_GAMEPADS 8
namespace RBX
{
class BasePlayerGui;
extern const char* const sGamepadService;
typedef boost::unordered_map<RBX::KeyCode, shared_ptr<RBX::InputObject> > Gamepad;
typedef boost::unordered_map<int, Gamepad> Gamepads;
class GamepadService
: public DescribedNonCreatable<GamepadService, Instance, sGamepadService>
, public Service
{
private:
typedef DescribedNonCreatable<GamepadService, Instance, sGamepadService> Super;
Gamepads gamepads;
boost::unordered_map<InputObject::UserInputType, bool> gamepadNavigationEnabledMap;
RBX::Timer<RBX::Time::Fast> repeatGuiSelectionTimer;
RBX::Timer<RBX::Time::Fast> fastRepeatGuiSelectionTimer;
bool autoGuiSelectionAllowed; // whether this game allows for automatic gui selection with gamepad keys
Vector2 lastGuiSelectionDirection; // helper for determining how to use thumbstick for gui selection
rbx::signals::scoped_connection updateInputConnection;
rbx::signals::scoped_connection inputEndedConnection;
rbx::signals::scoped_connection inputChangedConnection;
rbx::signals::scoped_connection cameraCframeUpdateConnection;
shared_ptr<RBX::InputObject> createInputObjectForGamepadKeyCode(RBX::KeyCode keyCode, RBX::InputObject::UserInputType gamepadType);
void createControllerKeyMapForController(int controllerIndex);
Vector2 getGuiSelectionDirection(const shared_ptr<InputObject>& event);
bool isVectorInDeadzone(const Vector2& correctGuiDirection) const;
GuiResponse autoSelectGui();
GuiObject* getRandomShownGuiObject(Instance* object);
void currentCameraChanged(shared_ptr<Camera> newCurrentCamera);
void cameraCframeChanged(CoordinateFrame cframe);
void updateOnInputStep();
void onInputChanged(const shared_ptr<Instance>& event);
void onInputEnded(const shared_ptr<Instance>& event);
GuiResponse process(const shared_ptr<InputObject>& event, BasePlayerGui* guiToProcess);
// Instance
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
public:
GamepadService();
static InputObject::UserInputType getGamepadEnumForInt(int controllerIndex);
static int getGamepadIntForEnum(InputObject::UserInputType gamepadEnum);
Gamepad getGamepadState(int controllerIndex);
bool setAutoGuiSelectionAllowed(bool value);
bool getAutoGuiSelectionAllowed() const { return autoGuiSelectionAllowed; }
bool isNavigationGamepad(InputObject::UserInputType gamepadType);
void setNavigationGamepad(InputObject::UserInputType gamepadType, bool enabled);
boost::unordered_map<InputObject::UserInputType, bool> getNavigationGamepadMap() { return gamepadNavigationEnabledMap; }
GuiResponse processDev(const shared_ptr<InputObject>& event);
GuiResponse processCore(const shared_ptr<InputObject>& event);
GuiResponse trySelectGuiObject(const Vector2& inputVector, const shared_ptr<InputObject>& event, BasePlayerGui* guiToProcess);
GuiResponse trySelectGuiObject(const Vector2& inputVector);
};
}
+57
View File
@@ -0,0 +1,57 @@
#pragma once
#include "V8Tree/Service.h"
#include "Util/G3DCore.h"
#include "Util/Extents.h"
#include "G3D/Array.h"
#include "util/PartMaterial.h"
namespace RBX {
class PartInstance;
class Primitive;
class ContactManager;
class World;
class Workspace;
class Instance;
extern const char* const sGeometryService;
class GeometryService
: public DescribedNonCreatable<GeometryService, Instance, sGeometryService>
, public Service
{
private:
typedef DescribedNonCreatable<GeometryService, Instance, sGeometryService> Super;
Workspace *workspace;
G3D::Array<Primitive*> foundPrimitives;
public:
GeometryService();
Vector3 getHitLocationFilterStairs(Instance *ancestor, RBX::RbxRay ray, Primitive **hitPrim);
Vector3 getHitLocationFilterDescendents(Instance *ancestor, RBX::RbxRay ray, Primitive **hitPrim, Vector3& surfaceNormal, PartMaterial& surfaceMaterial, bool terrainCellsAreCubes, bool ignoreWaterCells);
Vector3 getHitLocationFilterDescendents(const Instances *ancestors, RBX::RbxRay ray, Primitive **hitPrim, Vector3& surfaceNormal, PartMaterial& surfaceMaterial, bool terrainCellsAreCubes, bool ignoreWaterCells);
// we template this function to avoid heavy code duplication: IgnoreType is currently either Instance or Instances
template<class IgnoreType>
Vector3 getHitLocationPartFilterDescendents(IgnoreType *ancestor, RBX::RbxRay ray, shared_ptr<PartInstance>& result, Vector3& surfaceNormal, PartMaterial& surfaceMaterial, bool terrainCellsAreCubes, bool ignoreWaterCells);
void getPartsTouchingExtents(
const Extents& extents,
const Primitive* ignore,
int maxCount,
G3D::Array<PartInstance*>& found);
void getPartsTouchingExtentsWithIgnore(
const Extents& extents,
const Instances* ancestors,
int maxCount,
G3D::Array<PartInstance*>& found);
protected:
virtual void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
};
}
+200
View File
@@ -0,0 +1,200 @@
#pragma once
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include "Script/ThreadRef.h"
namespace RBX {
// A generic mechanism for displaying stats (like 3D FPS, network traffic, etc.)
extern const char *const sSettings;
extern const char *const sSettingsItem;
class Settings
: public DescribedNonCreatable<Settings, ServiceProvider, sSettings>
{
private:
typedef DescribedNonCreatable<Settings, ServiceProvider, sSettings> Super;
struct InvalidDescendentDetector {
bool anyInvalid;
InvalidDescendentDetector();
static bool invalid(const Instance* instance);
void operator()(shared_ptr<Instance> descendant);
};
struct InvalidDescendentCollector {
std::vector< shared_ptr<Instance> > invalidInstances;
InvalidDescendentCollector();
void operator()(shared_ptr<Instance> descendant);
};
protected:
std::string settingsFile;
bool settingsErased;
///////////////////////////////
// overrides
virtual void verifyAddDescendant(const Instance* newParent,
const Instance* instanceGettingNewParent) const override;
public:
Settings(const std::string& settingsFile);
void setSaveTarget(const std::string& optGlobalSettingsFile) {
settingsFile = optGlobalSettingsFile;
}
void loadState(const std::string& optGlobalSettingsFile);
void saveState();
void eraseSettingsStore();
void removeInvalidChildren();
bool useSubmitTaskForLuaListeners() const override { return true; }
};
extern const char *const sGlobalBasicSettings;
class GlobalBasicSettings
: public DescribedNonCreatable<GlobalBasicSettings, Settings, sGlobalBasicSettings>
{
typedef DescribedNonCreatable<GlobalBasicSettings, Settings, sGlobalBasicSettings> Super;
public:
GlobalBasicSettings();
class Item : public NonFactoryProduct< Instance, sSettingsItem>
{
public:
virtual void reset() {}
bool useSubmitTaskForLuaListeners() const override { return true; }
protected:
bool askAddChild(const Instance* instance) const override
{
return dynamic_cast<const Item*>(instance)!=NULL;
}
};
boost::mutex mutex;
static shared_ptr<GlobalBasicSettings> singleton();
void reset();
bool isUserFeatureEnabled(std::string name);
void verifySetParent(const Instance* instance) const override;
};
extern const char *const sGlobalAdvancedSettings;
class GlobalAdvancedSettings
: public DescribedNonCreatable<GlobalAdvancedSettings, Settings, sGlobalAdvancedSettings>
{
typedef DescribedNonCreatable<GlobalAdvancedSettings, Settings, sGlobalAdvancedSettings> Super;
public:
GlobalAdvancedSettings();
~GlobalAdvancedSettings();
class Item : public NonFactoryProduct< Instance, sSettingsItem>
{
public:
bool useSubmitTaskForLuaListeners() const override { return true; }
protected:
bool askAddChild(const Instance* instance) const override
{
return dynamic_cast<const Item*>(instance)!=NULL;
}
};
shared_ptr<const RBX::Reflection::ValueTable> getFVariables();
std::string getFVariable(std::string flag);
bool getFFlag(std::string name);
boost::mutex mutex;
static shared_ptr<GlobalAdvancedSettings> singleton();
static GlobalAdvancedSettings* raw_singleton();
void verifySetParent(const Instance* instance) const override;
};
template<class Class, const char* const & sClassName>
class GlobalAdvancedSettingsItem
: public RBX::DescribedCreatable<Class, RBX::GlobalAdvancedSettings::Item, sClassName>
, public Service
{
typedef RBX::DescribedCreatable<Class, RBX::GlobalAdvancedSettings::Item, sClassName> Super;
static GlobalAdvancedSettingsItem* sing;
protected:
GlobalAdvancedSettingsItem()
{
Super::setName(sClassName);
if (sing)
throw RBX::runtime_error("singleton %s already exists", sClassName);
sing = this;
}
~GlobalAdvancedSettingsItem()
{
sing = NULL;
}
public:
static Class& singleton()
{
// shortcut
if (sing)
return *boost::polymorphic_downcast<Class*>(sing);
RBX::GlobalAdvancedSettings* gs = RBX::GlobalAdvancedSettings::singleton().get();
boost::mutex::scoped_lock lock(gs->mutex);
if (!sing)
{
// "s" won't get collected when we leave scope because the parent will hold a ref to it
shared_ptr<Class> s = Class::createInstance();
s->setParent(gs);
RBXASSERT(s.get()==sing);
}
return *boost::polymorphic_downcast<Class*>(sing);
}
};
template<class Class, const char* const & sClassName>
GlobalAdvancedSettingsItem<Class, sClassName>* GlobalAdvancedSettingsItem<Class, sClassName>::sing = NULL;
template<class Class, const char* const & sClassName>
class GlobalBasicSettingsItem
: public RBX::DescribedCreatable<Class, RBX::GlobalBasicSettings::Item, sClassName>
, public Service
{
typedef RBX::DescribedCreatable<Class, RBX::GlobalBasicSettings::Item, sClassName> Super;
static GlobalBasicSettingsItem* sing;
protected:
GlobalBasicSettingsItem()
{
Super::setName(sClassName);
if (sing)
throw RBX::runtime_error("singleton %s already exists", sClassName);
sing = this;
}
~GlobalBasicSettingsItem()
{
sing = NULL;
}
public:
static Class& singleton()
{
// shortcut
if (sing)
return *boost::polymorphic_downcast<Class*>(sing);
RBX::GlobalBasicSettings* gs = RBX::GlobalBasicSettings::singleton().get();
boost::mutex::scoped_lock lock(gs->mutex);
if (!sing)
{
// "s" won't get collected when we leave scope because the parent will hold a ref to it
shared_ptr<Class> s = Class::createInstance();
s->setParent(gs);
RBXASSERT(s.get()==sing);
}
return *boost::polymorphic_downcast<Class*>(sing);
}
virtual void resetSettings()
{}
};
template<class Class, const char* const & sClassName>
GlobalBasicSettingsItem<Class, sClassName>* GlobalBasicSettingsItem<Class, sClassName>::sing = NULL;
} // namespace
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "V8Tree/Service.h"
#include "V8Tree/Instance.h"
namespace RBX {
extern const char* const sGroupService;
class GroupService
: public DescribedCreatable<GroupService, Instance, sGroupService, Reflection::ClassDescriptor::INTERNAL_LOCAL>
, public Service
{
private:
static void onReceivedRawGroupInfoSuccess(weak_ptr<DataModel> weakDataModel, std::string response, boost::function<void(Reflection::Variant)> resumeFunction, boost::function<void(std::string)> errorFunction);
static void onReceivedRawGroupInfoError(weak_ptr<DataModel> weakDataModel, std::string error, boost::function<void(std::string)> errorFunction);
static void onReceivedRawGetGroupsSuccess(weak_ptr<DataModel> weakDataModel, std::string response, boost::function<void(shared_ptr<const Reflection::ValueArray>)> resumeFunction, boost::function<void(std::string)> errorFunction);
static void onReceivedRawGetGroupsError(weak_ptr<DataModel> weakDataModel, std::string error, boost::function<void(std::string)> errorFunction);
public:
GroupService();
void getGroupInfoAsync(const int groupId, boost::function<void(Reflection::Variant)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getAlliesAsync(const int groupId, boost::function<void(shared_ptr<Instance>)> resumeFunction, boost::function<void (std::string)> errorFunction);
void getEnemiesAsync(const int groupId, boost::function<void(shared_ptr<Instance>)> resumeFunction, boost::function<void (std::string)> errorFunction);
void getGroupsAsync(const int userId, boost::function<void(shared_ptr<const Reflection::ValueArray>)> resumeFunction, boost::function<void(std::string)> errorFunction);
};
}
+47
View File
@@ -0,0 +1,47 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "Gui/GuiEvent.h"
#include "Util/G3DCore.h"
#include "V8DataModel/InputObject.h"
#include "V8DataModel/UserInputService.h"
#include "GfxBase/IAdornable.h"
namespace RBX {
enum GuiQueue
{
GUIQUEUE_GENERAL = 0,
GUIQUEUE_TEXT,
GUIQUEUE_COUNT
};
extern const char* const sGuiBase;
class GuiBase : public DescribedNonCreatable<GuiBase, Instance, sGuiBase>
, public IAdornable
{
public:
GuiBase(const char* name);
static int minZIndex() {return 0;}
static int maxZIndex() {return 10;}
static int minZIndex2d() {return minZIndex() + 1;}
static int maxZIndex2d() {return maxZIndex();}
virtual GuiResponse process(const shared_ptr<InputObject>& event) { return GuiResponse::notSunk(); }
virtual bool canProcessMeAndDescendants() const = 0;
virtual GuiResponse processGesture(const UserInputService::Gesture& gesture, const shared_ptr<const RBX::Reflection::ValueArray>& touchPositions, const shared_ptr<const Reflection::Tuple>& args) { return GuiResponse::notSunk(); }
virtual int getZIndex() const = 0;
virtual GuiQueue getGuiQueue() const = 0;
private:
typedef DescribedNonCreatable<GuiBase, Instance, sGuiBase> Super;
};
}
+72
View File
@@ -0,0 +1,72 @@
#pragma once
#include "GuiBase.h"
namespace RBX {
extern const char* const sGuiBase2d;
//A set of base functionality used by all Lua bound Gui objects
class GuiBase2d : public DescribedNonCreatable<GuiBase2d, GuiBase, sGuiBase2d>
{
public:
GuiBase2d(const char* name);
virtual bool isGuiLeaf() const { return false; }
virtual Vector2 getAbsolutePosition() const { return absolutePosition; }
bool setAbsolutePosition(const Vector2& value, bool fireChangedEvent = true);
Vector2 getAbsoluteSize() const { return absoluteSize; }
bool setAbsoluteSize(const Vector2& value, bool fireChangedEvent = true);
Rect2D getRect2D() const; // four integers - maybe we should store size, position as a Rect2d (g3d version) or Rect (our version)?
Rect2D getRect2DFloat() const;
virtual Rect2D getChildRect2D() const { return getRect2DFloat(); }
virtual Rect2D getCanvasRect() const { return getChildRect2D(); }
virtual void handleResize(const Rect2D& viewport, bool force);
virtual bool recalculateAbsolutePlacement(const Rect2D& viewport);
/////////////////////////////////////////////////////////////
// Instance
//
/*override*/ bool askAddChild(const Instance* instance) const;
////////////////////////////////////////////////////////////////////////////////////
//
// GuiBase
/*implement*/ virtual bool canProcessMeAndDescendants() const { return true; }
/*implement*/ virtual int getZIndex() const { return zIndex; }
/*implement*/ virtual GuiQueue getGuiQueue() const { return guiQueue; }
////////////////////////////////////////////////////////////////////////////////////
//
// IAdornable
/*override*/ bool shouldRender2d() const { return false; } // explicit render traversal by ScreenGui or other.
/*override*/ bool isVisible(const Rect2D& rect) const { return rect.intersects(getRect2D()); }
static Reflection::PropDescriptor<GuiBase2d, Vector2> prop_AbsoluteSize;
static Reflection::PropDescriptor<GuiBase2d, Vector2> prop_AbsolutePosition;
protected:
void recursiveRender2d(Adorn* adorn);
void setGuiQueue(GuiQueue queue) { guiQueue = queue; }
Vector2 absolutePosition;
Vector2 absolutePositionFloat;
Vector2 absoluteSize;
Vector2 absoluteSizeFloat;
int zIndex;
GuiQueue guiQueue;
private:
typedef DescribedNonCreatable<GuiBase2d, GuiBase, sGuiBase2d> Super;
static void RecursiveRenderChildren(shared_ptr<RBX::Instance> instance, Adorn* adorn);
};
}
+52
View File
@@ -0,0 +1,52 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8Tree/Instance.h"
#include "Util/BrickColor.h"
#include "GuiBase.h"
namespace RBX {
extern const char* const sGuiBase3d;
//A base class for "adornment" instances (3D objects that adorn Instances)
class GuiBase3d
: public DescribedNonCreatable<GuiBase3d, GuiBase, sGuiBase3d>
{
public:
GuiBase3d(const char* name);
void setBrickColor(BrickColor value);
BrickColor getBrickColor() const { return BrickColor::closest(color); }
void setColor(Color3 value);
Color3 getColor() const { return color; }
void setTransparency(float value);
float getTransparency() const { return transparency; }
void setVisible(bool value);
bool getVisible() const { return visible;}
////////////////////////////////////////////////////////////////////////////////////
//
// IAdornable
/*override*/ bool shouldRender3dAdorn() const {return getVisible();}
////////////////////////////////////////////////////////////////////////////////////
//
// GuiBase
/*implement*/ virtual bool canProcessMeAndDescendants() const { return false; };
/*implement*/ virtual int getZIndex() const { return -1; }
/*implement*/ virtual GuiQueue getGuiQueue() const { return GUIQUEUE_GENERAL; }
protected:
Color3 color;
float transparency;
bool visible;
private:
typedef DescribedNonCreatable<GuiBase3d, GuiBase, sGuiBase3d> Super;
};
}
+130
View File
@@ -0,0 +1,130 @@
#pragma once
#include <string>
#include "util/object.h"
namespace RBX {
class Instance;
class TextDisplay;
class GuiRoot;
class TopMenuBar;
class Verb;
class DataModel;
class Workspace;
class ChatOption;
class UnifiedWidget;
class CustomStatsGuiJSON;
class GuiBuilder
{
public:
enum Display
{
DISPLAY_NONE,
DISPLAY_FPS,
DISPLAY_SUMMARY,
DISPLAY_PHYSICS,
DISPLAY_PHYSICS_AND_OWNER,
DISPLAY_RENDER
};
enum NetworkStats
{
NETWORKSTATS_INVALID = 0,
NETWORKSTATS_FIRST,
NETWORKSTATS_RAKNET = NETWORKSTATS_FIRST,
NETWORKSTATS_PHYSICS,
NETWORKSTATS_DATATYPE,
NETWORKSTATS_STREAMING,
NETWORKSTATS_COUNT
};
static Display getDebugDisplay();
static void setDebugDisplay(Display display);
void buildGui(
Workspace* workspace,
bool buildInGameGui);
// uses CoreGuiService and CoreScript to inject a lua gui into the game
void buildLuaGui();
void updateGui();
void addCustomStat(const std::string& name, const std::string& value);
void removeCustomStat(const std::string& name);
void saveCustomStats();
void Initialize(DataModel* dataModel);
friend class CustomStatsGuiJSON;
void removeSafeChatMenu();
void addSafeChatMenu();
void nextNetworkStats();
NetworkStats getDisplayingNetworkStats() {return networkStatsCounter;}
static void buildNetworkStatsOutput(shared_ptr<Instance> instance, std::string* output);
static void buildSimpleStatsOutput(shared_ptr<Instance> instance, std::string* output);
/// Stats Menu
void toggleGeneralStats();
void toggleRenderStats();
void toggleNetworkStats();
void togglePhysicsStats();
void toggleSummaryStats();
void toggleCustomStats();
private:
// Main Elements
shared_ptr<TopMenuBar> buildRightPalette();
shared_ptr<TopMenuBar> buildChatHud();
shared_ptr<TopMenuBar> buildChatMenu();
shared_ptr<TopMenuBar> buildStatsHud1();
shared_ptr<TopMenuBar> buildStatsHud2();
shared_ptr<TopMenuBar> buildRenderStats();
shared_ptr<TopMenuBar> buildNetworkStats();
shared_ptr<TopMenuBar> buildNetworkStats2(bool);
shared_ptr<TopMenuBar> buildFPS();
shared_ptr<TopMenuBar> buildPhysicsStats();
shared_ptr<TopMenuBar> buildPhysicsStats2();
shared_ptr<TopMenuBar> buildSummaryStats();
shared_ptr<TopMenuBar> buildCustomStats();
static void updatePerformanceBasedStat(shared_ptr<TextDisplay> item, float value, float greenCutoff, float yellowCutoff, float orangeCutoff, bool isBottleneck);
void updateSummaryStats(TopMenuBar* hudArray);
void updateCustomStats(TopMenuBar* hudArray);
Verb* getWhitelistVerb(const std::string& name);
void buildChatMenu(ChatOption *cur, std::string code, shared_ptr<UnifiedWidget> parentWidget);
DataModel* dataModel;
Workspace* workspace;
shared_ptr<TopMenuBar> safeChatMenu;
struct Data
{
std::string stat;
shared_ptr< TextDisplay > item;
};
typedef std::map< std::string, Data > CustomStatsContainer;
CustomStatsContainer customStatsCont;
NetworkStats networkStatsCounter;
bool oldTrackDataTypesValue;
bool oldTrackPhysicsDetailsValue;
};
} // namespace
+14
View File
@@ -0,0 +1,14 @@
/* Copyright 2003-2010 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "Gui/GUI.h"
#include "V8Tree/Verb.h"
namespace RBX
{
namespace Gui
{
enum WidgetState {NOTHING, HOVER, DOWN_OVER, DOWN_AWAY};
}
}
@@ -0,0 +1,66 @@
#pragma once
#include "Gui/GuiEvent.h"
#include "V8DataModel/InputObject.h"
#include "GuiBase.h"
#include "V8DataModel/GuiBase2d.h"
#include <boost/unordered_map.hpp>
namespace RBX {
class Instance;
class Adorn;
class GuiObject;
extern const char* const sLayerCollector;
// Controls the rendering order of GUI elements
class GuiLayerCollector : public DescribedNonCreatable<GuiLayerCollector, GuiBase2d, sLayerCollector>
{
protected:
GuiLayerCollector(const char* name);
public:
~GuiLayerCollector();
////////////////////////////////////////////////////////////////////////////////////
//
// GuiTarget
/*override*/ GuiResponse process(const shared_ptr<InputObject>& event, bool sinkIfMouseOver = true);
/*override*/ GuiResponse processGesture(const UserInputService::Gesture& gesture, const shared_ptr<const RBX::Reflection::ValueArray>& touchPositions, const shared_ptr<const Reflection::Tuple>& args);
void render2d(Adorn* adorn);
void render2dContext(Adorn* adorn, const Instance* context);
/*override*/ void onDescendantAdded(Instance* instance);
/*override*/ void onDescendantRemoving(const shared_ptr<Instance>& instance);
void getGuiObjectsForSelection(std::vector<GuiObject*>& guiObjects);
private:
typedef DescribedNonCreatable<GuiLayerCollector, GuiBase2d, sLayerCollector> Super;
typedef std::vector<shared_ptr<GuiBase> > GuiVector;
typedef std::vector<GuiVector> GuiLayers;
bool rebuildGuiVector;
static void LoadZ(const shared_ptr<RBX::Instance>& instance, GuiLayers guiVectors[]);
void loadZVectors();
void tryReleaseLastButtonDown(const shared_ptr<InputObject>& event);
GuiResponse processDescendants(const shared_ptr<InputObject>& event);
GuiResponse doProcessGesture(const boost::shared_ptr<GuiBase>& guiBase, const UserInputService::Gesture& gesture, const shared_ptr<const RBX::Reflection::ValueArray>& touchPositions, const shared_ptr<const Reflection::Tuple>& args);
void render2dStandardGuiElements(Adorn* adorn, const Instance* context, GuiVector& batch, const Rect2D& viewport);
void render2dTextGuiElements(Adorn* adorn, const Instance* context, GuiVector& batch, const Rect2D& viewport);
void descendantPropertyChanged(const shared_ptr<GuiBase>& gb, const Reflection::PropertyDescriptor* descriptor);
GuiLayers mGuiVectors[RBX::GUIQUEUE_COUNT]; // temp arrays for rendering - never realloc, always fast clear
boost::unordered_map<Instance*,rbx::signals::scoped_connection> propertyConnections;
};
}
+201
View File
@@ -0,0 +1,201 @@
#pragma once
#include <string>
#include "Util/BrickColor.h"
#include "Util/TextureId.h"
#include "Gui/ProfanityFilter.h"
#include "Gui/GuiDraw.h"
#include "Util/ContentFilter.h"
#include "V8DataModel/GuiObject.h"
namespace RBX
{
class GuiImageMixin
{
public:
GuiImageMixin()
: imageTransparency(0)
, imageColor(Color3::white())
, imageScale(GuiObject::SCALE_STRETCH)
, sliceCenter(Rect2D())
{
}
TextureId getImage() const { return image;}
Vector2 getImageRectOffset() const { return imageRectOffset; }
Vector2 getImageRectSize() const { return imageRectSize; }
float getImageTransparency() const { return imageTransparency; }
Color3 getImageColor3() const { return imageColor; }
Rect2D getSliceCenter() const { return sliceCenter; }
GuiObject::ImageScale getImageScale() const { return imageScale; }
protected:
TextureId image;
float imageTransparency;
Color3 imageColor;
Vector2 imageRectOffset;
Vector2 imageRectSize;
GuiDrawImage guiImageDraw;
Rect2D sliceCenter;
GuiObject::ImageScale imageScale;
};
#define DECLARE_GUI_IMAGE_MIXIN(Class) \
void setImage(TextureId value); \
void setImageRectOffset(Vector2 value); \
void setImageRectSize(Vector2 value); \
void setImageTransparency(float value); \
void setImageColor3(Color3 value); \
void setSliceCenter(Rect2D value); \
void setImageScale(ImageScale value); \
void renderStretched(Adorn* adorn); \
void renderSliced(Adorn* adorn); \
void renderImage(Adorn* adorn);
#define IMPLEMENT_GUI_IMAGE_MIXIN(Class) \
static const Reflection::PropDescriptor<Class, TextureId> prop_Image("Image", category_Image, &Class::getImage, &Class::setImage); \
static const Reflection::PropDescriptor<Class, Vector2> prop_ImageRectOffset("ImageRectOffset", category_Image, &Class::getImageRectOffset, &Class::setImageRectOffset); \
static const Reflection::PropDescriptor<Class, Vector2> prop_ImageRectSize("ImageRectSize", category_Image, &Class::getImageRectSize, &Class::setImageRectSize); \
static const Reflection::PropDescriptor<Class, float> prop_ImageTransparency("ImageTransparency", category_Image, &Class::getImageTransparency, &Class::setImageTransparency); \
static const Reflection::PropDescriptor<Class, Color3> prop_ImageColor3("ImageColor3", category_Image, &Class::getImageColor3, &Class::setImageColor3); \
static const Reflection::PropDescriptor<Class, Rect2D> prop_SliceCenter("SliceCenter", category_Image, &Class::getSliceCenter, &Class::setSliceCenter); \
static const Reflection::EnumPropDescriptor<Class, GuiObject::ImageScale> prop_ImageScale("ScaleType", category_Image, &Class::getImageScale, &Class::setImageScale); \
void Class::setImage(TextureId value) \
{ \
if(image != value){ \
image = value; \
raisePropertyChanged(prop_Image); \
} \
} \
void Class::setImageRectOffset(Vector2 value) \
{ \
if(imageRectOffset != value){ \
Rect2D offsetSliceCenter = Rect2D::xyxy(sliceCenter.x0y0() + value, sliceCenter.x1y1() + value); \
Rect2D imageRect = Rect2D::xywh(value, imageRectSize); \
if (sliceCenter != Rect2D::xywh(0,0,0,0) && !imageRect.contains(offsetSliceCenter)) \
{ \
RBX::StandardOut::singleton()->printf(MESSAGE_WARNING,"SliceCenter ((%f,%f), (%f,%f)) is outside the bounds of imageOffset ((%f,%f), (%f,%f)).", offsetSliceCenter.x0(),offsetSliceCenter.y0(),offsetSliceCenter.x1(), offsetSliceCenter.y1(), imageRect.x0(),imageRect.y0(),imageRect.x1(), imageRect.y1()); \
} \
imageRectOffset = value; \
raisePropertyChanged(prop_ImageRectOffset); \
} \
} \
void Class::setImageRectSize(Vector2 value) \
{ \
if(imageRectSize != value){ \
Rect2D offsetSliceCenter = Rect2D::xyxy(sliceCenter.x0y0() + imageRectOffset, sliceCenter.x1y1() + imageRectOffset); \
Rect2D imageRect = Rect2D::xywh(imageRectOffset, value); \
if (sliceCenter != Rect2D::xywh(0,0,0,0) && !imageRect.contains(offsetSliceCenter)) \
{ \
RBX::StandardOut::singleton()->printf(MESSAGE_WARNING,"SliceCenter ((%f,%f), (%f,%f)) is outside the bounds of imageOffset ((%f,%f), (%f,%f))", offsetSliceCenter.x0(),offsetSliceCenter.y0(),offsetSliceCenter.x1(), offsetSliceCenter.y1(), imageRect.x0(),imageRect.y0(),imageRect.x1(), imageRect.y1()); \
return; \
} \
imageRectSize = value; \
raisePropertyChanged(prop_ImageRectSize); \
} \
} \
void Class::setImageTransparency(float value) \
{ \
value = G3D::clamp(value, 0, 1); \
\
if(imageTransparency != value){ \
imageTransparency = value; \
raisePropertyChanged(prop_ImageTransparency); \
} \
} \
void Class::setImageColor3(Color3 value) \
{ \
if(imageColor != value){ \
imageColor = value; \
raisePropertyChanged(prop_ImageColor3); \
} \
} \
void Class::setSliceCenter(Rect2D value) \
{ \
if(sliceCenter != value) \
{ \
Rect2D offsetSliceCenter = Rect2D::xyxy(value.x0y0() + imageRectOffset, value.x1y1() + imageRectOffset); \
Rect2D imageRect = Rect2D::xywh(imageRectOffset, imageRectSize); \
if (imageRect != Rect2D::xywh(0,0,0,0) && !imageRect.contains(offsetSliceCenter)) \
{ \
RBX::StandardOut::singleton()->printf(MESSAGE_WARNING,"SliceCenter ((%f,%f), (%f,%f)) is outside the bounds of imageOffset ((%f,%f), (%f,%f))", offsetSliceCenter.x0(),offsetSliceCenter.y0(),offsetSliceCenter.x1(), offsetSliceCenter.y1(), imageRect.x0(),imageRect.y0(),imageRect.x1(), imageRect.y1()); \
} \
sliceCenter = value; \
raisePropertyChanged(prop_SliceCenter); \
} \
} \
void Class::setImageScale(ImageScale value) \
{ \
if(imageScale != value){ \
imageScale = value; \
raisePropertyChanged(prop_ImageScale); \
} \
} \
\
void Class::renderStretched(Adorn* adorn) \
{ \
Vector2 imageSize; \
if (guiImageDraw.setImage(adorn, image, GuiDrawImage::NORMAL, &imageSize, this, ".Image")) \
{ \
Vector2 texul, texbr; \
guiImageDraw.computeUV(texul, texbr, imageRectOffset, imageRectSize, imageSize); \
\
Color4 color = Color4(getImageColor3(), 1 - imageTransparency); \
\
GuiObject* clippingObject = firstAncestorClipping(); \
if( clippingObject == NULL || !absoluteRotation.empty()) \
guiImageDraw.render2d(adorn, true, getRect2D(), texul, texbr, color, absoluteRotation, Gui::NOTHING, false); \
else \
guiImageDraw.render2d(adorn, true, getRect2D(), texul, texbr, color, clippingObject->getClippedRect(), Gui::NOTHING, false); \
} \
} \
\
void Class::renderSliced(Adorn* adorn) \
{ \
TextureId selectImage = getImage(); \
\
if(guiImageDraw.setImage(adorn, selectImage, GuiDrawImage::NORMAL, NULL, this, ".Image")) \
{ \
Color4 rectColor = Color4(getImageColor3(), 1.0 - getImageTransparency()); \
Rect2D imageRectTextureOffset = Rect2D::xywh(imageRectOffset, imageRectSize); \
if (imageRectTextureOffset.width() > 0.0f && imageRectTextureOffset.height() > 0.0f) \
{ \
render2dScale9Impl2(adorn, selectImage, guiImageDraw, sliceCenter, firstAncestorClipping(), rectColor, NULL, &imageRectTextureOffset); \
} \
else \
{ \
render2dScale9Impl2(adorn, selectImage, guiImageDraw, sliceCenter, firstAncestorClipping(), rectColor); \
} \
} \
} \
\
void Class::renderImage(Adorn* adorn) \
{ \
switch (imageScale) \
{ \
case GuiObject::SCALE_STRETCH: \
{ \
renderStretched(adorn); \
break; \
} \
case GuiObject::SCALE_SLICED: \
{ \
renderSliced(adorn); \
break; \
} \
default: \
break; \
} \
\
renderStudioSelectionBox(adorn); \
}
} // namespace RBX
+531
View File
@@ -0,0 +1,531 @@
#pragma once
#include "V8DataModel/GuiCore.h"
#include "V8DataModel/GuiBase2d.h"
#include "V8DataModel/EventReplicator.h"
#include "V8DataModel/TextService.h"
#include "gui/GuiEvent.h"
#include "Util/BrickColor.h"
#include "Util/UDim.h"
#include "Util/TextureId.h"
#include "Util/Rotation2D.h"
#include "Gui/GuiDraw.h"
#include "Script/ThreadRef.h"
namespace RBX
{
class GuiDrawImage;
class TweenService;
class UserInputService;
extern const char* const sGuiObject;
class GuiObject
: public DescribedNonCreatable<GuiObject, GuiBase2d, sGuiObject>
{
private:
typedef DescribedNonCreatable<GuiObject, GuiBase2d, sGuiObject> Super;
public:
enum ImageScale
{
SCALE_STRETCH = 0,
SCALE_SLICED = 1
};
enum SizeConstraint
{
RELATIVE_XY = 0,
RELATIVE_XX = 1,
RELATIVE_YY = 2
};
enum TweenEasingDirection
{
EASING_DIRECTION_IN,
EASING_DIRECTION_OUT,
EASING_DIRECTION_IN_OUT
};
enum TweenEasingStyle
{
EASING_STYLE_LINEAR,
EASING_STYLE_SINE,
EASING_STYLE_BACK,
EASING_STYLE_QUAD,
EASING_STYLE_QUART,
EASING_STYLE_QUINT,
EASING_STYLE_BOUNCE,
EASING_STYLE_ELASTIC,
};
enum TweenStatus
{
TWEEN_CANCELED,
TWEEN_COMPLETED,
};
struct Tween
{
UDim2 start;
UDim2 end;
float elapsedTime;
float totalTime;
TweenEasingDirection style;
TweenEasingStyle variance;
float delayTime;
boost::function<void(TweenStatus)> callback;
Tween(const UDim2& start, const UDim2& end, float time, TweenEasingDirection style, TweenEasingStyle variance, float delayTime)
:start(start)
,end(end)
,elapsedTime(0)
,delayTime(delayTime)
,totalTime(time)
,style(style)
,variance(variance)
{}
bool isDone() const { return elapsedTime >= totalTime; }
};
struct Tweens
{
scoped_ptr<Tween> sizeTween;
scoped_ptr<Tween> positionTween;
bool empty() const { return !sizeTween && !positionTween; }
};
private:
static UDim2 TweenInterpolate(TweenEasingDirection style, TweenEasingStyle variance,
float elapsedTime, float totalTime, const UDim2& startValue, const UDim2& endValue);
static void UpdateTween(Tween& tween, GuiObject* obj, boost::function<void(GuiObject*, UDim2)> updateFunc, float timeStep);
bool descendantOfBillboardGui();
void fireGenericInputEvent(const shared_ptr<InputObject>& event);
void fireGestureEvent(const UserInputService::Gesture& gesture, const shared_ptr<const RBX::Reflection::ValueArray>& touchPositions, const shared_ptr<const Reflection::Tuple>& args);
scoped_ptr<Tweens> tweens;
bool selectionBox;
boost::unordered_map<const shared_ptr<InputObject>,bool> interactedInputObjects;
weak_ptr<GuiObject> nextSelectionUp;
weak_ptr<GuiObject> nextSelectionDown;
weak_ptr<GuiObject> nextSelectionLeft;
weak_ptr<GuiObject> nextSelectionRight;
shared_ptr<GuiObject> selectionImageObject;
InputObject::UserInputType lastMouseDownType;
// use for dragging gui objects
bool draggable;
bool dragging;
Vector2 lastMousePosition;
rbx::signals::scoped_connection draggingEndedConnection;
shared_ptr<InputObject> draggingBeganInputObject;
void draggingEnded(const shared_ptr<Instance>& event);
public:
bool tweenStep(const double& timeStep);
bool tweenSizeAndPosition(UDim2 endSize, UDim2 endPosition, TweenEasingDirection style, TweenEasingStyle variance, float time, bool overwrite, Lua::WeakFunctionRef callback);
bool tweenPosition(UDim2 endPosition, TweenEasingDirection style, TweenEasingStyle variance, float time, bool overwrite, Lua::WeakFunctionRef callback);
bool tweenPosition(UDim2 endPosition, TweenEasingDirection style, TweenEasingStyle variance,float time, bool overwrite, bool removeOnCallback);
bool tweenPosition(UDim2 endPosition, TweenEasingDirection style, TweenEasingStyle variance,float time, bool overwrite, bool removeOnCallback, TweenService* tweenService);
bool tweenSize(UDim2 endSize, TweenEasingDirection style, TweenEasingStyle variance, float time, bool overwrite, Lua::WeakFunctionRef callback);
bool tweenPositionDelay(UDim2 startValue, UDim2 endValue, float time, TweenEasingDirection style, TweenEasingStyle variance, float delay, bool overwrite, boost::function<void(TweenStatus)> callback);
bool tweenPositionDelay(UDim2 startValue, UDim2 endValue, float time, TweenEasingDirection style, TweenEasingStyle variance, float delay, bool overwrite, boost::function<void(TweenStatus)> callback, TweenService* tweenService);
bool tweenSizeDelay(UDim2 startValue, UDim2 endValue, float time, TweenEasingDirection style, TweenEasingStyle variance, float delay, bool overwrite, boost::function<void(TweenStatus)> callback);
virtual Rect2D getClippedRect();
static float convertFontSize(TextService::FontSize size)
{
switch(size)
{
case TextService::SIZE_8 : return 8;
case TextService::SIZE_9 : return 9;
case TextService::SIZE_10: return 10;
case TextService::SIZE_11: return 11;
case TextService::SIZE_12: return 12;
case TextService::SIZE_14: return 14;
case TextService::SIZE_18: return 18;
case TextService::SIZE_24: return 24;
case TextService::SIZE_36: return 36;
case TextService::SIZE_48: return 48;
case TextService::SIZE_28: return 28;
case TextService::SIZE_32: return 32;
case TextService::SIZE_42: return 42;
case TextService::SIZE_60: return 60;
case TextService::SIZE_96: return 96;
default:
RBXASSERT(0);
return 0;
}
}
GuiObject(const char* name, bool active);
static const Reflection::PropDescriptor<GuiObject, bool> prop_Visible;
static const Reflection::PropDescriptor<GuiObject, int> prop_ZIndex;
void setSize(UDim2 value);
UDim2 getSize() const { return size; }
void setSizeConstraint(SizeConstraint value);
SizeConstraint getSizeConstraint() const { return sizeConstraint; }
void setPosition(UDim2 value);
UDim2 getPosition() const { return position; }
void setRotation(float value);
float getRotation() const { return rotation.getValue(); }
bool setAbsoluteRotation(const Rotation2D& value);
const Rotation2D& getAbsoluteRotation() const { return absoluteRotation; }
void setBorderSizePixel(int value);
int getBorderSizePixel() const { return borderSizePixel; }
void setDraggable(bool value);
bool getDraggable() const { return draggable; }
bool getClipping() const { return clipping; }
void setClipping(bool value);
// used to show a selection box around the gui (used when selected in tree)
void setSelectionBox(bool value) { selectionBox = value; }
bool getSelectionBox() const {return selectionBox; }
GuiObject* getNextSelectionUp() const;
void setNextSelectionUp(GuiObject* value);
GuiObject* getNextSelectionDown() const;
void setNextSelectionDown(GuiObject* value);
GuiObject* getNextSelectionLeft() const;
void setNextSelectionLeft(GuiObject* value);
GuiObject* getNextSelectionRight() const;
void setNextSelectionRight(GuiObject* value);
GuiObject* firstAncestorClipping();
void handleDrag(RBX::Vector2 mousePosition);
void handleDragging(const shared_ptr<InputObject>& event);
void handleDragBegin(RBX::Vector2 mousePosition);
Gui::WidgetState getGuiState() const { return guiState; }
void setGuiState(Gui::WidgetState state) { guiState = state; }
void setZIndex(int value);
void setBorderColor(BrickColor value);
BrickColor getBorderColor() const { return BrickColor::closest(borderColor); }
void setBorderColor3(Color3 value);
Color3 getBorderColor3() const { return borderColor; }
void setBackgroundColor(BrickColor value);
BrickColor getBackgroundColor() const { return BrickColor::closest(backgroundColor); }
void setBackgroundColor3(Color3 value);
Color3 getBackgroundColor3() const { return backgroundColor; }
void setVisible(bool value);
bool getVisible() const { return visible; }
void setActive(bool value);
bool getActive() const { return active; }
/*override*/ bool canProcessMeAndDescendants() const {return getVisible();}
// determines whether a gamepad/keyboard can move the selection to this object
void setSelectable(bool value);
bool getSelectable() const { return selectable; }
void setBackgroundTransparency(float value);
float getBackgroundTransparency() const { return backgroundTransparency; }
virtual void setTransparencyLegacy(float value) { setBackgroundTransparency(value); }
float getTransparencyLegacy() const { return getBackgroundTransparency(); }
bool isCurrentlyVisible();
// Selection Events
rbx::signal<void()> selectionGainedEvent;
rbx::signal<void()> selectionLostEvent;
// low level generic event signals
rbx::signal<void(shared_ptr<Instance>)> inputBeganEvent;
rbx::signal<void(shared_ptr<Instance>)> inputChangedEvent;
rbx::signal<void(shared_ptr<Instance>)> inputEndedEvent;
// touch gesture event signals
rbx::signal<void(shared_ptr<const RBX::Reflection::ValueArray>)> tapGestureEvent;
rbx::signal<void(shared_ptr<const RBX::Reflection::ValueArray>,float, float, InputObject::UserInputState)> pinchGestureEvent;
rbx::signal<void(UserInputService::SwipeDirection, int)> swipeGestureEvent;
rbx::signal<void(shared_ptr<const RBX::Reflection::ValueArray>, InputObject::UserInputState)> longPressGestureEvent;
rbx::signal<void(shared_ptr<const RBX::Reflection::ValueArray>, float, float, InputObject::UserInputState)> rotateGestureEvent;
rbx::signal<void(shared_ptr<const RBX::Reflection::ValueArray>, Vector2, Vector2, InputObject::UserInputState)> panGestureEvent;
rbx::remote_signal<void(int, int)> mouseEnterSignal;
rbx::remote_signal<void(int, int)> mouseLeaveSignal;
rbx::remote_signal<void(int, int)> mouseMovedSignal;
rbx::remote_signal<void(int, int)> mouseWheelForwardSignal;
rbx::remote_signal<void(int, int)> mouseWheelBackwardSignal;
DECLARE_EVENT_REPLICATOR_SIG(GuiObject,MouseEnter, void(int,int));
DECLARE_EVENT_REPLICATOR_SIG(GuiObject,MouseLeave, void(int,int));
DECLARE_EVENT_REPLICATOR_SIG(GuiObject,MouseMoved, void(int,int));
DECLARE_EVENT_REPLICATOR_SIG(GuiObject,MouseWheelForward, void(int,int));
DECLARE_EVENT_REPLICATOR_SIG(GuiObject,MouseWheelBackward, void(int,int));
rbx::remote_signal<void(int, int)> dragStoppedSignal;
rbx::remote_signal<void(UDim2)> dragBeginSignal;
DECLARE_EVENT_REPLICATOR_SIG(GuiObject,DragStopped, void(int, int));
DECLARE_EVENT_REPLICATOR_SIG(GuiObject,DragBegin, void(UDim2));
/////////////////////////////////////////////////////////////
// Instance
//
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ void onAncestorChanged(const AncestorChanged& event);
/*override*/ void onPropertyChanged(const Reflection::PropertyDescriptor& descriptor);
/*override*/ int getPersistentDataCost() const
{
return Super::getPersistentDataCost() + 6;
}
/////////////////////////////////////////////////////////////
// GuiBase2d
//
/*override*/ bool recalculateAbsolutePlacement(const Rect2D& parentViewport);
/*override*/ Vector2 getAbsolutePosition() const;
////////////////////////////////////////////////////////////////////////////////////
//
// IAdornable
/*override*/ void render2d(Adorn* adorn);
void legacyRender2d(Adorn* adorn, const Rect2D& parentRectangle);
void renderSelectionFrame(Adorn* adorn, GuiObject* selectionImageObject);
virtual void renderStudioSelectionBox(Adorn* adorn);
////////////////////////////////////////////////////////////////////////////////////
//
// GuiBase
/*override*/ GuiResponse process(const shared_ptr<InputObject>& event);
/*override*/ GuiResponse processGesture(const UserInputService::Gesture& gesture, const shared_ptr<const RBX::Reflection::ValueArray>& touchPositions, const shared_ptr<const Reflection::Tuple>& args);
virtual GuiResponse preProcess(const shared_ptr<InputObject>& event) { return GuiResponse::notSunk(); };
virtual void checkForResize();
GuiObject* getSelectionImageObject() const {return selectionImageObject.get();}
void setSelectionImageObject(GuiObject* value);
protected:
virtual void setServerGuiObject();
bool serverGuiObject;
bool clipping;
Gui::WidgetState guiState;
UDim2 size;
UDim2 position;
RotationAngle rotation;
Rotation2D absoluteRotation;
SizeConstraint sizeConstraint;
int borderSizePixel;
Color3 backgroundColor;
Color3 borderColor;
bool visible;
bool active;
bool selectable;
float backgroundTransparency;
//float getAlpha() const;
float getRenderBackgroundAlpha() const;
Color4 getRenderBackgroundColor4() const;
float getFontSizeScale(bool _textScale, bool _textWrap, TextService::FontSize _fontSizeEnum, const Rect2D& rect);
float getScaledFontSize(const Rect2D& rect, const std::string& _textName, TextService::Font _font, bool _textWrap, float _fontSize);
void render2dImpl( Adorn* adorn,
const Color4& _backgroundColor);
void render2dImpl( Adorn* adorn,
const Color4& _backgroundColor,
Rect2D& rect);
Vector2 render2dTextImpl( Adorn* adorn,
const Color4& _backgroundColor,
const std::string& textName,
TextService::Font _font,
TextService::FontSize fontSize,
const Color4& textColor,
const Color4& textStrokeColor,
bool textWrap,
bool textScale,
TextService::XAlignment _xalign,
TextService::YAlignment _yalign);
Vector2 render2dTextImpl( Adorn* adorn,
const Rect2D& rectIn,
const std::string& textName,
TextService::Font _font,
TextService::FontSize fontSize,
const Color4& textColor,
const Color4& textStrokeColor,
bool textWrap,
bool textScale,
TextService::XAlignment _xalign,
TextService::YAlignment _yalign);
void render2dScale9Impl( Adorn* adorn,
const TextureId& texId,
const Vector2int16& scaleEdgeSize,
const Vector2& minSize,
GuiDrawImage& guiImageDraw,
Rect2D& rect,
GuiObject* clippingObject);
void render2dScale9Impl2(Adorn* adorn,
const TextureId& texId,
GuiDrawImage& guiImageDraw,
Rect2D& scaleRect,
GuiObject* clippingObject,
Color4& color,
Rect2D* overrideRect = NULL,
Rect2D* imageOffsetRect = NULL);
virtual GuiResponse processTouchEvent(const shared_ptr<InputObject>& event);
virtual GuiResponse processMouseEvent(const shared_ptr<InputObject>& event);
virtual GuiResponse processMouseEventInternal(const shared_ptr<InputObject>& event, bool fireEvents);
virtual GuiResponse preProcessMouseEvent(const shared_ptr<InputObject>& event) { return GuiResponse::notSunk(); };
virtual GuiResponse processKeyEvent(const shared_ptr<InputObject>& event);
virtual GuiResponse processGamepadEvent(const shared_ptr<InputObject>& event);
static Rect2D Scale9Rect2D(const Rect2D& rect, float border, float minSize);
void forceResize();
bool mouseIsOver(const Vector2& mousePosition);
bool isSelectedObject();
};
extern const char* const sGuiButton;
class GuiButton
: public DescribedNonCreatable<GuiButton, GuiObject, sGuiButton>
{
private:
typedef DescribedNonCreatable<GuiButton, GuiObject, sGuiButton> Super;
bool clicked;
bool shouldFireClickedEvent;
weak_ptr<InputObject> lastSelectedObjectEvent;
GuiResponse checkForSelectedObjectClick(const shared_ptr<InputObject>& event);
public:
GuiButton(const char* name);
enum Style
{
CUSTOM_STYLE = 0,
ROBLOX_RED_STYLE = 1,
ROBLOX_GREY_STYLE = 2,
ROBLOX_BUTTON_ROUND_STYLE = 3,
ROBLOX_BUTTON_ROUND_DEFAULT_STYLE = 4,
ROBLOX_BUTTON_ROUND_DROPDOWN_STYLE = 5,
};
static const Reflection::PropDescriptor<GuiButton, bool> prop_Modal;
rbx::remote_signal<void()> mouseButton1ClickSignal;
rbx::remote_signal<void()> mouseButton2ClickSignal;
rbx::remote_signal<void(int, int)> mouseButton1DownSignal;
rbx::remote_signal<void(int, int)> mouseButton1UpSignal;
rbx::remote_signal<void(int, int)> mouseButton2DownSignal;
rbx::remote_signal<void(int, int)> mouseButton2UpSignal;
DECLARE_EVENT_REPLICATOR_SIG(GuiButton,MouseButton1Click, void());
DECLARE_EVENT_REPLICATOR_SIG(GuiButton,MouseButton2Click, void());
DECLARE_EVENT_REPLICATOR_SIG(GuiButton,MouseButton1Down, void(int,int));
DECLARE_EVENT_REPLICATOR_SIG(GuiButton,MouseButton1Up, void(int,int));
DECLARE_EVENT_REPLICATOR_SIG(GuiButton,MouseButton2Down, void(int,int));
DECLARE_EVENT_REPLICATOR_SIG(GuiButton,MouseButton2Up, void(int,int));
bool getAutoButtonColor() const { return autoButtonColor; }
void setAutoButtonColor(bool value);
bool getSelected() const { return selected; }
void setSelected(bool value);
Style getStyle() const { return style; }
void setStyle(Style value);
/*override*/ bool isGuiLeaf() const { return true; }
/////////////////////////////////////////////////////////////
// Instance
//
/*override*/ void onPropertyChanged(const Reflection::PropertyDescriptor& descriptor);
/////////////////////////////////////////////////////////////
// GuiBase2d
//
/*override*/ GuiResponse processMouseEvent(const shared_ptr<InputObject>& event);
/*override*/ GuiResponse processGamepadEvent(const shared_ptr<InputObject>& event);
/*override*/ GuiResponse processKeyEvent(const shared_ptr<InputObject>& event);
/*override*/ GuiResponse processTouchEvent(const shared_ptr<InputObject>& event);
/*override*/ Rect2D getChildRect2D() const;
void render2dButtonImpl(Adorn* adorn, Rect2D& rect);
bool getClicked() {return clicked;}
void setClicked(bool value) {clicked = value;}
bool getModal() const { return modal; }
void setModal(bool value);
void setVerb(std::string verbString);
Verb* getVerb() { return verb; }
protected:
/*override*/ void setServerGuiObject();
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
bool autoButtonColor;
bool selected;
bool modal;
Style style;
Verb* verb;
std::string verbToSet;
boost::scoped_array<GuiDrawImage> images;
};
extern const char* const sGuiLabel;
class GuiLabel
: public DescribedNonCreatable<GuiLabel, GuiObject, sGuiLabel>
{
public:
GuiLabel(const char* name);
/*override*/ bool isGuiLeaf() const { return true; }
};
}
+190
View File
@@ -0,0 +1,190 @@
#pragma once
#include "V8DataModel/InputObject.h"
#include "v8datamodel/GuiObject.h"
#include "V8Tree/Service.h"
namespace RBX {
namespace Lua
{
class WeakFunctionRef;
}
extern const char* const sGuiService;
class GuiService
: public DescribedNonCreatable<GuiService, Instance, sGuiService, Reflection::ClassDescriptor::INTERNAL_LOCAL>
, public Service
{
public:
typedef std::pair<weak_ptr<GuiObject>, shared_ptr<const Reflection::Tuple> > SelectionGroupPair;
typedef boost::unordered_map<std::string, SelectionGroupPair> SelectionMap;
static Reflection::RefPropDescriptor<GuiService, GuiObject> prop_selectedGuiObject;
static Reflection::RefPropDescriptor<GuiService, GuiObject> prop_selectedCoreGuiObject;
private:
typedef DescribedNonCreatable<GuiService, Instance, sGuiService, Reflection::ClassDescriptor::INTERNAL_LOCAL> Super;
Vector4 guiInset; // user's GUIs will be rendered inset by x,y in the top-left corner and by z,w in the bottom-right
rbx::signals::scoped_connection screenGuiConnection;
std::string errorMessage;
std::string uiMessage;
SelectionMap selectionMap;
bool gamepadNavEnabled;
bool coreGamepadNavEnabled;
bool menuOpen;
void getScreenResolutionNoRetry(boost::function<void(Vector2)> resumeFunction, boost::function<void(std::string)> errorFunction);
public:
int getBrickCount();
shared_ptr<Instance> getClosestDialogToPosition(Vector3 position);
// Show Stats based on Input
bool showStatsBasedOnInputString(std::string inputText);
bool getModalDialogStatus() const;
bool getIsWindows() const {
#ifdef _WIN32
return true;
#else
return false;
#endif
};
enum SpecialKey
{
KEY_INSERT = 0,
KEY_HOME = 1,
KEY_END = 2,
KEY_PAGEUP = 3,
KEY_PAGEDOWN = 4,
KEY_CHATHOTKEY = 5,
};
enum CenterDialogType
{
CENTER_DIALOG_UNSOLICITED_DIALOG = 1,
CENTER_DIALOG_PLAYER_INITIATED_DIALOG = 2,
CENTER_DIALOG_MODAL_DIALOG = 3,
CENTER_DIALOG_QUIT_DIALOG = 4,
};
enum UiMessageType
{
UIMESSAGE_ERROR,
UIMESSAGE_INFO
};
void addCenterDialog(shared_ptr<Instance> dialog, GuiService::CenterDialogType type, Lua::WeakFunctionRef show, Lua::WeakFunctionRef hide);
void removeCenterDialog(shared_ptr<Instance> dialog);
void openBrowserWindow(std::string url);
GuiService();
rbx::signal<void(std::string)> openUrlWindow;
rbx::signal<void()> urlWindowClosed;
rbx::signal<void(std::string, std::string)> keyPressed;
rbx::signal<void()> escapeKeyPressed;
rbx::signal<void(GuiService::SpecialKey, std::string)> specialKeyPressed;
rbx::signal<void(std::string)> newErrorSignal;
rbx::signal<void(UiMessageType, std::string)> newUiMessageSignal;
rbx::signal<void()> showLeaveConfirmationSignal;
rbx::signal<void()> menuOpenedSignal;
rbx::signal<void()> menuClosedSignal;
void fireMenuOpenedSignal() { menuOpenedSignal(); }
void fireMenuClosedSignal() { menuClosedSignal(); }
void setMenuOpen(bool value);
bool getMenuOpen() const { return menuOpen; }
void addKey(std::string);
void removeKey(std::string);
void addSpecialKey(GuiService::SpecialKey);
void removeSpecialKey(SpecialKey key);
bool dispatchKey(GuiService::SpecialKey);
bool processKeyDown(const shared_ptr<RBX::InputObject>& event);
const Vector4& getGlobalGuiInset() const { return guiInset; }
void setGlobalGuiInset(int x1, int y1, int x2, int y2); // in pixels
Vector2 getScreenResolution();
void getScreenResolutionLua(boost::function<void(Vector2)> resumeFunction, boost::function<void(std::string)> errorFunction);
void setErrorMessage(std::string newErrorMessage);
std::string getErrorMessage();
void setUiMessage(UiMessageType msgType, std::string newErrorMessage);
std::string getUiMessage();
void toggleFullscreen();
bool isTenFootInterface();
// gamepad ui navigation features
GuiObject* getSelectedGuiObjectLua() const;
void setSelectedGuiObjectLua(GuiObject* value);
GuiObject* getSelectedCoreGuiObjectLua() const;
void setSelectedCoreGuiObjectLua(GuiObject* value);
GuiObject* getSelectedGuiObject();
void addSelectionGroup(std::string selectionGroupName, shared_ptr<Instance> selectionParent);
void addSelectionGroup(std::string selectionGroupName, shared_ptr<const Reflection::Tuple> selectionTuple);
void removeSelectionGroup(std::string selectionGroupName);
SelectionGroupPair getSelectedObjectGroup(shared_ptr<GuiObject> object);
bool getGamepadNavEnabled() const { return gamepadNavEnabled; }
void setGamepadNavEnabled(bool value);
bool getCoreGamepadNavEnabled() const { return coreGamepadNavEnabled; }
void setCoreGamepadNavEnabled(bool value);
bool getAutoGuiSelectionAllowed() const;
void setAutoGuiSelectionAllowed(bool value);
typedef boost::function<void(std::string, std::string, Reflection::AsyncCallbackDescriptor::ResumeFunction, Reflection::AsyncCallbackDescriptor::ErrorFunction)> NotificationCallback;
NotificationCallback notificationCallback;
protected:
bool hasSpecial(SpecialKey key);
struct DialogWrapper
{
weak_ptr<GuiObject> dialog;
CenterDialogType dialogType;
boost::function<void()> showFunction;
boost::function<void()> hideFunction;
};
DialogWrapper* currentDialog;
bool shouldPreemptCurrentDialog(DialogWrapper* newDialog) const;
void queueDialogWrapper(DialogWrapper* newDialog, bool preempted);
bool showWaitingDialog(CenterDialogType type);
std::map<CenterDialogType, std::list<DialogWrapper*> > dialogQueue;
std::map<boost::weak_ptr<GuiObject>, DialogWrapper*> dialogWrapperMap;
// TODO: Perf: Make this a boost::array<char, 256>
std::set<char> subscribedChars;
std::set<SpecialKey> subscribedSpecials;
};
}
+347
View File
@@ -0,0 +1,347 @@
#pragma once
#include "Util/BrickColor.h"
#include "Util/TextureId.h"
#include "Gui/ProfanityFilter.h"
#include "Util/ContentFilter.h"
#include "GfxBase/Typesetter.h"
#include "V8DataModel/TextService.h"
#include "security/SecurityContext.h"
#include "Network/Players.h"
#define category_Text "Text"
namespace RBX {
class GuiTextMixin
{
public:
GuiTextMixin(const std::string& text, const Color3& textColor)
: text(text)
, fontSize(TextService::SIZE_8)
, textColor(textColor)
, textTransparency(0)
, textWrap(false)
, textScale(false)
, filterState(ContentFilter::Waiting)
, xAlignment(TextService::XALIGNMENT_CENTER)
, yAlignment(TextService::YALIGNMENT_CENTER)
, font(TextService::FONT_LEGACY)
, textStrokeTransparency(1.0f)
, textStrokeColor(0,0,0)
{}
const std::string& getText() const { return text; }
TextService::FontSize getFontSize() const { return fontSize; }
TextService::Font getFont() const { return font; }
BrickColor getTextColor() const { return BrickColor::closest(textColor); }
Color3 getTextColor3() const { return textColor; }
float getTextTransparency() const { return textTransparency; }
float getTextStrokeTransparency() const { return textStrokeTransparency; }
Color3 getTextStrokeColor3() const { return textStrokeColor; }
bool getTextWrap() const { return textWrap; }
bool getTextScale() const { return textScale; }
TextService::XAlignment getXAlignment() const { return xAlignment; }
TextService::YAlignment getYAlignment() const { return yAlignment; }
protected:
float getRenderTextAlpha(float transparency) const
{
return G3D::clamp(1.0f - transparency, 0.0f, 1.0f);
}
Color4 getRenderTextColor4() const
{
return Color4(textColor,getRenderTextAlpha(getTextTransparency()));
}
Color4 getRenderTextStrokeColor4() const
{
return Color4(textStrokeColor,getRenderTextAlpha(getTextStrokeTransparency()));
}
ContentFilter::FilterResult filterState;
std::string text;
TextService::FontSize fontSize;
Color3 textColor;
float textTransparency;
Color3 textStrokeColor;
float textStrokeTransparency;
bool textWrap;
bool textScale;
TextService::XAlignment xAlignment;
TextService::YAlignment yAlignment;
TextService::Font font;
};
#define DECLARE_GUI_TEXT_MIXIN() \
/*override*/ void checkForResize(); \
void setText(std::string value); \
void setFontSize(TextService::FontSize value); \
void setFont(TextService::Font value); \
void setTextColor(BrickColor value); \
void setTextColor3(Color3 value); \
void setTextTransparency(float value); \
void setTextStrokeTransparency(float value); \
void setTextStrokeColor3(Color3 value); \
void setTextWrap(bool value); \
void setTextScale(bool value); \
void setXAlignment(TextService::XAlignment value); \
void setYAlignment(TextService::YAlignment value); \
int getPosInString(RBX::Vector2 cursorPos) const; \
Vector2 getTextBounds() const; \
bool getTextFits() const; \
/*override */ void setTransparencyLegacy(float value); \
/*override*/ int getPersistentDataCost() const;
#define IMPLEMENT_GUI_TEXT_MIXIN(Class) \
REFLECTION_BEGIN(); \
static const Reflection::PropDescriptor<Class, std::string> prop_Text("Text", category_Text, &Class::getText, &Class::setText); \
static const Reflection::EnumPropDescriptor<Class, TextService::FontSize> prop_FontSize("FontSize", category_Text, &Class::getFontSize, &Class::setFontSize); \
static const Reflection::EnumPropDescriptor<Class, TextService::Font> prop_Font("Font", category_Text, &Class::getFont, &Class::setFont); \
static const Reflection::PropDescriptor<Class, BrickColor> prop_TextColor("TextColor", category_Text, &Class::getTextColor, &Class::setTextColor, Reflection::PropertyDescriptor::LEGACY_SCRIPTING); \
static const Reflection::PropDescriptor<Class, Color3> prop_TextColor3("TextColor3", category_Text, &Class::getTextColor3, &Class::setTextColor3); \
static const Reflection::PropDescriptor<Class, float> prop_TextTransparency("TextTransparency", category_Text, &Class::getTextTransparency, &Class::setTextTransparency); \
static const Reflection::PropDescriptor<Class, bool> prop_TextWrap("TextWrapped", category_Text, &Class::getTextWrap, &Class::setTextWrap); \
static const Reflection::PropDescriptor<Class, bool> prop_depTextWrap("TextWrap", category_Text, &Class::getTextWrap, &Class::setTextWrap, Reflection::PropertyDescriptor::Attributes::deprecated(prop_TextWrap, Reflection::PropertyDescriptor::UI)); \
static const Reflection::PropDescriptor<Class, bool> prop_TextScale("TextScaled", category_Text, &Class::getTextScale, &Class::setTextScale); \
static const Reflection::EnumPropDescriptor<Class, TextService::XAlignment> prop_TextXAlignment("TextXAlignment", category_Text, &Class::getXAlignment, &Class::setXAlignment); \
static const Reflection::EnumPropDescriptor<Class, TextService::YAlignment> prop_TextYAlignment("TextYAlignment", category_Text, &Class::getYAlignment, &Class::setYAlignment); \
static const Reflection::PropDescriptor<Class, Vector2> prop_TextBounds("TextBounds", category_Text, &Class::getTextBounds, NULL, Reflection::PropertyDescriptor::UI); \
static const Reflection::PropDescriptor<Class, bool> prop_TextFits("TextFits", category_Text, &Class::getTextFits, NULL, Reflection::PropertyDescriptor::UI); \
static const Reflection::PropDescriptor<Class, Color3> prop_TextStrokeColor3("TextStrokeColor3", category_Text, &Class::getTextStrokeColor3, &Class::setTextStrokeColor3); \
static const Reflection::PropDescriptor<Class, float> prop_TextStrokeTransparency("TextStrokeTransparency", category_Text, &Class::getTextStrokeTransparency, &Class::setTextStrokeTransparency); \
REFLECTION_END(); \
\
void Class::checkForResize() \
{ \
Super::checkForResize(); \
raisePropertyChanged(prop_TextBounds); \
raisePropertyChanged(prop_TextFits); \
} \
\
void Class::setText(std::string value) \
{ \
if(value.size() > ContentFilter::MAX_CONTENT_FILTER_SIZE){ \
value = value.substr(0, ContentFilter::MAX_CONTENT_FILTER_SIZE); \
} \
if(!ProfanityFilter::ContainsProfanity(value) || getRobloxLocked()){ \
if(GuiTextMixin::text != value){ \
bool didTextFit = getTextFits(); \
GuiTextMixin::text = value; \
filterState = ContentFilter::Waiting; \
raisePropertyChanged(prop_Text); \
raisePropertyChanged(prop_TextBounds); \
if(didTextFit != getTextFits()) \
raisePropertyChanged(prop_TextFits); \
} \
} \
} \
\
void Class::setFontSize(TextService::FontSize value) \
{ \
if (GuiTextMixin::fontSize != value) { \
GuiTextMixin::fontSize = value; \
raisePropertyChanged(prop_FontSize); \
raisePropertyChanged(prop_TextBounds); \
} \
} \
\
void Class::setFont(TextService::Font value) \
{ \
if (GuiTextMixin::font != value) { \
GuiTextMixin::font = value; \
raisePropertyChanged(prop_Font); \
raisePropertyChanged(prop_TextBounds); \
} \
} \
\
void Class::setTextColor(BrickColor value) \
{ \
setTextColor3(value.color3()); \
} \
\
void Class::setTextColor3(Color3 value) \
{ \
if(GuiTextMixin::textColor != value){ \
GuiTextMixin::textColor = value; \
raisePropertyChanged(prop_TextColor); \
raisePropertyChanged(prop_TextColor3); \
} \
} \
\
void Class::setTextTransparency(float value) \
{ \
if(GuiTextMixin::textTransparency != value){ \
GuiTextMixin::textTransparency = value; \
raisePropertyChanged(prop_TextTransparency); \
} \
} \
\
void Class::setTextStrokeTransparency(float value) \
{ \
if(GuiTextMixin::textStrokeTransparency != value){ \
GuiTextMixin::textStrokeTransparency = value; \
raisePropertyChanged(prop_TextStrokeTransparency); \
} \
} \
\
void Class::setTextStrokeColor3(Color3 value) \
{ \
if(GuiTextMixin::textStrokeColor != value){ \
GuiTextMixin::textStrokeColor = value; \
raisePropertyChanged(prop_TextStrokeColor3); \
} \
} \
\
void Class::setTextWrap(bool value) \
{ \
if(GuiTextMixin::textWrap != value){ \
bool didTextFit = getTextFits(); \
GuiTextMixin::textWrap = value; \
raisePropertyChanged(prop_TextWrap); \
raisePropertyChanged(prop_TextBounds); \
if(didTextFit != getTextFits()) \
raisePropertyChanged(prop_TextFits); \
} \
} \
void Class::setTextScale(bool value) \
{ \
if(GuiTextMixin::textScale != value){ \
GuiTextMixin::textScale = value; \
raisePropertyChanged(prop_TextScale); \
if(value) \
setTextWrap(value); \
else \
{ \
raisePropertyChanged(prop_TextBounds); \
raisePropertyChanged(prop_TextFits); \
} \
} \
} \
\
void Class::setXAlignment(TextService::XAlignment value) \
{ \
if(GuiTextMixin::xAlignment != value){ \
bool didTextFit = getTextFits(); \
GuiTextMixin::xAlignment = value; \
raisePropertyChanged(prop_TextXAlignment); \
raisePropertyChanged(prop_TextBounds); \
if(didTextFit != getTextFits()) \
raisePropertyChanged(prop_TextFits); \
} \
} \
\
void Class::setYAlignment(TextService::YAlignment value) \
{ \
if(GuiTextMixin::yAlignment != value){ \
bool didTextFit = getTextFits(); \
GuiTextMixin::yAlignment = value; \
raisePropertyChanged(prop_TextYAlignment); \
raisePropertyChanged(prop_TextBounds); \
if(didTextFit != getTextFits()) \
raisePropertyChanged(prop_TextFits); \
} \
} \
\
void Class::setTransparencyLegacy(float value) \
{ \
setTextTransparency(value); \
Super::setTransparencyLegacy(value); \
} \
\
Vector2 Class::getTextBounds() const \
{ \
if(Network::Players::frontendProcessing(this, false)) \
if(TextService* textService = ServiceProvider::create<TextService>(this)) \
{ \
if(Typesetter* typesetter = textService->getTypesetter(GuiTextMixin::font)) \
return typesetter->measure( GuiTextMixin::text, \
GuiObject::convertFontSize(GuiTextMixin::fontSize), \
GuiTextMixin::textWrap ? getRect2D().wh() : Vector2::zero()); \
} \
\
return Vector2::zero(); \
} \
\
int Class::getPosInString(RBX::Vector2 cursorPos) const \
{ \
if(Network::Players::frontendProcessing(this, false)) \
if(TextService* textService = ServiceProvider::create<TextService>(this)) \
{ \
if(Typesetter* typesetter = textService->getTypesetter(GuiTextMixin::font)) \
{ \
Vector2 pos(0,0); \
Rect2D rect(getRect2D()); \
\
switch(getXAlignment()) \
{ \
case TextService::XALIGNMENT_LEFT: \
pos.x = rect.x0(); \
break; \
case TextService::XALIGNMENT_RIGHT: \
pos.x = rect.x1(); \
break; \
case TextService::XALIGNMENT_CENTER: \
pos.x = rect.center().x; \
break; \
} \
switch(getYAlignment()) \
{ \
case TextService::YALIGNMENT_TOP: \
pos.y = rect.y0(); \
break; \
case TextService::YALIGNMENT_CENTER: \
pos.y = rect.center().y; \
break; \
case TextService::YALIGNMENT_BOTTOM: \
pos.y = rect.y1(); \
break; \
} \
return typesetter->getCursorPositionInText( getText(), \
pos, \
GuiObject::convertFontSize(GuiTextMixin::fontSize), \
TextService::ToTextXAlign(GuiTextMixin::getXAlignment()), \
TextService::ToTextYAlign(GuiTextMixin::getYAlignment()), \
GuiTextMixin::textWrap ? getRect2D().wh() : Vector2::zero(), \
absoluteRotation, \
cursorPos \
); \
} \
} \
\
return -1; \
} \
\
bool Class::getTextFits() const \
{ \
if(Network::Players::frontendProcessing(this, false)) \
if(TextService* textService = ServiceProvider::create<TextService>(this)) \
{ \
if(Typesetter* typesetter = textService->getTypesetter(GuiTextMixin::font)){ \
bool result = false; \
Vector2 bounds = typesetter->measure( GuiTextMixin::text, \
GuiObject::convertFontSize(GuiTextMixin::fontSize), \
GuiTextMixin::textWrap ? getRect2D().wh() : Vector2::zero(), \
&result); \
return result && (bounds.x < getRect2D().width()); \
} \
} \
return false; \
} \
\
int Class::getPersistentDataCost() const \
{ \
return Super::getPersistentDataCost() + Instance::computeStringCost(getText()); \
} \
} // namespace RBX
+395
View File
@@ -0,0 +1,395 @@
#pragma once
#include "Util/SteppedInstance.h"
#include "V8World/KernelJoint.h"
#include "Util/RunStateOwner.h"
#include "solver/Constraint.h"
namespace RBX
{
class PartInstance;
class World;
void registerBodyMovers();
extern const char* const sBodyMover;
// Base class for Instances that move a body using Controller::computeForce()
class BodyMover : public DescribedNonCreatable<BodyMover, Instance, sBodyMover>
, public KernelJoint // Implements "computeForce"
{
private:
typedef Instance Super;
Vector3 lastWakeForce; // last values latched to wake
Vector3 lastWakeTorque;
void computeForce(bool throttling, Body* &root, Vector3& force, Vector3& torque); // internal version
// Connector
/*override*/ void computeForce(bool throttling);
// Joint
/*override*/ bool canStepWorld() const {return true;}
protected:
// KernelJoint
/*override*/ Body* getEngineBody();
/*override*/ void stepWorld();
private:
// Instance
/*override*/ void onAncestorChanged(const AncestorChanged& event);
virtual bool duplicateBodyMoverExists(Primitive* p0, Primitive* p1);
protected:
World* world;
weak_ptr<PartInstance> part; // The Body this controls
/*implement*/ virtual void computeForceImpl(bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque) = 0;
BodyMover(const char* name);
/*override*/ void putInKernel(Kernel* kernel);
/*override*/ void removeFromKernel();
public:
~BodyMover();
bool askSetParent(const Instance* instance) const;
};
// A "gyroscope" used to control the motion of a PartInstance
extern const char* const sBodyGyro;
class BodyGyro
: public DescribedCreatable<BodyGyro, BodyMover, sBodyGyro>
{
float kP; // units: 1/sec^2 torque = kP * momentOfInertia * rotation
float kD; // units: 1/sec torque = kD * momentOfInertia * rotVelocity
Vector3 maxTorque; // units: 1/sec^2?? torque <= maxTorqueComponent * momentOfInertia
CoordinateFrame cframe; // The desired orientation (translation is ignored)
MovingRegression instabilityDetectorX;
MovingRegression instabilityDetectorY;
MovingRegression instabilityDetectorZ;
private:
ConstraintBodyAngularVelocity* angularVelocityConstraint;
Vector3 computeBalanceTorque(Body* body, Body* root);
Vector3 computeOrientationTorque(Body* body, Body* root);
/*override*/ void computeForceImpl(
bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque);
/*override*/ void putInKernel(Kernel* kernel);
/*override*/ void removeFromKernel();
void update(void);
void onPDChanged(const Reflection::PropertyDescriptor&);
/*override*/ void stepWorld();
public:
BodyGyro(void);
~BodyGyro(void);
static Reflection::BoundProp<float> prop_kP;
static Reflection::BoundProp<float> prop_kD;
static Reflection::PropDescriptor<BodyGyro, G3D::Vector3> prop_maxTorque;
static Reflection::PropDescriptor<BodyGyro, G3D::Vector3> prop_maxTorqueDeprecated;
static Reflection::PropDescriptor<BodyGyro, CoordinateFrame> prop_cframe;
static Reflection::PropDescriptor<BodyGyro, CoordinateFrame> prop_cframeDeprecated;
Vector3 getMaxTorque() const { return maxTorque; }
void setMaxTorque(Vector3 value);
CoordinateFrame getCFrame() const { return cframe; }
void setCFrame(CoordinateFrame value);
};
// A constant force at COM (expressed in world coordinates)
extern const char* const sBodyForce;
class BodyForce
: public DescribedCreatable<BodyForce, BodyMover, sBodyForce>
{
private:
Vector3 bodyForceValue;
/*override */ bool duplicateBodyMoverExists(Primitive*, Primitive*) { return false; }
/*override*/ void computeForceImpl(
bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque);
public:
BodyForce(void);
static Reflection::PropDescriptor<BodyForce, Vector3> prop_Force;
static Reflection::PropDescriptor<BodyForce, Vector3> prop_ForceDeprecated;
Vector3 getBodyForce() const { return bodyForceValue; }
void setBodyForce(Vector3 value);
};
// A constant force expressed in body coordinates
extern const char* const sBodyThrust;
class BodyThrust
: public DescribedCreatable<BodyThrust, BodyMover, sBodyThrust>
{
private:
Vector3 bodyThrustValue;
Vector3 location;
protected:
/*override */ bool duplicateBodyMoverExists(Primitive*, Primitive*) { return false; }
/*override*/ void computeForceImpl(
bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque);
public:
BodyThrust(void);
static Reflection::PropDescriptor<BodyThrust, Vector3> prop_force;
static Reflection::PropDescriptor<BodyThrust, Vector3> prop_forceDeprecated;
static Reflection::PropDescriptor<BodyThrust, Vector3> prop_location;
static Reflection::PropDescriptor<BodyThrust, Vector3> prop_locationDeprecated;
Vector3 getForce() const { return bodyThrustValue; }
void setForce(Vector3 value);
Vector3 getLocation() const { return location; }
void setLocation(Vector3 value);
};
// Attempts to keep a body at a fixed position
extern const char* const sBodyPosition;
class BodyPosition
: public DescribedCreatable<BodyPosition, BodyMover, sBodyPosition>
, public IStepped
{
private:
ConstraintLinearSpring* spring;
typedef DescribedCreatable<BodyPosition, BodyMover, sBodyPosition> Super;
float kP; // units: 1/sec^2 force = kP * mass * position
float kD; // units: 1/sec force = kD * mass * velocity
Vector3 maxForce; // force <= maxForce
Vector3 position;
Vector3 lastForce;
bool firedEvent;
/*override*/ void putInKernel(Kernel* kernel);
/*override*/ void removeFromKernel();
void update(void);
/*override*/ void computeForceImpl(
bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque);
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider) {
Super::onServiceProvider(oldProvider, newProvider);
onServiceProviderIStepped(oldProvider, newProvider);
}
// IStepped
/*override*/ void onStepped(const Stepped& event);
void onPDChanged(const Reflection::PropertyDescriptor&);
/*override*/ void stepWorld();
public:
BodyPosition(void);
~BodyPosition(void);
static Reflection::BoundProp<float> prop_kP;
static Reflection::BoundProp<float> prop_kD;
static Reflection::PropDescriptor<BodyPosition, Vector3> prop_maxForce;
static Reflection::PropDescriptor<BodyPosition, Vector3> prop_maxForceDeprecated;
static Reflection::PropDescriptor<BodyPosition, G3D::Vector3> prop_position;
static Reflection::PropDescriptor<BodyPosition, G3D::Vector3> prop_positionDeprecated;
rbx::remote_signal<void()> reachedTargetSignal;
Vector3 getLastForce() { return lastForce; }
Vector3 getMaxForce() const { return maxForce; }
void setMaxForce(Vector3 value);
Vector3 getPosition() const { return position; }
void setPosition(Vector3 value);
};
// Attempts to keep a body at a fixed velocity
extern const char* const sBodyVelocity;
class BodyVelocity
: public DescribedCreatable<BodyVelocity, BodyMover, sBodyVelocity>
{
private:
float kP; // units: 1/sec force = kMoveP * mass * velocity
// TODO: should this be maxAccel?
Vector3 maxForce; // units: 1/sec^2 force <= maxForce
Vector3 velocity;
Vector3 lastForce;
ConstraintLinearVelocity* linearVelocity;
/*override*/ void computeForceImpl(
bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque);
/*override*/ void putInKernel(Kernel* kernel);
/*override*/ void removeFromKernel();
void update();
void onPChanged(const Reflection::PropertyDescriptor&);
public:
BodyVelocity(void);
static Reflection::BoundProp<float> prop_kP;
static Reflection::PropDescriptor<BodyVelocity, G3D::Vector3> prop_maxForce;
static Reflection::PropDescriptor<BodyVelocity, G3D::Vector3> prop_maxForceDeprecated;
static Reflection::PropDescriptor<BodyVelocity, Vector3> prop_velocity;
static Reflection::PropDescriptor<BodyVelocity, Vector3> prop_velocityDeprecated;
Vector3 getLastForce() { return lastForce; }
Vector3 getMaxForce() const { return maxForce; }
void setMaxForce(Vector3 value);
Vector3 getVelocity() const { return velocity; }
void setVelocity(Vector3 value);
};
// Attempts to keep a body at a fixed angular velocity
extern const char* const sBodyAngularVelocity;
class BodyAngularVelocity
: public DescribedCreatable<BodyAngularVelocity, BodyMover, sBodyAngularVelocity>
{
private:
float kP; // units: 1/sec force = kMoveP * mass * velocity
Vector3 maxTorque; // units: 1/sec^2 force <= maxForce
Vector3 angularvelocity;
Vector3 lastTorque;
ConstraintLegacyAngularVelocity* angularVelocityConstraint;
/*override*/ void putInKernel(Kernel* kernel);
/*override*/ void removeFromKernel();
void update(void);
void onPChanged(const Reflection::PropertyDescriptor&);
protected:
/*override*/ void computeForceImpl(
bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque);
public:
BodyAngularVelocity(void);
static Reflection::BoundProp<float> prop_kP;
static Reflection::PropDescriptor<BodyAngularVelocity, Vector3> prop_maxTorque;
static Reflection::PropDescriptor<BodyAngularVelocity, Vector3> prop_maxTorqueDeprecated;
static Reflection::PropDescriptor<BodyAngularVelocity, Vector3> prop_angularvelocity;
static Reflection::PropDescriptor<BodyAngularVelocity, Vector3> prop_angularvelocityDeprecated;
Vector3 getMaxTorque() const { return maxTorque; }
void setMaxTorque(Vector3 value);
Vector3 getAngularVelocity() const { return angularvelocity; }
void setAngularVelocity(Vector3 value);
};
extern const char* const sRocket;
// Steers a part by rotating it and applying thrust along the Part's -z axis
class Rocket
: public DescribedCreatable<Rocket, BodyMover, sRocket>
, public IStepped
{
private:
typedef DescribedCreatable<Rocket, BodyMover, sRocket> Super;
bool active;
shared_ptr<PartInstance> target;
Vector3 targetOffset; // a point in target coordinates
float targetRadius;
bool firedEvent;
// Propulsion
float maxThrust;
float kThrustP; // units: 1/sec^2 force = kP * mass * position
float kThrustD; // units: 1/sec force = kD * mass * velocity
float maxSpeed;
// Orientation & Roll
float kTurnP; // units: 1/sec^2 torque = kP * momentOfInertia * rotation
float kTurnD; // units: 1/sec torque = kD * momentOfInertia * rotVelocity
Vector3 maxTorque; // units: 1/sec^2?? torque <= maxTorqueComponent * momentOfInertia (Torque is in Part-frame)
float cartoonFactor; // 0 - realistic. 1 - cartoony
Vector3 computeTorque(Body* body, Body* root, const G3D::Vector3& targetDir);
PartInstance* getTargetDangerous() const { return target.get(); } // for reflection only
void setTarget(PartInstance* value);
void onGoalChanged(const Reflection::PropertyDescriptor&) {
firedEvent = false;
}
// Instance
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider) {
Super::onServiceProvider(oldProvider, newProvider);
onServiceProviderIStepped(oldProvider, newProvider);
}
// IStepped
/*override*/ void onStepped(const Stepped& event);
// Gyro
/*override*/ void computeForceImpl(
bool throttling,
Body* body,
Body* root,
Vector3& force,
Vector3& torque);
public:
Rocket(void);
virtual ~Rocket();
static Reflection::RefPropDescriptor<Rocket, PartInstance> prop_Target;
static Reflection::BoundProp<Vector3> prop_targetOffset;
static Reflection::BoundProp<float> prop_targetRadius;
static Reflection::BoundProp<float> prop_MaxThrust;
static Reflection::BoundProp<float> prop_ThrustP;
static Reflection::BoundProp<float> prop_ThrustD;
static Reflection::BoundProp<float> prop_MaxSpeed;
//static Reflection::BoundProp<float> prop_RollVelocity;
static Reflection::BoundProp<Vector3> prop_MaxTorque;
static Reflection::BoundProp<float> prop_TurnP;
static Reflection::BoundProp<float> prop_TurnD;
static Reflection::BoundProp<float> prop_CartoonFactor;
static Reflection::BoundFuncDesc<Rocket, void()> func_Fire;
static Reflection::BoundFuncDesc<Rocket, void()> func_Abort;
rbx::remote_signal<void()> reachedTargetSignal;
void fire();
void abort();
private:
static Reflection::BoundProp<bool> prop_Active;
};
}
+197
View File
@@ -0,0 +1,197 @@
#pragma once
// If you are looking to run a release-like build with a debugger or vs production
// you should uncomment the LOVE_ALL_ACCESS line. This should never be set for
// actual releases!
// (Now conveniently located at the top of the file!)
//#define LOVE_ALL_ACCESS
#include "Security/RandomConstant.h"
#define LINE_RAND4 ((RBX_BUILDSEED&0x3FFFF)*__LINE__)
// This line is different due to an unexplained VS2012 issue in debug.
// __LINE__ appears to fail to evaluate to a constant in some cases.
#define LINE_RAND1 (((RBX_BUILDSEED&0xFF)*(__COUNTER__+1))&0xFC)
// HATE_FLAGS: these are the original flags used for reporting detected exploits.
// "Impossible error" is used to help detect anything else.
// Perhaps the user is attempting to cause a game shutdown by
// attacking the networking protocol.
#define HATE_IMPOSSIBLE_ERROR 0x80000000
#define HATE_CE_ASM 0x40000000
#define HATE_NEW_AV_CHECK 0x20000000
#define HATE_HASH_FUNCTION_CHANGED 0x10000000
#define HATE_RETURN_CHECK 0x8000000
#define HATE_VERB_SNATCH 0x4000000
#define HATE_VEH_HOOK 0x2000000
#define HATE_HSCE_HASH_CHANGED 0x1000000
#define HATE_DLL_INJECTION 0x800000
#define HATE_INVALID_ENVIRONMENT 0x400000
#define HATE_SPEEDHACK 0x200000
#define HATE_LUA_VM_HOOKED 0x100000
#define HATE_OSX_MEMORY_HASH_CHANGED 0x80000
#define HATE_UNHOOKED_VEH 0x40000
#define HATE_CHEATENGINE_NEW 0x20000
#define HATE_HSCE_EBX 0x10000
#define HATE_WEAK_DM_POINTER_BROKEN 0x8000
#define HATE_LUA_HASH_CHANGED 0x4000
#define HATE_DESTROY_ALL 0x2000
#define HATE_SEH_CHECK 0x1000
#define HATE_HOOKED_GTX 0x800
#define HATE_DEBUGGER 0x400
#define HATE_LUA_SCRIPT_HASH_CHANGED 0x200
#define HATE_CATCH_EXECUTABLE_ACCESS_VIOLATION 0x100
#define HATE_CONST_CHANGED 0x80
#define HATE_INVALID_BYTECODE 0x40
#define HATE_MEMORY_HASH_CHANGED 0x20
#define HATE_ILLEGAL_SCRIPTS 0x10
#define HATE_SIGNATURE 0x8
#define HATE_NEW_HWBP 0x4
#define HATE_XXHASH_BROKEN 0x2
#define HATE_CHEATENGINE_OLD 0x1 // the image detection, hwnd scanner, and logs.
// SCORN_FLAGS: these are the set of flags that extended the HATE_FLAGS
#define SCORN_IMPOSSIBLE_ERROR 0xFFFFF000
#define SCORN_REPLICATE_PROP 0xFFF
static const unsigned int kNoScornFlags = 0;
// These 32 bit-vectors create a basis for all 32b values.
// eg, y = 0x455F4314 ^ 0xB108F6D2
// gives a value that corresponds to 0x00000003, assuming these are mapped to a
// bit corresponding to the index in the table.
// (these values were generated from a sage script)
static const unsigned int kGf2EncodeLut[32] = {
0x455F4314, 0xB108F6D2, 0x3C297366, 0x76EFD2BB,
0xBE165929, 0xDC284CB4, 0x69A0FE16, 0xCE19BDD9,
0xFD1E6044, 0x0B2BD610, 0xC0BFA0AE, 0xB1004FD3,
0x79D6A004, 0x78925BB3, 0x0E320F15, 0xDB56E1D6,
0x685E2DC1, 0xFB5F13E1, 0x8B1571F0, 0x1E83936A,
0xDB2AAE2A, 0xA49F0A74, 0xD0F8ADB7, 0x53D0B56E,
0xE69C8A79, 0xD6FCEEF9, 0x80AC6B77, 0x68A47CCF,
0x92CA6C6D, 0x7170E034, 0x4CE64F7D, 0xDB8CBB83 };
// These are the 32 bit vectors used to convert back.
// eg, innerProduct( (0x455F4314 ^ 0xB108F6D2), 0xFCEE5D30 ) = 1
// innerProduct( (0x455F4314 ^ 0xB108F6D2), 0xDC401163 ) = 1
// innerProduct( (0x455F4314 ^ 0xB108F6D2), 0xA295C49F ) = 0
// ...
// inner product is parity(a & b) = (1 & popcnt(a & b))
// (these values were generated from a sage script)
static const unsigned int kGf2DecodeLut[32] = {
0xFCEE5D30, 0xDC401163, 0xA295C49F, 0xA73452E1,
0x848D2984, 0x18DF419E, 0x73531D65, 0x11777D3E,
0xD203172E, 0x5D2F07BA, 0x5A96E9DE, 0x7B80D8E4,
0xCC969B58, 0x2B99050C, 0xC45979EB, 0xC124CFE9,
0xF62F63BB, 0x49B0989B, 0xEC6E91C6, 0xB9C8406B,
0x769E8FA2, 0xF3961122, 0x42038864, 0x3A31303E,
0x21F1D62A, 0xC75CC383, 0xB9A4B34A, 0x1050D751,
0xA10126CD, 0x3D1B091B, 0xCAC3F44F, 0x7F89722D };
#define MCC_FAKE_FFLAG_IDX 14
#define MCC_FREECONSOLE_IDX 13
#define MCC_SPEED_IDX 12
#define MCC_MCC_IDX 11
#define MCC_PMC_IDX 10
#define MCC_BAD_IDX 9
#define MCC_INIT_IDX 8
#define MCC_NULL1_IDX 7
#define MCC_NULL0_IDX 6
#define MCC_VEH_IDX 5
#define MCC_GTX_IDX 4
#define MCC_HWBP_IDX 3
#define MCC_RDATA_IDX 2
#define MCC_VMP_IDX 1
#define MCC_TEXT_IDX 0
namespace RBX
{
namespace Security
{
#if defined(_WIN32) && !defined(RBX_PLATFORM_DURANGO)
// This generates an "or" operation in a way that is closer to what a compiler would
// generate.
template<unsigned int key> __forceinline void setHackFlagVs(unsigned int& y, const unsigned int x)
{
unsigned int dest = ((unsigned int)(&y) + key);
int flag = x ^ _rotl(key,11);
volatile int vFlag = flag;
volatile unsigned int tmp = dest;
vFlag ^= _rotl(key,11);
*(unsigned int*)(tmp - key) |= vFlag;
}
// This performs an "or" operation in a way that blends in well with VMProtect, which
// favors "bts" over "or".
template<unsigned int key> __forceinline void setHackFlagVmp(unsigned int& y, const unsigned int x)
{
unsigned int dest = ((unsigned int)(&y) + key);
int flag = x ^ key ^ _rotl(key,17);
volatile int vFlag = flag ^ key;
volatile unsigned int tmp = dest;
tmp -= key;
vFlag ^= _rotl(key,17);
unsigned long bitLoc;
_BitScanForward(&bitLoc, vFlag);
long* vDest = (long*)(tmp);
_bittestandset(vDest, bitLoc);
}
// Get a hack flag location in an indirect manner.
template<unsigned int key> __forceinline unsigned int getHackFlag(const unsigned int& flag)
{
unsigned int dest = ((unsigned int)(&flag) + key);
volatile unsigned int tmp = dest;
return *(unsigned int*)(tmp - key);
}
template<unsigned int key> __forceinline unsigned int getIndirectly(void* addr)
{
unsigned int dest = ((unsigned int)(addr) + key);
volatile unsigned int tmp = dest;
return *(unsigned int*)(tmp - key);
}
#else
template<unsigned int key1> inline void setHackFlagVmp(unsigned int& y, const unsigned int x)
{
y |= x;
}
template<unsigned int key1> inline void setHackFlagVs(unsigned int& y, const unsigned int x)
{
y |= x;
}
template<unsigned int key> inline unsigned int getHackFlag(const unsigned int& flag)
{
return flag;
}
#endif
}
}
// In order to spread these hackflags out in the linking phase, I'm placing these in
// a wide variety of places in .data . Sadly, this means they can't be an array.
namespace RBX
{
namespace Security
{
extern unsigned int
hackFlag0, hackFlag1, hackFlag2, hackFlag3,
hackFlag4, hackFlag5, hackFlag6, hackFlag7,
hackFlag8, hackFlag9, hackFlag10, hackFlag11,
hackFlag12;
}
}
+208
View File
@@ -0,0 +1,208 @@
/**
* HandleAdornment.h
* Copyright (c) 2015 ROBLOX Corp. All Rights Reserved.
* Created by Tyler Berg on 3/24/2015
*/
#pragma once
#include "V8DataModel/Adornment.h"
#include "GfxBase/IAdornable.h"
#include "AppDraw/Draw.h"
namespace RBX
{
extern const char* const sHandleAdornment;
class HandleAdornment
: public DescribedNonCreatable<HandleAdornment, PVAdornment, sHandleAdornment>
{
public:
typedef DescribedNonCreatable<HandleAdornment, PVAdornment, sHandleAdornment> Super;
HandleAdornment(const char* name);
static Reflection::PropDescriptor<HandleAdornment, Vector3> prop_sizeRelativeOffset;
static Reflection::PropDescriptor<HandleAdornment, CoordinateFrame> prop_adornCFrame;
static Reflection::PropDescriptor<HandleAdornment, int> prop_adornZIndex;
static Reflection::PropDescriptor<HandleAdornment, bool> prop_alwaysOnTop;
Vector3 getOffset() const { return sizeRelativeOffset; }
void setOffset(Vector3 value)
{
if (sizeRelativeOffset != value)
{
sizeRelativeOffset = value;
raisePropertyChanged(prop_sizeRelativeOffset);
}
}
CoordinateFrame getCFrame() const { return coordinateFrame; }
void setCFrame(CoordinateFrame value)
{
if (coordinateFrame != value)
{
coordinateFrame = value;
raisePropertyChanged(prop_adornCFrame);
}
}
int getZIndex() const { return zIndex; }
void setZIndex(int value);
bool getAlwaysOnTop() const { return alwaysOnTop; }
void setAlwaysOnTop(bool value)
{
if (alwaysOnTop != value)
{
alwaysOnTop = value;
raisePropertyChanged(prop_alwaysOnTop);
}
}
virtual void render3dAdorn(Adorn* adorn) = 0;
virtual bool isCollidingWithHandle(const shared_ptr<InputObject>& inputObject) = 0;
virtual GuiResponse process(const shared_ptr<InputObject>& event);
virtual CoordinateFrame getWorldCoordinateFrame() const;
rbx::remote_signal<void()> mouseEnterSignal;
rbx::remote_signal<void()> mouseLeaveSignal;
rbx::remote_signal<void()> mouseButton1DownSignal;
rbx::remote_signal<void()> mouseButton1UpSignal;
protected:
Vector3 sizeRelativeOffset;
CoordinateFrame coordinateFrame;
int zIndex;
bool alwaysOnTop;
bool mouseOver;
};
extern const char* const sBoxHandleAdornment;
class BoxHandleAdornment
: public DescribedCreatable<BoxHandleAdornment, HandleAdornment, sBoxHandleAdornment>
{
public:
BoxHandleAdornment();
Vector3 getSize() const { return boxSize; }
void setSize(Vector3 value) { boxSize = value; }
virtual void render3dAdorn(Adorn* adorn);
virtual bool isCollidingWithHandle(const shared_ptr<InputObject>& inputObject);
private:
Vector3 boxSize;
};
extern const char* const sConeHandleAdornment;
class ConeHandleAdornment
: public DescribedCreatable<ConeHandleAdornment, HandleAdornment, sConeHandleAdornment>
{
public:
ConeHandleAdornment();
float getRadius() const { return radius; }
void setRadius(float value) { radius = value; }
virtual CoordinateFrame getWorldCoordinateFrame();
float getHeight() const { return height; }
void setHeight(float value) { height = value; }
virtual void render3dAdorn(Adorn* adorn);
virtual bool isCollidingWithHandle(const shared_ptr<InputObject>& inputObject);
private:
float radius;
float height;
};
extern const char* const sCylinderHandleAdornment;
class CylinderHandleAdornment
: public DescribedCreatable<CylinderHandleAdornment, HandleAdornment, sCylinderHandleAdornment>
{
public:
CylinderHandleAdornment();
float getRadius() const { return radius; }
void setRadius(float value) { radius = value; }
virtual CoordinateFrame getWorldCoordinateFrame();
float getHeight() const { return height; }
void setHeight(float value) { height = value; }
virtual void render3dAdorn(Adorn* adorn);
virtual bool isCollidingWithHandle(const shared_ptr<InputObject>& inputObject);
private:
float radius;
float height;
};
extern const char* const sSphereHandleAdornment;
class SphereHandleAdornment
: public DescribedCreatable<SphereHandleAdornment, HandleAdornment, sSphereHandleAdornment>
{
public:
SphereHandleAdornment();
float getRadius() const { return radius; }
void setRadius(float value) { radius = value; }
virtual void render3dAdorn(Adorn* adorn);
virtual bool isCollidingWithHandle(const shared_ptr<InputObject>& inputObject);
private:
float radius;
};
extern const char* const sLineHandleAdornment;
class LineHandleAdornment
: public DescribedCreatable<LineHandleAdornment, HandleAdornment, sLineHandleAdornment>
{
public:
LineHandleAdornment();
float getLength() const { return length; }
void setLength(float value) { length = value; }
float getThickness() const { return thickness; }
void setThickness(float value) { thickness = value; }
virtual void render3dAdorn(Adorn* adorn);
virtual bool isCollidingWithHandle(const shared_ptr<InputObject>& inputObject);
private:
float length;
float thickness;
};
extern const char* const sImageHandleAdornment;
class ImageHandleAdornment
: public DescribedCreatable<ImageHandleAdornment, HandleAdornment, sImageHandleAdornment>
{
public:
ImageHandleAdornment();
Vector2 getSize() const { return size; }
void setSize(Vector2 value) { size = value; }
TextureId getImage() const { return image; }
void setImage(TextureId value) { image = value; }
virtual void render3dAdorn(Adorn* adorn);
virtual bool isCollidingWithHandle(const shared_ptr<InputObject>& inputObject);
private:
Vector2 size;
TextureId image;
};
}
+79
View File
@@ -0,0 +1,79 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/HandlesBase.h"
#include "V8DataModel/EventReplicator.h"
#include "GfxBase/IAdornable.h"
#include "Util/Faces.h"
#include "AppDraw/HandleType.h"
namespace RBX
{
extern const char* const sHandles;
class Handles
: public DescribedCreatable<Handles, HandlesBase, sHandles>
{
private:
typedef DescribedCreatable<Handles, HandlesBase, sHandles> Super;
public:
Handles();
rbx::remote_signal<void(NormalId)> mouseEnterSignal;
rbx::remote_signal<void(NormalId)> mouseLeaveSignal;
rbx::remote_signal<void(NormalId,float)> mouseDragSignal;
rbx::remote_signal<void(NormalId)> mouseButton1DownSignal;
rbx::remote_signal<void(NormalId)> mouseButton1UpSignal;
DECLARE_EVENT_REPLICATOR_SIG(Handles,MouseEnter, void(NormalId));
DECLARE_EVENT_REPLICATOR_SIG(Handles,MouseLeave, void(NormalId));
DECLARE_EVENT_REPLICATOR_SIG(Handles,MouseDrag, void(NormalId,float));
DECLARE_EVENT_REPLICATOR_SIG(Handles,MouseButton1Down, void(NormalId));
DECLARE_EVENT_REPLICATOR_SIG(Handles,MouseButton1Up, void(NormalId));
enum VisualStyle
{
RESIZE_HANDLES = 0,
MOVEMENT_HANDLES = 1,
ARC_HANDLES = 2,
VELOCITY_HANDLES = 3,
};
void setVisualStyle(VisualStyle value);
VisualStyle getVisualStyle() const { return visualStyle; }
void setFaces(Faces value);
Faces getFaces() const { return faces; }
////////////////////////////////////////////////////////////////////////////////////
//
// HandlesBase
/*override*/ RBX::HandleType getHandleType() const;
////////////////////////////////////////////////////////////////////////////////////
//
// Instance
/*override*/ void onPropertyChanged(const Reflection::PropertyDescriptor& descriptor);
////////////////////////////////////////////////////////////////////////////////////
//
// GuiBase
/*override*/ GuiResponse process(const shared_ptr<InputObject>& event);
protected:
////////////////////////////////////////////////////////////////////////////////////
//
// HandlesBase
/*override*/ int getHandlesNormalIdMask() const { return faces.normalIdMask; }
/*override*/ void setServerGuiObject();
private:
VisualStyle visualStyle;
Faces faces;
};
}
+77
View File
@@ -0,0 +1,77 @@
/* Copyright 2003-2009 ROBLOX Corporation, All Rights Reserved */
#pragma once
#include "V8DataModel/Adornment.h"
#include "V8DataModel/EventReplicator.h"
#include "GfxBase/IAdornable.h"
#include "AppDraw/HandleType.h"
namespace RBX
{
extern const char* const sHandlesBase;
class HandlesBase
: public DescribedNonCreatable<HandlesBase, PartAdornment, sHandlesBase>
{
private:
typedef DescribedNonCreatable<HandlesBase, PartAdornment, sHandlesBase> Super;
public:
HandlesBase(const char* name);
virtual RBX::HandleType getHandleType() const { return RBX::HANDLE_RESIZE; }
////////////////////////////////////////////////////////////////////////////////////
//
// Instance
///*override*/ void onPropertyChanged(const Reflection::PropertyDescriptor& descriptor); // must implement in dervied
/*override*/ void onAncestorChanged(const AncestorChanged& event);
////////////////////////////////////////////////////////////////////////////////////
//
// GuiBase
/*override*/ bool canProcessMeAndDescendants() const;
////////////////////////////////////////////////////////////////////////////////////
//
// IAdornable
/*override*/ void render2d(Adorn* adorn);
/*override*/ void render3dAdorn(Adorn* adorn);
protected:
virtual void setServerGuiObject();
virtual int getHandlesNormalIdMask() const { return 0; }
bool findTargetHandle(const shared_ptr<InputObject>& inputObject, Vector3& hitPointWorld, NormalId& hitNormalId);
bool getDistanceFromHandle(const shared_ptr<InputObject>& inputObject, NormalId localNormalId, const Vector3& hitPointWorld, float& distance);
bool getFacePosFromHandle(const shared_ptr<InputObject>& inputObject, NormalId faceId, const Vector3& hitPointWorld, Vector2& relativePos, Vector2& absolutePos);
bool getAngleRadiusFromHandle(const shared_ptr<InputObject>& inputObject, NormalId faceId, const Vector3& hitPointWorld, float& angle, float& radius, float& absangle, float& absradius);
////////////////////////////////////////////////////////////////////////////////////
//
// IAdornable
/*override*/ bool shouldRender2d() const {return shouldRender3dAdorn();}
struct MouseDownCaptureInfo
{
CoordinateFrame partLocation;
Vector3 hitPointWorld;
NormalId hitNormalId;
MouseDownCaptureInfo(const CoordinateFrame& partLocation, const Vector3& hitPointWorld, NormalId hitNormalId)
: partLocation(partLocation)
, hitPointWorld(hitPointWorld)
, hitNormalId(hitNormalId)
{}
};
NormalId mouseOver;
shared_ptr<MouseDownCaptureInfo> mouseDownCaptureInfo;
private:
bool serverGuiObject;
};
}
+55
View File
@@ -0,0 +1,55 @@
//
// HapticService.h
// App
//
// Created by Ben Tkacheff on 2/09/16.
//
//
#pragma once
#include "V8Tree/Service.h"
namespace RBX
{
extern const char* const sHapticService;
class HapticService
: public DescribedCreatable<HapticService, Instance, sHapticService, Reflection::ClassDescriptor::INTERNAL_LOCAL>
, public Service
{
public:
typedef enum
{
MOTOR_LARGE = 0,
MOTOR_SMALL = 1,
MOTOR_LEFTTRIGGER = 2,
MOTOR_RIGHTTRIGGER = 3,
MOTOR_NONE = 4,
} VibrationMotor;
private:
typedef boost::unordered_map<VibrationMotor, bool> VibrationEnabledMap;
typedef boost::unordered_map<VibrationMotor, shared_ptr<const RBX::Reflection::Tuple> > VibrationStateMap;
typedef boost::unordered_map<InputObject::UserInputType, VibrationStateMap > InputVibrationMap;
typedef boost::unordered_map<InputObject::UserInputType, VibrationEnabledMap > InputVibrationEnabledMap;
InputVibrationEnabledMap vibrationMotorsEnabledMap;
InputVibrationMap vibrationMotorsStateMap;
public:
HapticService();
rbx::signal<void(InputObject::UserInputType, VibrationMotor, shared_ptr<const RBX::Reflection::Tuple>)> setVibrationMotorSignal;
rbx::signal<void(InputObject::UserInputType)> setEnabledVibrationMotorsSignal;
void setEnabledVibrationMotors(InputObject::UserInputType inputType, HapticService::VibrationMotor vibrationMotor, bool isEnabled);
bool isVibrationSupported(InputObject::UserInputType inputType);
bool isMotorSupported(InputObject::UserInputType inputType, HapticService::VibrationMotor vibrationMotor);
void setMotor(InputObject::UserInputType inputType, HapticService::VibrationMotor vibrationMotor, shared_ptr<const RBX::Reflection::Tuple> args);
shared_ptr<const RBX::Reflection::Tuple> getMotor(InputObject::UserInputType inputType, HapticService::VibrationMotor vibrationMotor);
};
}
+194
View File
@@ -0,0 +1,194 @@
#pragma once
#include "V8Tree/Service.h"
#include "Gui/Widget.h"
#include "Gui/GuiDraw.h"
namespace RBX {
class PVInstance;
class Verb;
class PlayerHopper;
class MouseCommand;
class Mouse;
namespace Network {
class Player;
}
extern const char *const sBackpackItem;
class BackpackItem // common root of Tool, HopperBin - stuff that can go in the hopper and on the player
: public DescribedNonCreatable<BackpackItem, Widget, sBackpackItem>
{
private:
typedef DescribedNonCreatable<BackpackItem, Widget, sBackpackItem> Super;
GuiDrawImage guiImageDraw;
TextureId textureId;
GuiDrawImage window;
bool inBackpack();
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ bool askAddChild(const Instance* instance) const;
protected:
//Instance
/*override*/ void setName(const std::string& value);
// GuiItem
/*override*/ Vector2 getSize(Canvas canvas) const;
/*override*/ bool isEnabled() {return inBackpack();}
int getBinId() const;
public:
void setTextureId(const TextureId& value);
const TextureId getTextureId() const;
virtual bool drawEnabled() const {return true;}
virtual bool drawSelected() const {return false;}
virtual void onLocalClicked() {}
virtual void onLocalOtherClicked() {}
};
//////////////////////////////////////////////////////////////////////////////
extern const char *const sHopperBin;
class HopperBin
: public DescribedCreatable<HopperBin, BackpackItem, sHopperBin>
{
private:
typedef DescribedCreatable<HopperBin, BackpackItem, sHopperBin> Super;
public:
// Warning - these enums affect XML read - only append
typedef enum BinType { SCRIPT_BIN = 0,
GAME_TOOL = 1,
GRAB_TOOL = 2,
CLONE_TOOL = 3,
HAMMER_TOOL = 4} BinType;
bool active; // I have a pending deselect event to fire
private:
BinType binType;
bool replicationInitialized;
void onSelectScript();
void onSelectCommand();
// GuiItem
/*override*/ int getCursor();
// BackpackItem
/*override*/ bool drawSelected() const {return active;}
void selectedConnectionShimFunction();
void reverseSelectedConnectionShimFunction(shared_ptr<Instance>& instance);
rbx::signals::connection selectedConnectionShim;
public:
HopperBin();
rbx::remote_signal<void()> replicatedSelectedSignal;
rbx::remote_signal<void(shared_ptr<Instance>)> selectedSignal;
rbx::signal<void()> deselectedSignal;
BinType getBinType() const {return binType;}
void setBinType(const BinType value);
void disable();
// BackpackItem
/*override*/ void onLocalClicked();
/*override*/ void onLocalOtherClicked();
/*override*/ void onAncestorChanged(const AncestorChanged& event);
// deprecated, for reading legacy stuff
void setLegacyCommand(const std::string& text);
void setLegacyTextureName(const std::string& value);
void dataChanged(const Reflection::PropertyDescriptor&);
};
//////////////////////////////////////////////////////////////////////////////
//
// Generic / tree view of the hopper
// Used to build the Hopper Service
// Draws dim
class Hopper
: public RelativePanel
{
private:
typedef RelativePanel Super;
protected:
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ bool askAddChild(const Instance* instance) const;
public:
Hopper();
};
//////////////////////////////////////////////////////////////////////////////
extern const char *const sStarterPackService;
class StarterPackService
: public DescribedNonCreatable<StarterPackService, Hopper, sStarterPackService>
, public Service
{
private:
typedef DescribedNonCreatable<StarterPackService, Hopper, sStarterPackService> Super;
public:
StarterPackService();
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// Legacy 1-30-07
// Renamed this class to StarterPack for clarity, and also
// because StarterPack was around for a while which caused both to be used
extern const char *const sLegacyHopperService;
class LegacyHopperService
: public DescribedNonCreatable<LegacyHopperService, Hopper, sLegacyHopperService>
, public Service
{
private:
typedef DescribedNonCreatable<LegacyHopperService, Hopper, sLegacyHopperService> Super;
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
public:
LegacyHopperService();
~LegacyHopperService();
};
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// StarterGear
// - the gear I bring with me in game
//
extern const char *const sStarterGear;
class StarterGear : public DescribedCreatable<StarterGear, Instance, sStarterGear>
{
private:
// Instance
/*override*/ bool askSetParent(const Instance* instance) const;
/*override*/ bool askAddChild(const Instance* instance) const;
public:
StarterGear();
/*override*/ bool canClientCreate() { return true; }
};
} // namespace
+53
View File
@@ -0,0 +1,53 @@
#include "V8Tree/Instance.h"
#include "v8datamodel/DataModelJob.h"
#include "v8datamodel/DataModel.h"
#include "v8datamodel/HttpRbxApiService.h"
DYNAMIC_FASTINTVARIABLE(HttpRbxApiJobFrequencyInSeconds, 1);
namespace RBX {
class HttpRbxApiJob : public DataModelJob
{
shared_ptr<HttpRbxApiService> apiService;
int lastJobFrequency;
double desiredHz;
public:
HttpRbxApiJob(HttpRbxApiService* owner)
: DataModelJob("HttpRbxApiJob", DataModelJob::Write, false, shared_from(DataModel::get(owner)), Time::Interval(0.01))
, apiService(shared_from(owner))
{
updateHz();
}
void updateHz()
{
desiredHz = 1.0f / DFInt::HttpRbxApiJobFrequencyInSeconds;
lastJobFrequency = DFInt::HttpRbxApiJobFrequencyInSeconds;
}
/*override*/ Time::Interval sleepTime(const Stats& stats)
{
return computeStandardSleepTime(stats, desiredHz);
}
/*override*/ Job::Error error(const Stats& stats)
{
return computeStandardError(stats, desiredHz);
}
/*override*/ TaskScheduler::StepResult stepDataModelJob(const Stats& stats)
{
if (DFInt::HttpRbxApiJobFrequencyInSeconds != lastJobFrequency)
updateHz();
apiService->addThrottlingBudgets(DFInt::HttpRbxApiJobFrequencyInSeconds / 60.0f);
apiService->executeThrottledRequests();
apiService->executeRetryRequests();
return TaskScheduler::Stepped;
}
};
} // namespace RBX
+193
View File
@@ -0,0 +1,193 @@
#pragma once
#include "Reflection/Reflection.h"
#include "V8Tree/Instance.h"
#include "V8Tree/Service.h"
#include "rbx/RunningAverage.h"
#include "v8datamodel/HttpService.h"
#include "Util/Http.h"
#include "Util/DoubleEndedVector.h"
DYNAMIC_FASTINT(PercentApiRequestsRecordGoogleAnalytics)
namespace RBX {
class HttpRbxApiJob;
typedef enum
{
PRIORITY_EXTREME = 2, // Request will NOT be throttled ever
PRIORITY_SERVER_ELEVATED = 1, // Request may be throttled, should only be higher priority items (only works on server calls)
PRIORITY_DEFAULT = 0, // Request may be throttled
} ThrottlingPriority;
extern const char* const sHttpRbxApiService;
class HttpRbxApiService
:public DescribedCreatable<HttpRbxApiService, Instance, sHttpRbxApiService, Reflection::ClassDescriptor::INTERNAL>
,public Service
{
public:
// this struct is used to store/execute API requests
struct HttpApiRequest
{
private:
Http http;
public:
bool isPost;
std::string postData;
std::string httpContentType;
bool async;
std::string syncResponse;
ThrottlingPriority throttlingPriority;
int retryCount;
boost::function<void(std::string)> resumeFunction;
boost::function<void(std::string)> errorFunction;
void execute(HttpRbxApiService* apiService);
void setHttp(Http& newHttp)
{
http = newHttp;
http.shouldRetry = false;
}
Http getHttp() const { return http; }
HttpApiRequest()
{
retryCount = 0;
postData = "";
httpContentType = "";
async = true;
isPost = false;
syncResponse = "";
throttlingPriority = PRIORITY_DEFAULT;
http.shouldRetry = false;
}
};
private:
typedef DescribedCreatable<HttpRbxApiService, Instance, sHttpRbxApiService, Reflection::ClassDescriptor::INTERNAL> Super;
//////////////////////////////////////////////////////////////////////
// MEMBERS
//////////////////////////////////////////////////////////////////////
// These track the number of API requests we execute by storing a budget
// which is decremented every request, and is added to as time passes
BudgetedThrottlingHelper defaultServerThrottle, elevatedServerThrottle, clientThrottle, retryBudget;
// used to store requests that go over the throttle budgets
// each queue can only store HttpRbxApiMaxThrottledQueueSize items
// if HttpRbxApiMaxThrottledQueueSize is reached then the request returns a throttle error
DoubleEndedVector<HttpApiRequest> throttledDefaultServerRequests, throttledElevatedServerRequests, throttledClientRequests, retryQueue;
// a DataModel job responsible for allowing time for the
// execution of HttpApiRequest objects
shared_ptr<HttpRbxApiJob> httpRbxApiJob;
std::string apiBaseUrl;
static std::string StaticApiBaseUrl;
bool serverPresent;
bool clientPresent;
bool isPlaySolo;
rbx::signals::scoped_connection serviceAddedConnection;
rbx::signals::scoped_connection playersChangedConnection;
rbx::signals::scoped_connection contentProviderPropertyChangedConnection;
unsigned int totalNumOfApiCalls;
RBX::Timer<RBX::Time::Fast> instanceAliveTimer;
bool recordInGoogleAnalytics;
//////////////////////////////////////////////////////////////////////
// METHODS
//////////////////////////////////////////////////////////////////////
// initialization helpers
void checkForClientAndServer(Instance* context);
void newServiceAdded(shared_ptr<Instance> newService);
void playersPropertyChanged(const RBX::Reflection::PropertyDescriptor* desc);
void disconnectEventConnections();
// general function that allows either async or sync functions to have their errors set appropriately
void setErrorForAsync(const std::string& errorString, boost::function<void(std::string)> errorFunction);
// Throttling Helpers
bool tryThrottleRequest(const HttpApiRequest& apiRequest, BudgetedThrottlingHelper& budgetThrottler, DoubleEndedVector<HttpApiRequest>& throttledRequestQueue,
boost::function<void(std::string)> errorFunction);
bool executeApiRequest(HttpApiRequest& apiRequest, const ThrottlingPriority& throttlePriority,
boost::function<void(std::string)> errorFunction);
void executeThrottledRequests(DoubleEndedVector<HttpApiRequest>& queue, BudgetedThrottlingHelper& helper);
int getPlayerNum();
// Post/Get Helpers
void getAsyncInternal(Http& httpRequest, const ThrottlingPriority& throttlePriority,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void postAsyncInternal(Http& httpRequest, std::string& data, const HttpService::HttpContentType& contentType,
const bool shouldCompress, const ThrottlingPriority& throttlePriority, boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void checkAndUpdatePostUrl(std::string& fullUrl, const std::string& urlPath) const;
static void httpHelper(weak_ptr<HttpRbxApiService> weakApiService, std::string* response, std::exception* exception, HttpApiRequest request, ThrottlingPriority throttlePriority,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
static bool retrySyncRequest(Http& http, std::string& syncResponse);
void setStaticApiBaseUrl(const RBX::Reflection::PropertyDescriptor* pPropertyDescriptor);
//////////////////////////////////////////////////////////////
// Instance
///////////////////////
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
public:
//////////////////////////////////////////////////////////////////////
// FUNCTIONS
//////////////////////////////////////////////////////////////////////
HttpRbxApiService();
// Google analytics helpers
void addToApiCallCount() { totalNumOfApiCalls++; }
bool getRecordInGoogleAnalytics() const { return recordInGoogleAnalytics; }
// Throttling Functions
void addThrottlingBudgets(float timeDeltaMinutes);
void executeThrottledRequests();
void executeRetryRequests();
bool addToRetryQueue(HttpApiRequest apiRequest);
// Synchronous Http calls (only use if we need to block the thread)
void get(Http& httpRequest, bool useHttps, ThrottlingPriority throttlePriority, std::string& response);
void get(const std::string& urlPath, bool useHttps, ThrottlingPriority throttlePriority, std::string& response);
// Asynchronous Http calls
void getAsync(Http& httpRequest, ThrottlingPriority throttlePriority,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getAsync(std::string urlPath, bool useHttps, ThrottlingPriority throttlePriority,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void getAsyncLua(std::string urlPath, bool useHttps, ThrottlingPriority throttlePriority,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void postAsync(Http& httpRequest, std::string& data, ThrottlingPriority throttlePriority, HttpService::HttpContentType content,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void postAsync(std::string urlPath, std::string data,bool useHttps, ThrottlingPriority throttlePriority, HttpService::HttpContentType content,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void postAsyncWithAdditionalHeaders(std::string urlPath, std::string data,bool useHttps, ThrottlingPriority throttlePriority, HttpService::HttpContentType content, RBX::HttpAux::AdditionalHeaders additionalHeaders,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
void postAsyncLua(std::string urlPath, std::string data,bool useHttps, ThrottlingPriority throttlePriority, HttpService::HttpContentType content,
boost::function<void(std::string)> resumeFunction, boost::function<void(std::string)> errorFunction);
// API URL Helpers
static bool isAPIHttpRequest(const Http& httpRequest);
static std::string getApiUrlPath(const Http& httpRequest);
};
} //namespace RBX

Some files were not shown because too many files have changed in this diff Show More