New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convert CommandHistory to a std::shared_ptr #1161
Changes from 2 commits
1452071
4e4b965
3f19be4
3cd6f1b
e8104ed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,10 +50,10 @@ static COORD calculatePopupSize(const CommandHistory& history) | |
return { gsl::narrow<short>(width), height }; | ||
} | ||
|
||
CommandListPopup::CommandListPopup(SCREEN_INFORMATION& screenInfo, const CommandHistory& history) : | ||
Popup(screenInfo, calculatePopupSize(history)), | ||
CommandListPopup::CommandListPopup(SCREEN_INFORMATION& screenInfo, const std::shared_ptr<CommandHistory>& history) : | ||
Popup(screenInfo, calculatePopupSize(*history)), | ||
_history{ history }, | ||
_currentCommand{ std::min(history.LastDisplayed, static_cast<SHORT>(history.GetNumberOfCommands() - 1)) } | ||
_currentCommand{ std::min(history->LastDisplayed, static_cast<SHORT>(history->GetNumberOfCommands() - 1)) } | ||
{ | ||
FAIL_FAST_IF(_currentCommand < 0); | ||
_setBottomIndex(); | ||
|
@@ -106,11 +106,11 @@ NTSTATUS CommandListPopup::_handlePopupKeys(CookedRead& cookedReadData, const wc | |
break; | ||
case VK_END: | ||
// Move waaay forward, UpdateCommandListPopup() can handle it. | ||
_update((SHORT)(cookedReadData.History().GetNumberOfCommands())); | ||
_update((SHORT)(cookedReadData.History()->GetNumberOfCommands())); | ||
break; | ||
case VK_HOME: | ||
// Move waaay back, UpdateCommandListPopup() can handle it. | ||
_update(-(SHORT)(cookedReadData.History().GetNumberOfCommands())); | ||
_update(-(SHORT)(cookedReadData.History()->GetNumberOfCommands())); | ||
break; | ||
case VK_PRIOR: | ||
_update(-(SHORT)Height()); | ||
|
@@ -136,13 +136,13 @@ NTSTATUS CommandListPopup::_handlePopupKeys(CookedRead& cookedReadData, const wc | |
|
||
void CommandListPopup::_setBottomIndex() | ||
{ | ||
if (_currentCommand < (SHORT)(_history.GetNumberOfCommands() - Height())) | ||
if (_currentCommand < (SHORT)(_history->GetNumberOfCommands() - Height())) | ||
{ | ||
_bottomIndex = std::max(_currentCommand, gsl::narrow<SHORT>(Height() - 1i16)); | ||
} | ||
else | ||
{ | ||
_bottomIndex = (SHORT)(_history.GetNumberOfCommands() - 1); | ||
_bottomIndex = (SHORT)(_history->GetNumberOfCommands() - 1); | ||
} | ||
} | ||
|
||
|
@@ -151,18 +151,18 @@ NTSTATUS CommandListPopup::_deleteSelection(CookedRead& cookedReadData) noexcept | |
{ | ||
try | ||
{ | ||
auto& history = cookedReadData.History(); | ||
history.Remove(static_cast<short>(_currentCommand)); | ||
auto history = cookedReadData.History(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh yes... |
||
history->Remove(static_cast<short>(_currentCommand)); | ||
_setBottomIndex(); | ||
|
||
if (history.GetNumberOfCommands() == 0) | ||
if (history->GetNumberOfCommands() == 0) | ||
{ | ||
// close the popup | ||
return CONSOLE_STATUS_READ_COMPLETE; | ||
} | ||
else if (_currentCommand >= static_cast<short>(history.GetNumberOfCommands())) | ||
else if (_currentCommand >= static_cast<short>(history->GetNumberOfCommands())) | ||
{ | ||
_currentCommand = static_cast<short>(history.GetNumberOfCommands() - 1); | ||
_currentCommand = static_cast<short>(history->GetNumberOfCommands() - 1); | ||
_bottomIndex = _currentCommand; | ||
} | ||
|
||
|
@@ -181,13 +181,13 @@ NTSTATUS CommandListPopup::_swapUp(CookedRead& cookedReadData) noexcept | |
{ | ||
try | ||
{ | ||
auto& history = cookedReadData.History(); | ||
auto history = cookedReadData.History(); | ||
|
||
if (history.GetNumberOfCommands() <= 1 || _currentCommand == 0) | ||
if (history->GetNumberOfCommands() <= 1 || _currentCommand == 0) | ||
{ | ||
return STATUS_SUCCESS; | ||
} | ||
history.Swap(_currentCommand, _currentCommand - 1); | ||
history->Swap(_currentCommand, _currentCommand - 1); | ||
_update(-1); | ||
_drawList(); | ||
} | ||
|
@@ -204,13 +204,13 @@ NTSTATUS CommandListPopup::_swapDown(CookedRead& cookedReadData) noexcept | |
{ | ||
try | ||
{ | ||
auto& history = cookedReadData.History(); | ||
auto history = cookedReadData.History(); | ||
|
||
if (history.GetNumberOfCommands() <= 1 || _currentCommand == gsl::narrow<short>(history.GetNumberOfCommands()) - 1i16) | ||
if (history->GetNumberOfCommands() <= 1 || _currentCommand == gsl::narrow<short>(history->GetNumberOfCommands()) - 1i16) | ||
{ | ||
return STATUS_SUCCESS; | ||
} | ||
history.Swap(_currentCommand, _currentCommand + 1); | ||
history->Swap(_currentCommand, _currentCommand + 1); | ||
_update(1); | ||
_drawList(); | ||
} | ||
|
@@ -229,7 +229,7 @@ void CommandListPopup::_handleReturn(CookedRead& cookedReadData) | |
void CommandListPopup::_cycleSelectionToMatchingCommands(CookedRead& cookedReadData, const wchar_t wch) | ||
{ | ||
short Index = 0; | ||
if (cookedReadData.History().FindMatchingCommand({ &wch, 1 }, | ||
if (cookedReadData.History()->FindMatchingCommand({ &wch, 1 }, | ||
_currentCommand, | ||
Index, | ||
CommandHistory::MatchOptions::JustLooking)) | ||
|
@@ -346,7 +346,7 @@ void CommandListPopup::_drawList() | |
CommandNumberLength)); | ||
|
||
// write command to screen | ||
auto command = _history.GetNth(i); | ||
auto command = _history->GetNth(i); | ||
lStringLength = command.size(); | ||
{ | ||
size_t lTmpStringLength = lStringLength; | ||
|
@@ -423,13 +423,13 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap) | |
if (wrap) | ||
{ | ||
// Modulo the number of commands to "circle" around if we went off the end. | ||
NewCmdNum %= _history.GetNumberOfCommands(); | ||
NewCmdNum %= _history->GetNumberOfCommands(); | ||
} | ||
else | ||
{ | ||
if (NewCmdNum >= gsl::narrow<SHORT>(_history.GetNumberOfCommands())) | ||
if (NewCmdNum >= gsl::narrow<SHORT>(_history->GetNumberOfCommands())) | ||
{ | ||
NewCmdNum = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1i16; | ||
NewCmdNum = gsl::narrow<SHORT>(_history->GetNumberOfCommands()) - 1i16; | ||
} | ||
else if (NewCmdNum < 0) | ||
{ | ||
|
@@ -452,9 +452,9 @@ void CommandListPopup::_update(const SHORT originalDelta, const bool wrap) | |
else if (NewCmdNum > _bottomIndex) | ||
{ | ||
_bottomIndex += delta; | ||
if (_bottomIndex >= gsl::narrow<SHORT>(_history.GetNumberOfCommands())) | ||
if (_bottomIndex >= gsl::narrow<SHORT>(_history->GetNumberOfCommands())) | ||
{ | ||
_bottomIndex = gsl::narrow<SHORT>(_history.GetNumberOfCommands()) - 1i16; | ||
_bottomIndex = gsl::narrow<SHORT>(_history->GetNumberOfCommands()) - 1i16; | ||
} | ||
Scroll = true; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,7 @@ | |
CookedRead::CookedRead(InputBuffer* const pInputBuffer, | ||
INPUT_READ_HANDLE_DATA* const pInputReadHandleData, | ||
SCREEN_INFORMATION& screenInfo, | ||
CommandHistory* pCommandHistory, | ||
std::shared_ptr<CommandHistory> pCommandHistory, | ||
wchar_t* userBuffer, | ||
const size_t cchUserBuffer, | ||
const ULONG ctrlWakeupMask, | ||
|
@@ -55,9 +55,9 @@ bool CookedRead::HasHistory() const noexcept | |
return _pCommandHistory != nullptr; | ||
} | ||
|
||
CommandHistory& CookedRead::History() noexcept | ||
std::shared_ptr<CommandHistory> CookedRead::History() noexcept | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would prefer if this handed out a reference to the command history like it used to, it shouldn't be allowing other classes to share in the history ownership from here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. |
||
{ | ||
return *_pCommandHistory; | ||
return _pCommandHistory; | ||
} | ||
|
||
void CookedRead::Erase() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,7 @@ class CookedRead final : public ReadData | |
CookedRead(InputBuffer* const pInputBuffer, | ||
INPUT_READ_HANDLE_DATA* const pInputReadHandleData, | ||
SCREEN_INFORMATION& screenInfo, | ||
CommandHistory* pCommandHistory, | ||
std::shared_ptr<CommandHistory> pCommandHistory, | ||
wchar_t* userBuffer, | ||
const size_t cchUserBuffer, | ||
const ULONG ctrlWakeupMask, | ||
|
@@ -69,7 +69,7 @@ class CookedRead final : public ReadData | |
|
||
SCREEN_INFORMATION& ScreenInfo(); | ||
|
||
CommandHistory& History() noexcept; | ||
std::shared_ptr<CommandHistory> History() noexcept; | ||
bool HasHistory() const noexcept; | ||
|
||
void BufferInput(const wchar_t wch); | ||
|
@@ -112,7 +112,7 @@ class CookedRead final : public ReadData | |
COORD _promptStartLocation; | ||
// the location of the cursor before a popup is launched | ||
COORD _beforePopupCursorPosition; | ||
CommandHistory* _pCommandHistory; // non-ownership pointer | ||
std::shared_ptr<CommandHistory> _pCommandHistory; // shared pointer | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: the comment on this line is redundant now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok... |
||
// mask of control keys that if pressed will end the cooked read early | ||
const ULONG _ctrlWakeupMask; | ||
// current state of the CookedRead | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ChristophePichaud I haven't looked at the ownership chain closely but I question why CommandHistory needs be a shared_ptr for this class. (and some of the other const shared_ptr references in this PR)
Take a look at this for guidance for shared_ptr.
I could be wrong because I haven't looked at this close enough. The thing to look for here which classes are sharing ownership? Those are the classes that need to have shared_ptrs. If the class doesn't share ownership then they should be raw pointer or references. Hope this makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal is to encapsulate the raw pointer as a smart pointer. You don't have some many choice, it's unique_ptr, weak_ptr or shared_ptr. Ok you can get back a raw pointer but only in small scenarios. I read the guidance and I make the changes. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have applied the guidance. It's cool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ChristophePichaud The CommandListPopup ctor in this case is taking the shared pointer by const reference. This indicates that this class is not taking part in the ownership. ie - ref counting is not being incremented. So this code does not need to use a shared_ptr.
This code can be left as it was. (taking a const CommandHistory&) The benefit is you are not tying the pointer type to the class. If in the future this code changes and uses a different kind of smart pointer this code would not have to change.
If CommandListPopup really was needed to be part of the ownership chain then this code wouldn't work anyway because it doesn't increment the ref count.
Does this make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be
The CommandListPopup ctor in this case is taking the shared pointer by const reference and the class is storing the variable in a const & in the class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CommandListPopup class accepts the history argument two times. First, its stores it as a shared_ptr for future use and also as a const ref for a simple calculation for the bqse ctor... So the code is correct.
Check twice.
Tell me back ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm with @dlong11 on this, for this class it needs to have a
CommandHistory
and it can't be changed after aCommandHistory
class is created. The history also shouldn't be destructed while a popup is around so keeping it aCommandHistory&
seems more appropriate.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @dlong11 and @adiviness, I have made the various changes in the code.
You are right, sometimes, it's better to handle the stuff with references.
Thanks.