Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 1514070

Browse files
committed
[[ SosBehavior ]] Serialize behavior in script-only-stack format
This patch adds a 'with behavior' clause to the header of a script only stack. The clause is emitted if the stack has a behavior property which references a stack. When a script-only-stack with such a clause is loaded, the behavior is set as part of the loading.
1 parent 69828d6 commit 1514070

File tree

3 files changed

+66
-8
lines changed

3 files changed

+66
-8
lines changed

engine/src/dispatch.cpp

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
5656
#include "stacksecurity.h"
5757
#include "scriptpt.h"
5858
#include "widget-events.h"
59+
#include "parentscript.h"
5960

6061
#include "exec.h"
6162
#include "exec-interface.h"
@@ -716,6 +717,28 @@ static MCStack* script_only_stack_from_bytes(uint8_t *p_bytes,
716717
return nullptr;
717718
}
718719

720+
// If 'with' is next then parse the behavior reference.
721+
MCNewAutoNameRef t_behavior_name;
722+
if (sp.skip_token(SP_REPEAT, TT_UNDEFINED, RF_WITH) == PS_NORMAL)
723+
{
724+
// Ensure 'behavior' is next
725+
if (sp.skip_token(SP_FACTOR, TT_PROPERTY, P_PARENT_SCRIPT) != PS_NORMAL)
726+
{
727+
return nullptr;
728+
}
729+
730+
// Read the behavior name
731+
if (sp.next(t_type) != PS_NORMAL || t_type != ST_LIT)
732+
{
733+
return nullptr;
734+
}
735+
736+
if (!MCNameClone(sp.gettoken_nameref(), &t_behavior_name))
737+
{
738+
return nullptr;
739+
}
740+
}
741+
719742
// Parse end of line.
720743
Parse_stat t_stat;
721744
t_stat = sp . next(t_type);
@@ -763,6 +786,12 @@ static MCStack* script_only_stack_from_bytes(uint8_t *p_bytes,
763786
// Set its name.
764787
t_stack -> setname(*t_script_name);
765788

789+
// If we parsed a behavior reference, then set it.
790+
if (*t_behavior_name != nullptr)
791+
{
792+
t_stack->setparentscript_onload(0, *t_behavior_name);
793+
}
794+
766795
return t_stack;
767796
}
768797

@@ -1142,8 +1171,22 @@ IO_stat MCDispatch::dosavescriptonlystack(MCStack *sptr, const MCStringRef p_fna
11421171
// Ensure script isn't encrypted if a password was removed in session
11431172
sptr -> unsecurescript(sptr);
11441173

1145-
// Write out the standard script stack header, and then the script itself
1146-
MCStringFormat(&t_script_body, "script \"%@\"\n%@", sptr -> getname(), sptr->_getscript());
1174+
// Write out the standard script stack header with behavior reference
1175+
// (if applicable) and then the script itself
1176+
MCParentScript *t_parent_script = sptr->getparentscript();
1177+
if (t_parent_script != nullptr &&
1178+
t_parent_script->GetObjectId() == 0)
1179+
{
1180+
MCStringFormat(&t_script_body,
1181+
"script \"%@\" with behavior \"%@\"\n%@",
1182+
sptr->getname(),
1183+
t_parent_script->GetObjectStack(),
1184+
sptr->_getscript());
1185+
}
1186+
else
1187+
{
1188+
MCStringFormat(&t_script_body, "script \"%@\"\n%@", sptr -> getname(), sptr->_getscript());
1189+
}
11471190

11481191
// Convert line endings - but only if the native line ending isn't CR!
11491192
#ifndef __CR__

engine/src/object.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4051,12 +4051,11 @@ IO_stat MCObject::extendedload(MCObjectInputStream& p_stream, uint32_t version,
40514051

40524052
if (t_stat == IO_NORMAL)
40534053
{
4054-
parent_script = MCParentScript::Acquire(this, t_id, t_stack);
4055-
if (parent_script == NULL)
4056-
t_stat = IO_ERROR;
4057-
4058-
s_loaded_parent_script_reference = true;
4059-
}
4054+
if (!setparentscript_onload(t_id, t_stack))
4055+
{
4056+
t_stat = IO_ERROR;
4057+
}
4058+
}
40604059

40614060
MCNameDelete(t_stack);
40624061
}
@@ -4134,6 +4133,18 @@ IO_stat MCObject::extendedload(MCObjectInputStream& p_stream, uint32_t version,
41344133
return t_stat;
41354134
}
41364135

4136+
bool MCObject::setparentscript_onload(uint32_t p_id, MCNameRef p_stack)
4137+
{
4138+
parent_script = MCParentScript::Acquire(this, p_id, p_stack);
4139+
if (parent_script == NULL)
4140+
{
4141+
return false;
4142+
}
4143+
4144+
s_loaded_parent_script_reference = true;
4145+
4146+
return true;
4147+
}
41374148

41384149
// MW-2008-10-28: [[ ParentScripts ]] This method attempts to resolve the
41394150
// parentscript reference for this object (if any).

engine/src/object.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,10 @@ class MCObject :
971971
// is no parentScript, it returns NULL - note that this is an MCParentScript,
972972
// not an MCParentScriptUse.
973973
MCParentScript *getparentscript(void) const;
974+
975+
// Set the parentScript of the object at load time of it (used by the script
976+
// only stack loader).
977+
bool setparentscript_onload(uint32_t p_id, MCNameRef p_stack);
974978

975979
// MW-2009-01-28: [[ Inherited parentScripts ]]
976980
// This method returns false if there was not enough memory to complete the

0 commit comments

Comments
 (0)