BsCmdEditPlainFieldGO.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #pragma once
  2. #include "BsEditorPrerequisites.h"
  3. #include "BsEditorCommand.h"
  4. #include "BsUndoRedo.h"
  5. namespace BansheeEngine
  6. {
  7. // TODO - This is only valid for plain field types. Add something similar for pointers and/or arrays?
  8. template<class T>
  9. class CmdEditPlainFieldGO : public EditorCommand
  10. {
  11. public:
  12. ~CmdEditPlainFieldGO()
  13. {
  14. if(mNewData != nullptr)
  15. bs_free(mNewData);
  16. if(mOldData != nullptr)
  17. bs_free(mOldData);
  18. }
  19. static void execute(const GameObjectHandleBase& gameObject, const String& fieldName, const T& fieldValue)
  20. {
  21. // Register command and commit it
  22. CmdEditPlainFieldGO* command = new (bs_alloc<CmdEditPlainFieldGO>()) CmdEditPlainFieldGO(gameObject, fieldName, fieldValue);
  23. UndoRedo::instance().registerCommand(command);
  24. command->commit();
  25. }
  26. void commit()
  27. {
  28. if(mGameObject.isDestroyed())
  29. return;
  30. T fieldValue;
  31. RTTIPlainType<T>::fromMemory(fieldValue, (char*)mNewData);
  32. RTTITypeBase* rtti = mGameObject->getRTTI();
  33. rtti->setPlainValue(mGameObject.get(), mFieldName, fieldValue);
  34. }
  35. void revert()
  36. {
  37. if(mGameObject.isDestroyed())
  38. return;
  39. T fieldValue;
  40. RTTIPlainType<T>::fromMemory(fieldValue, (char*)mOldData);
  41. RTTITypeBase* rtti = mGameObject->getRTTI();
  42. rtti->setPlainValue(mGameObject.get(), mFieldName, fieldValue);
  43. }
  44. private:
  45. friend class UndoRedo;
  46. CmdEditPlainFieldGO(const GameObjectHandleBase& gameObject, const String& fieldName, const T& fieldValue)
  47. :mGameObject(gameObject), mFieldName(fieldName), mNewData(nullptr), mOldData(nullptr)
  48. {
  49. // Convert new value to bytes
  50. UINT32 newDataNumBytes = RTTIPlainType<T>::getDynamicSize(fieldValue);
  51. mNewData = bs_alloc(newDataNumBytes);
  52. RTTIPlainType<T>::toMemory(fieldValue, (char*)mNewData);
  53. // Get old value and also convert it to bytes
  54. String oldFieldValue;
  55. gameObject->getRTTI()->getPlainValue(gameObject.get(), fieldName, oldFieldValue);
  56. UINT32 oldDataNumBytes = RTTIPlainType<T>::getDynamicSize(oldFieldValue);
  57. mOldData = bs_alloc(oldDataNumBytes);
  58. RTTIPlainType<T>::toMemory(oldFieldValue, (char*)mOldData);
  59. }
  60. GameObjectHandleBase mGameObject;
  61. String mFieldName;
  62. void* mNewData;
  63. void* mOldData;
  64. };
  65. }